Thursday, January 31, 2013

Big Character Demo with Arduino and BPP-440L

Building on the previous demo of print positioning for the BPP-440L, this Arduino demo shows how to use and format the display's big characters. These characters are constructed out of the LCD's custom-character set, and are a little trickier to work with than the larger font sizes on the GLO-series. On the GLOs, larger fonts work just like small ones in all respects, and don't interfere with the custom characters.

But like all text LCDs employing tricks to generate big characters, the BPP-440L must be finessed for best results. Fortunately, it's easy, and there's heavily commented code after the break. Here's the sort of thing we're talking about:



/*
Demonstrating Big character mode on the BPP-440L
4x40 serial LCD module. 
seetrontech.blogspot.com
seetron.com
 */

// SoftwareSerial lets us use any I/O pin for serial output 
// to the BPP-440L, saving the hardware UART for the bootloader  
#include <SoftwareSerial.h>  // or other critical comms.

// Streaming allows items for serial output to be grouped
#include <Streaming.h>  // logically on a single line

#define rxPin 255         // Not used, so set to invalid pin #
#define txPin 3           // Hook SER input to Arduino pin 3.
#define inverted 1       // Inverted serial (like RS-232, but TTL levels)
#define noninverted 0    // Noninverted serial (like UART output)

// Change the definition of SPOL to inverted or noninverted 
// depending on your display configuration. On newer BPP-440Ls, 
// if the SPOL jumper is intact (factory setting), you want 
// "inverted." If it's cut, use "noninverted." 
#define SPOL inverted

// For inverted serial, the output pin must be LOW when data is 
// not being sent; for noninverted, HIGH. 
#if SPOL
#define STOPBIT LOW
#else
#define STOPBIT HIGH
#endif

//=====================================================================
//          CONSTANTS FOR LCD INSTRUCTIONS
//
// Rather than scatter a bunch of magic numbers throughout the 
// program, I've defined some self-explanatory names for the 
// small subset of BPP-440L instructions needed. 
#define HOME (char) 1        // Moveto character position 0.
#define BIGMODE (char) 2     // Begin big-character mode.
#define ENDBIG (char) 3      // End big-char mode. 
#define CLS (char) 12        // Clear screen, moveto 0.
#define CR (char) 13         // Carriage return. 
#define MOVETO (char) 16     // Position instruction
#define MIDSCREEN (char) (20+64)  // Position addres of col 20

//=====================================================================
//          CONSTANTS FOR FORMATTING FUNCTION
// A function below that formats strings for the BPP-420L uses 
// a true/false argument to set right- or left- alignment of 
// big characters. 
#define RIGHT true
#define LEFT false

// In the BPP-440L Big-character mode, the space character " " 
// (32 dec, 0x20 hex) is three columns wide, while A-Z and 
// 0-9 are five columns. So to make a big space that is 
// suitable for padding for alignment, let's define a  
// "bigSpace" of five clear-column instructions. 
char const bigSpace[] = {
  0x11,0x11,0x11,0x11,0x11,0x00 } ;

//=====================================================================
// Set up a new serial output using the definitions above. 
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin, SPOL);

// Create the string object that will be used for our output data.
String printMe = "" ;  

//=====================================================================
// SETUP: 
//=====================================================================
// Put the serial-output pin in the stop-bit state and 
// set the bit rate to 9600bps. Then print the banner and the 
// fixed labels at the #defined locations. 

void setup()  {
  delay(500) ;
// define pin modes for tx, rx:
  digitalWrite(txPin, STOPBIT);  // Preset pin to stop-bit
  mySerial.begin(9600);          // Set the data rate.
  delay(10) ;                    // wait.

// Print block of text on the left side of the display.
  mySerial <<CLS ;
  mySerial <<"BPP-440L DEMO   |" <<CR <<"Big Characters  |" <<CR ;
  mySerial <<"w/ Padding for  |" <<CR <<"Right Alignment |" ;
}

//=====================================================================
// LOOP: 
//=====================================================================
// The program loop prints random numbers in big format on 
// the righthand side of the display. 

void loop() {
  delay(500) ;                      // Slow so text is legible. 
  printMe = String(randigits(4)) ;  // Get random digits
// Pad to fit specified # of big-character positions. Align right
// or left, depending on the final argument. 
  padforbigs(printMe,4,RIGHT) ;
// Move to specified position in screen, set big chars 
// and print the string. 
  mySerial <<MOVETO <<MIDSCREEN <<BIGMODE <<printMe; ; 
}

//=====================================================================
// FUNCTION: padforbigs 
//=====================================================================
// This function is designed for use with the BPP-440L big-
// character mode. It takes a string and a desired length (in # of 
// big-character positions, up to 8 for the whole screen), and 
// pads the string with spaces to make it fit/erase/replace the 
// entire specified field. It only works with letters A-Z and 
// numbers 0-9, as the big-mode punctuation chars are skinnier. 

void padforbigs(String & s, int olen, boolean rtalign) {
  int ilen ; 
  ilen = s.length() ;
  if (ilen > olen) {            // If the string is too long
    s = s.substring(0,olen) ;   // shorten it. 
  }
  else {
// Since the spaces are made up of ctrl-Q instructions, which 
// turn off the big-character mode, we embed the big-mode 
// instruction to turn it back on. This is only necessary for 
// right alignment; in left alignment, the ctrl-Qs are after
// the big characters. 
    if (rtalign){
      s = String(BIGMODE) + s ;
    }
    while ( ilen < olen ){      // If it's too short, 
      if (rtalign) {            // add spaces to the start
        s = String(bigSpace) + s ;
      }
      else {
        s = s + String(bigSpace) ;   // ..or the end, depending 
      }                         // on desired alignment. 
      ilen ++ ;
    }
  }
}

//=====================================================================
// FUNCTION: randigits
//=====================================================================
// This function returns a random number
// with a random # of digits, up to the # of 
// digits specified. This is to ensure that a
// short run of the demo program will show all 
// possible lengths of of values, so that you can  
// see that the program updates the screen   
// smoothly and erases previous values. 
unsigned int randigits(int numdigs) {
  numdigs = random(numdigs) ;
 switch (numdigs) {
   case 0:
     return random(10) ;
     break ;
    case 1:
     return random(100) ;
     break ;
    case 2:
     return random(1000) ;
     break ;
    case 3:
     return random(10000) ;
     break ;
    case 4:
     return random(65535) ;
     break ;
    default:
      return 42 ;
  } 
}

No comments:

Post a Comment