Coding Parallel LCD w/BS2 - decimal point question
Hi,
I'm trying to get my LCD to output values between 0 and 255. If I start at 0 and increase the numbers, they show up properly. For example, 25 shows up as 25. Then, when I get to 3 digit values, they show up properly as well.
The problem is when I go down from 3 digit numbers to 2 digit numbers. The LCD output stays in 3 digit mode so now my actual output of 25 shows up as 250. The LCD can't get back down to showing 2 or 1 digits unless I reset the whole program.
I'm sure I just have to change a line or something in the code, but I can't figure it out. Can you help? Here's what my code looks like. (Note the variable "TempC" goes from 0 to 255)
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
'
[ Constants ]
LcdCls CON $01 ' clear the LCD
LcdHome CON $02 ' move cursor home
LcdCrsrL CON $10 ' move cursor left
LcdCrsrR CON $14 ' move cursor right
LcdDispL CON $18 ' shift chars left
LcdDispR CON $1C ' shift chars right
LcdDDRam CON $80 ' Display Data RAM control
LcdCGRam CON $40 ' Character Generator RAM
LcdLine1 CON $80 ' DDRAM address of line 1
'
[ Variables ]
char VAR Byte ' character sent to LCD
idx VAR Byte ' loop counter
index VAR Byte ' index counter
flag VAR Bit ' flag variable
Datain VAR Byte ' Variable to hold incoming number (0 to 255)
TempC VAR Word ' Temp in Celcius
TempSpan VAR Word ' Full Scale input span in tenths of degrees.
'
[ EEPROM Data ]
Msg DATA "Go To:", 0 ' store message
'
[ Initialization ]
TempSpan = 5800 ' Declare span. Set Vref to .50V and
' 0 TO 255 res. will be spread over 50
' (hundredths).
Reset:
DIRL = %11111110 ' setup pins for LCD
PAUSE 100 ' let the LCD settle
LCD_Init:
LcdBus = %0011
PULSOUT E, 3
PAUSE 5
PULSOUT E, 3
PULSOUT E, 3
LcdBus = %0010 ' 4-bit mode
PULSOUT E, 1
char = %00101000 ' 2-line mode
GOSUB LCD_Cmd
char = %00001100 ' on, no crsr, no blink
GOSUB LCD_Cmd
char = %00000110 ' inc crsr, no disp shift
GOSUB LCD_Cmd
char = LcdCls ' clear the LCD
GOSUB LCD_Cmd
PAUSE 20
idx = Msg ' get EE address of message
' (loop counter)
GOSUB Write_Message
'PAUSE 20 ' wait 2 seconds
'char = LcdLine2 ' switch to line 2
'GOSUB LCD_Cmd
'PAUSE 20
'idx = Two ' get EE address of message
'GOSUB Write_Message
LCD_Main:
char = LcdLine1 + 9 ' Position cursor after word
GOSUB LCD_Cmd ' Write the value of temperature
GOSUB Write_Var
'PAUSE 500
'char = LcdLine2 + 4 ' Position cursor after word
'GOSUB LCD_Cmd ' Write Y or N to indicate heater on/off
'GOSUB Write_Var2
'char = LcdLine2 + 12
'GOSUB LCD_Cmd
'GOSUB Write_Var3
RETURN
Write_Message:
DO
READ idx, char ' get character from EE
IF (char = 0) THEN EXIT ' if 0, message is complete
GOSUB LCD_Out ' write the character
idx = idx + 1 ' point to next character
LOOP
RETURN
Write_Var:
flag = 0
FOR index = 3 TO 0 ' handle 3 digits
char = TempC DIG index ' check value of 3 digits
IF char THEN flag = 1 ' is digit a zero?
IF flag = 1 THEN ' strip leading zeros only
char = char + $30 ' if not add ASCII offset
GOSUB LCD_Out ' print it
ENDIF
NEXT
RETURN
LCD_Cmd:
LOW RS ' enter command mode
LCD_Out:
LcdBus = char.HIGHNIB ' output high nibble
PULSOUT E, 3 ' strobe the Enable line
LcdBus = char.LOWNIB ' output low nibble
PULSOUT E, 3
HIGH RS ' return to character mode
RETURN
I'm trying to get my LCD to output values between 0 and 255. If I start at 0 and increase the numbers, they show up properly. For example, 25 shows up as 25. Then, when I get to 3 digit values, they show up properly as well.
The problem is when I go down from 3 digit numbers to 2 digit numbers. The LCD output stays in 3 digit mode so now my actual output of 25 shows up as 250. The LCD can't get back down to showing 2 or 1 digits unless I reset the whole program.
I'm sure I just have to change a line or something in the code, but I can't figure it out. Can you help? Here's what my code looks like. (Note the variable "TempC" goes from 0 to 255)
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
'
[ Constants ]
LcdCls CON $01 ' clear the LCD
LcdHome CON $02 ' move cursor home
LcdCrsrL CON $10 ' move cursor left
LcdCrsrR CON $14 ' move cursor right
LcdDispL CON $18 ' shift chars left
LcdDispR CON $1C ' shift chars right
LcdDDRam CON $80 ' Display Data RAM control
LcdCGRam CON $40 ' Character Generator RAM
LcdLine1 CON $80 ' DDRAM address of line 1
'
[ Variables ]
char VAR Byte ' character sent to LCD
idx VAR Byte ' loop counter
index VAR Byte ' index counter
flag VAR Bit ' flag variable
Datain VAR Byte ' Variable to hold incoming number (0 to 255)
TempC VAR Word ' Temp in Celcius
TempSpan VAR Word ' Full Scale input span in tenths of degrees.
'
[ EEPROM Data ]
Msg DATA "Go To:", 0 ' store message
'
[ Initialization ]
TempSpan = 5800 ' Declare span. Set Vref to .50V and
' 0 TO 255 res. will be spread over 50
' (hundredths).
Reset:
DIRL = %11111110 ' setup pins for LCD
PAUSE 100 ' let the LCD settle
LCD_Init:
LcdBus = %0011
PULSOUT E, 3
PAUSE 5
PULSOUT E, 3
PULSOUT E, 3
LcdBus = %0010 ' 4-bit mode
PULSOUT E, 1
char = %00101000 ' 2-line mode
GOSUB LCD_Cmd
char = %00001100 ' on, no crsr, no blink
GOSUB LCD_Cmd
char = %00000110 ' inc crsr, no disp shift
GOSUB LCD_Cmd
char = LcdCls ' clear the LCD
GOSUB LCD_Cmd
PAUSE 20
idx = Msg ' get EE address of message
' (loop counter)
GOSUB Write_Message
'PAUSE 20 ' wait 2 seconds
'char = LcdLine2 ' switch to line 2
'GOSUB LCD_Cmd
'PAUSE 20
'idx = Two ' get EE address of message
'GOSUB Write_Message
LCD_Main:
char = LcdLine1 + 9 ' Position cursor after word
GOSUB LCD_Cmd ' Write the value of temperature
GOSUB Write_Var
'PAUSE 500
'char = LcdLine2 + 4 ' Position cursor after word
'GOSUB LCD_Cmd ' Write Y or N to indicate heater on/off
'GOSUB Write_Var2
'char = LcdLine2 + 12
'GOSUB LCD_Cmd
'GOSUB Write_Var3
RETURN
Write_Message:
DO
READ idx, char ' get character from EE
IF (char = 0) THEN EXIT ' if 0, message is complete
GOSUB LCD_Out ' write the character
idx = idx + 1 ' point to next character
LOOP
RETURN
Write_Var:
flag = 0
FOR index = 3 TO 0 ' handle 3 digits
char = TempC DIG index ' check value of 3 digits
IF char THEN flag = 1 ' is digit a zero?
IF flag = 1 THEN ' strip leading zeros only
char = char + $30 ' if not add ASCII offset
GOSUB LCD_Out ' print it
ENDIF
NEXT
RETURN
LCD_Cmd:
LOW RS ' enter command mode
LCD_Out:
LcdBus = char.HIGHNIB ' output high nibble
PULSOUT E, 3 ' strobe the Enable line
LcdBus = char.LOWNIB ' output low nibble
PULSOUT E, 3
HIGH RS ' return to character mode
RETURN
Comments
It preserves the indentations and makes it more readable.
'[/COLOR] [COLOR=#333333]' {$STAMP BS2}[/COLOR] [COLOR=#333333]' {$PBASIC 2.5}[/COLOR] [COLOR=#333333]'[/COLOR] [COLOR=#333333]' ================================================== =======================[/COLOR] [COLOR=#333333]' -----[ Constants ]-------------------------------------------------------[/COLOR] [COLOR=#333333]LcdCls CON $01 ' clear the LCD[/COLOR] [COLOR=#333333]LcdHome CON $02 ' move cursor home[/COLOR] [COLOR=#333333]LcdCrsrL CON $10 ' move cursor left[/COLOR] [COLOR=#333333]LcdCrsrR CON $14 ' move cursor right[/COLOR] [COLOR=#333333]LcdDispL CON $18 ' shift chars left[/COLOR] [COLOR=#333333]LcdDispR CON $1C ' shift chars right[/COLOR] [COLOR=#333333]LcdDDRam CON $80 ' Display Data RAM control[/COLOR] [COLOR=#333333]LcdCGRam CON $40 ' Character Generator RAM[/COLOR] [COLOR=#333333]LcdLine1 CON $80 ' DDRAM address of line 1[/COLOR] [COLOR=#333333]' -----[ Variables ]-------------------------------------------------------[/COLOR] [COLOR=#333333]char VAR Byte ' character sent to LCD[/COLOR] [COLOR=#333333]idx VAR Byte ' loop counter[/COLOR] [COLOR=#333333]index VAR Byte ' index counter[/COLOR] [COLOR=#333333]flag VAR Bit ' flag variable[/COLOR] [COLOR=#333333]Datain VAR Byte ' Variable to hold incoming number (0 to 255)[/COLOR] [COLOR=#333333]TempC VAR Word ' Temp in Celcius[/COLOR] [COLOR=#333333]TempSpan VAR Word ' Full Scale input span in tenths of degrees.[/COLOR] [COLOR=#333333]' -----[ EEPROM Data ]-----------------------------------------------------[/COLOR] [COLOR=#333333]Msg DATA "Go To:", 0 ' store message[/COLOR] [COLOR=#333333]' -----[ Initialization ]--------------------------------------------------[/COLOR] [COLOR=#333333]TempSpan = 5800 ' Declare span. Set Vref to .50V and[/COLOR] [COLOR=#333333]' 0 TO 255 res. will be spread over 50[/COLOR] [COLOR=#333333]' (hundredths).[/COLOR] [COLOR=#333333]Reset:[/COLOR] [COLOR=#333333]DIRL = %11111110 ' setup pins for LCD[/COLOR] [COLOR=#333333]PAUSE 100 ' let the LCD settle[/COLOR] [COLOR=#333333]LCD_Init:[/COLOR] [COLOR=#333333]LcdBus = %0011[/COLOR] [COLOR=#333333]PULSOUT E, 3[/COLOR] [COLOR=#333333]PAUSE 5[/COLOR] [COLOR=#333333]PULSOUT E, 3[/COLOR] [COLOR=#333333]PULSOUT E, 3[/COLOR] [COLOR=#333333]LcdBus = %0010 ' 4-bit mode[/COLOR] [COLOR=#333333]PULSOUT E, 1[/COLOR] [COLOR=#333333]char = %00101000 ' 2-line mode[/COLOR] [COLOR=#333333]GOSUB LCD_Cmd[/COLOR] [COLOR=#333333]char = %00001100 ' on, no crsr, no blink[/COLOR] [COLOR=#333333]GOSUB LCD_Cmd[/COLOR] [COLOR=#333333]char = %00000110 ' inc crsr, no disp shift[/COLOR] [COLOR=#333333]GOSUB LCD_Cmd[/COLOR] [COLOR=#333333]char = LcdCls ' clear the LCD[/COLOR] [COLOR=#333333]GOSUB LCD_Cmd[/COLOR] [COLOR=#333333]PAUSE 20[/COLOR] [COLOR=#333333]idx = Msg ' get EE address of message[/COLOR] [COLOR=#333333]' (loop counter)[/COLOR] [COLOR=#333333]GOSUB Write_Message[/COLOR] [COLOR=#333333]'PAUSE 20 ' wait 2 seconds[/COLOR] [COLOR=#333333]'char = LcdLine2 ' switch to line 2[/COLOR] [COLOR=#333333]'GOSUB LCD_Cmd[/COLOR] [COLOR=#333333]'PAUSE 20[/COLOR] [COLOR=#333333]'idx = Two ' get EE address of message[/COLOR] [COLOR=#333333]'GOSUB Write_Message[/COLOR] [COLOR=#333333]LCD_Main:[/COLOR] [COLOR=#333333]char = LcdLine1 + 9 ' Position cursor after word[/COLOR] [COLOR=#333333]GOSUB LCD_Cmd ' Write the value of temperature[/COLOR] [COLOR=#333333]GOSUB Write_Var[/COLOR] [COLOR=#333333]'PAUSE 500[/COLOR] [COLOR=#333333]'char = LcdLine2 + 4 ' Position cursor after word[/COLOR] [COLOR=#333333]'GOSUB LCD_Cmd ' Write Y or N to indicate heater on/off[/COLOR] [COLOR=#333333]'GOSUB Write_Var2[/COLOR] [COLOR=#333333]'char = LcdLine2 + 12[/COLOR] [COLOR=#333333]'GOSUB LCD_Cmd[/COLOR] [COLOR=#333333]'GOSUB Write_Var3[/COLOR] [COLOR=#333333]RETURN[/COLOR] [COLOR=#333333]Write_Message:[/COLOR] [COLOR=#333333]DO[/COLOR] [COLOR=#333333]READ idx, char ' get character from EE[/COLOR] [COLOR=#333333]IF (char = 0) THEN EXIT ' if 0, message is complete[/COLOR] [COLOR=#333333]GOSUB LCD_Out ' write the character[/COLOR] [COLOR=#333333]idx = idx + 1 ' point to next character[/COLOR] [COLOR=#333333]LOOP[/COLOR] [COLOR=#333333]RETURN[/COLOR] [COLOR=#333333]Write_Var:[/COLOR] [COLOR=#333333]flag = 0[/COLOR] [COLOR=#333333]FOR index = 3 TO 0 ' handle 3 digits[/COLOR] [COLOR=#333333]char = TempC DIG index ' check value of 3 digits[/COLOR] [COLOR=#333333]IF char THEN flag = 1 ' is digit a zero?[/COLOR] [COLOR=#333333]IF flag = 1 THEN ' strip leading zeros only[/COLOR] [COLOR=#333333]char = char + $30 ' if not add ASCII offset[/COLOR] [COLOR=#333333]GOSUB LCD_Out ' print it[/COLOR] [COLOR=#333333]ENDIF[/COLOR] [COLOR=#333333]NEXT[/COLOR] [COLOR=#333333]RETURN[/COLOR] [COLOR=#333333]LCD_Cmd:[/COLOR] [COLOR=#333333]LOW RS ' enter command mode[/COLOR] [COLOR=#333333]LCD_Out:[/COLOR] [COLOR=#333333]LcdBus = char.HIGHNIB ' output high nibble[/COLOR] [COLOR=#333333]PULSOUT E, 3 ' strobe the Enable line[/COLOR] [COLOR=#333333]LcdBus = char.LOWNIB ' output low nibble[/COLOR] [COLOR=#333333]PULSOUT E, 3[/COLOR] [COLOR=#333333]HIGH RS ' return to character mode[/COLOR] [COLOR=#333333]RETURN
Alternatively, you could clear the display each time before printing a number.
Add the following to the Write_Var: subroutine just before the RETURN
char = " " IF TempC < 100 THEN GOSUB LCD_Out IF TempC < 10 THEN GOSUB LCD_Out
A blank space will be added zero, one or two times, depending on the size of the number you are displaying.