circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

Issue 145 August 2002
Driving the NKK Smartswitch
Part 2: Graphics and Text


GRAPHIC GENERATION

It’s possible to create a graphic image to cover the full 24 × 36 pixels of the display. As with characters, the image is broken into a bit pattern for every row of the graphic image.

Rather than use large blocks of program memory, I restricted the graphics size to a maximum of 16 × 16. This requires 32 bytes per image. I also tacked on 2 bytes to describe the width and height of the image (in pixels), which would work out to 34 bytes. In addition, I limited this to five images because I am not great at graphics (so far I have only managed a fair representation of a maple leaf). The image is included in LCDmem.c as image zero. The generation of images one to four is left to your "image-ination."

The image should be left and top justified within the 16 × 16 matrix so that the first bit of the image is at pictures[x], iBitPattern[0] bit 15. Creation of an image is a lot of work, so once again I resorted to Excel. I used an extended version of the Excel workbook described earlier. You can also download this file from the Circuit Cellar web site.

It’s possible to expand the size of these images by modifying the program in a few areas. The images are contained in a structure called pictures, defined in LCDmem.c and repeated as a header in LCDmem.h. iBitPattern would have to be re-declared as an unsigned long type to cater to the increased number of horizontal pixels and the number of rows would have to be incremented from 16 in the iBitPattern[16] declaration.

In addition, the procedure Load-Graphic in the Command.c module would need to have the iMask modified to a long unsigned type and its initialization (iMask = 0x8000;) changed to suit the larger image. You can also increase the number of images by changing the array declaration pictures[5] in LCDmem.c and LCDmem.h, and by adding in the values for the graphics in the constant array.

THE USER INTERFACE

Before I bore you to tears with a description of the software operation, I want to demonstrate how the user interface works. You can download the command sequences and photos showing the results of the commands from the Circuit Cellar web site.

As you can see, Photo 1 is a mixture of graphics symbols, bit manipulation, and text entry. For all of the command sequences presented, I’ve ignored stating that the interface must poll cCMDs[0] and wait until bit 0 is zero. I have also omitted stating that setting bit 0 of cCMDs[0] to one should happen after all of the other bytes have been set up in order to initiate the action.

(Click here to enlarge)

Photo 1—This flag is actually created in four steps. First, a large block is written across the screen. Second, a gap is opened up in the middle of the block, creating the effect of the sidebars. Third, the maple leaf is inserted into the gap. Finally, the text is written in the bottom line.

SOFTWARE OPERATION

The code for the previously described functions is contained in the module Command.c. The decoding for the commands occurs in the procedure ProcessCommand(), which is a simple C language switch construction.

The heart of all these functions is locating the bit in RAM where the function will start being implemented. This procedure is GenPixel, which takes the pixel number as an integer parameter and generates a value for three variables: cPixRow, cPixColByte, and cPixColMask. These are then used to address a byte in RAM as cMatrix [cPixRow][cPixColByte] and the particular bit is contained on cPixColMask (see Listing 1).

Listing 1—GenPixel identifies the byte and bit associated with a particular pixel through a composite pointer using cPixRow, cPixColByte, and cPixColMask.

Rather than deal with each item in a given row, the items are handled individually, row by row. For instance, a letter will be copied from the character generator table to RAM before the next character is analyzed.

Another interesting procedure is IncPixPnt, which will increment the pixel being dealt with along a line, changing the cPixColMask and cPixColByte when necessary (see Listing 2). Each time a new row is started, the pixel pointer is set 40 pixels ahead of the pointer to the beginning of the current line. No attempt has been made to check for pixels beyond the limits of the RAM matrix. Remember that the leftmost pixel has a numeric value greater than the pixels to the right of it on the same line.

Listing 2—IncPixPnt increments the compound pointer to point to the bit associated with the next pixel on the right.