Odometer Effect with BPI- and BPK-series Displays
The LCD Serial Backpack gives you access to all LCD capabilities via a convenient serial connection. One often-overlooked LCD feature is the custom symbol set. By downloading data (bit patterns) to character-generator RAM you can change the appearance of up to eight special symbols.
This BASIC Stamp 2 program shows how to use one custom character to produce a useful and attractive animation effect that simulates the vertical scrolling of the last digit of an odometer.
' Program: ODO1.BS2 ("Odometer" style display on 2x16 Serial LCD) ' Contributed by: Scott Edwards. ' Configure display for 9600 baud; serial in to BS2 P0. ' This program demonstrates an interesting animation effect on a ' 2x16 LCD equipped with the LCD Serial Backpack (R) interface. ' It displays an on-screen counter whose lowest digit 'rolls up' ' just like the tenths-of-a-mile digit in a car's mechanical ' odometer. The effect was actually inspired by jackpot displays ' in Las Vegas, which use a similar effect. ' The technique for producing this effect relies on a little-known ' aspect of the LCD's CG (character generator) RAM. Alphanumeric ' LCDs give you 8 symbols whose bit patterns are stored in CG RAM. ' Writing to CG RAM changes the appearance of the symbol corresponding ' to the RAM address. The subtle thing is that when you write to CG ' RAM you change the bit pattern of symbols already displayed on the ' screen. For example, if your display shows symbol 0 in five different ' locations, changing symbol 0's bit pattern would alter all five ' instances of the character. ' In this application, we use symbol 0 as the final digit of a ' counter. Symbol 0 is initially defined with the bit pattern for ' "0". Each time the count increments, the program scrolls upward ' one position in an 80-byte table of bit patterns for the numbers ' "0" through "9". The visual effect is that the last digit of the ' counter rolls upward from one digit to the next. When it rolls ' from 9 to 0, the ones digit of the main counter increments. ' ==== TABLE OF BIT PATTERNS ' This table contains the bit patterns for the numbers 0-9 in the format ' used for LCD custom characters. There are a total of 80 bytes in this ' table. zero data $E,$11,$13,$15,$19,$11,$E,$0 one data $4,$C,$4,$4,$4,$4,$1F,$0 two data $E,$11,$11,$2,$4,$8,$1F,$0 three data $1F,$2,$4,$2,$1,$11,$E,$0 four data $2,$6,$A,$12,$1F,$2,$2,$0 five data $1F,$10,$1E,$1,$1,$11,$E,$0 six data $6,$8,$10,$1E,$11,$11,$E,$0 seven data $1F,$1,$2,$4,$8,$8,$8,$0 eight data $E,$11,$11,$E,$11,$11,$E,$0 nine data $E,$11,$11,$F,$1,$2,$6,$0 ' ==== CONSTANTS n9600 con $4054 ' Baudmode for 9600 bps inverted serial. I con $FE ' Instruction prefix CG con 64 ' Base address of custom-character 0. DD con 128 ' Base address of display RAM. clrLCD con 1 ' Clear-screen instruction. cntrPos con 196 ' Screen location of the counter. ' ==== VARIABLES patPntr var byte ' Pointer into the EEPROM data. index var nib ' Counter variable for loading 8 bytes to CG RAM. LCData var byte ' Data for xfer to the LCD. mainCnt var word ' Main counter ' ==== STARTUP ' To begin, the program waits a second to allow the display to ' initialize, then clears the screen and displays the title "Odometer ' Effect". It then executes updateCnt to display the counter. pause 1000 serout 0,n9600,[I,clrLCD] ' Clear the screen. pause 10 ' Wait a moment for clear to finish. serout 0,n9600,["Odometer Effect"] ' Print the title. gosub updateCnt ' Put the counter on screen. ' ==== MAIN PROGRAM LOOP ' This loop uses a pair of subroutines to scroll the last digit of ' the counter upward (xferPattern) and to update the state of the ' main, 5-digit counter (updateCnt). When the last digit has scrolled ' upward to the point that "9" rolls over to "0" it's time to increment ' the main counter. It takes 80 loops to go through the whole scrolling ' animation, so the main counter increments at 1/80th the loop rate. ' In an actual application, you'd probably need to use a little math ' to adjust the relationship of the scrolling rate to the event being ' counted. again: gosub xferPattern ' Define the bit pattern. if patPntr <> 80 then skip1 ' When we hit 80, increment the gosub updateCnt ' main counter. skip1: pause 50 ' Slow down a little to avoid blur. goto again ' Run continuously. ' ==== SUBROUTINE: updateCnt ' Prints the 5-digit counter value at cntrPos, followed by the ' animated symbol (ASCII 0). Strictly speaking, it's not ' necessary to keep reprinting the symbol, but doing so in ' this subroutine saves us the trouble of using a separate ' Serout to print the symbol the first time. --After displaying ' the counter, updateCnt adds 1 to it and resets the animation ' point to the beginning of the bit patterns. updateCnt: serout 0,n9600, [I,cntrPos,DEC5 mainCnt,0] mainCnt = mainCnt + 1 patPntr = 0 return ' ==== SUBROUTINE: xferPattern ' Transfers the current bit pattern to CG memory. xferPattern: serout 0,n9600,[I,CG] ' Go to CG RAM. for index = 0 to 7 ' Load 8 bytes of character pattern. read ((patPntr + index) //80), LCData ' Get byte from EEPROM. serout 0,n9600,[LCData] ' Send it to CG RAM. next ' Send all 8 bytes. patPntr = patPntr+1 ' Point to next location in table. return