LCDs and Variables to Strings
dwalker2020
Posts: 1
I am using the Stampworks set (PDB and a BS2) and I am trying to make the 2x16 parallel LCD display·the result of a RCTIME command. The screen would look like "10·· Micro-Second", or "100 Micro-Second". I tried to make the program similiar to experiment number 11 for the lcd stuff and experiment number 5 for the pot code (and hardware). You can check them out on the online version of the Stampworks book.
·
In order to display the variable (rawSpd (which is between 9 and 695, though there are hardware tolerences to take into account)) like they did in experiment 11, I would have to convert the variable to a string, store the string using DATA, and then read it off bit by bit to send it to the Hitatchi HD44780U in the display. I don't know how to convert the variable to a string, so this approach wasn't possible for me (I am still going through the Stampworks experiments). Does anyone know how to do that?
·
Instead, I used the lowest level approach possible and used If statements (and nested ones) to weed out a single digit of the variable, add 48 to it (to make it a standard ASCII number), then sent it to the display, and then do the next digit if it had more digits. This was really painful to do and required me to write it so that it would repeat everything multiple times for the different amounts of digits (I also threw in one digit in case the rawSpd some how <10).
·
My question is whether or not there is an easier way to do all of this. My dad now tells me that I should have used more subroutines (for getting digits) and loops....
My program:
'·· {$STAMP BS2}
'·· {$PBASIC 2.5}
'
' =========================================================================
'
[noparse][[/noparse] Program Description ]
'
' This program displays the results of an RCTIME command and "Micro-seconds" on a paralell LCD.
'
[noparse][[/noparse] I/O Definitions ]
E·············· PIN···· 1······················ ' Enable pin
RW············· PIN···· 2······················ ' Read/Write
RS············· CON···· 3······················ ' Register Select
LcdBus········· VAR···· OUTB··················· ' 4-bit LCD data bus
Speed·········· PIN···· 14····················· ' Pot pin
'
[noparse][[/noparse] 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
LcdLine2······· CON···· $C0···················· ' DDRAM address of line 2
'
[noparse][[/noparse] Variables ]
char··········· VAR···· Byte··················· ' character sent to LCD
idx············ VAR···· Byte··················· ' loop counter for printing to LCD
idx2··········· VAR···· Byte··················· ' loop counter for the spaces between rawSpd and microseconds
rawSpd········· VAR···· Word··················· ' RCTIME output variable
newchar········ VAR···· Byte··················· ' Space for
'
[noparse][[/noparse] EEPROM Data ]
· Msg············ DATA··· "Micro-Second", 0
'
[noparse][[/noparse] Initialization ]
· DIRL = %11111110····························· ' setup pins for LCD
· PAUSE 100···································· ' let the LCD settle
Lcd_Setup:
· LcdBus = %0011······························· ' 8-bit mode
· PULSOUT E, 3
· PAUSE 5
· PULSOUT E, 3
· PULSOUT E, 3
· LcdBus = %0010······························· ' 4-bit mode
· PULSOUT E, 1
· char = %00001100····························· ' on, no crsr, no blink
· GOSUB LCD_Cmd
· char = %00000110····························· ' inc crsr, no disp shift
· GOSUB LCD_Cmd
'
[noparse][[/noparse] Program Code ]
Main:
· char = LcdCls································ ' clear the LCD
· GOSUB LCD_Cmd
· PAUSE 5
· GOSUB Read_Speed····························· ' gets R/C circuit speed
· DEBUG ? rawSpd
· idx = Msg
Write_Message:
·IF (rawSpd < 10) THEN························· ' if rawSpd is single digit
··· char = rawSpd
··· char = char + 48··························· ' char + (ASCII of 0) to get ASCII of rawSpd
··· GOSUB LCD_Out
··· PAUSE 5
··· FOR idx2 = 1 TO 3··························· ' put in a couple spaces to standardize placement of "microseconds"
····· char = LcdDispR
····· GOSUB LCD_Out
··· NEXT
··· DO··········································· ' loop to print microseconds
····· 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
··· PAUSE 400···································· ' let me have enough time to see the LCD before erasing
··· ENDIF
·IF (rawSpd > 9) THEN···························· ' if rawSpd has 2 or 3 digits
···· IF (rawSpd <100)THEN························ ' weeds out the 3 digit numbers
······· char = rawSpd DIG 1······················ ' gets first digit
······· char = char + 48························· ' gets ASCII by normalizing to ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· char = rawSpd DIG 0······················ ' gets second digit
······· char = char + 48························· ' gets ASCII by normalizing to ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· FOR idx2 = 1 TO 2························ ' puts in some spaces for microseconds
········· char = LcdDispR
········· GOSUB LCD_Out
········· NEXT
······· DO··········································· ' loop to print microseconds
········· 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
······· PAUSE 400
····· ELSE··········································· ' all the rest are three digit
······· char = rawSpd DIG 2·························· ' get first digit
······· char = char + 48
······· GOSUB LCD_Out
······· PAUSE 5
······· char = rawSpd DIG 1··························· ' gets second digit
······· char = char + 48······························ ' gets ASCII by normalizing TO ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· char = rawSpd DIG 0··························· ' gets third digit
······· char = char + 48······························ ' gets ASCII by normalizing TO ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· char = LcdDispR······························· ' one space for micro second
······· GOSUB LCD_Out
······· DO··········································· ' loop to print microseconds
········· 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
······· PAUSE 400
····· ENDIF
· ENDIF
GOTO Main
'
[noparse][[/noparse] Subroutines ]
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
Read_Speed:
· HIGH Speed··································· ' charge cap
· PAUSE 1······································ ' for 1 millisecond
· RCTIME Speed, 1, rawSpd······················ ' read the pot (in 2 micro second units...)
· RETURN
·
In order to display the variable (rawSpd (which is between 9 and 695, though there are hardware tolerences to take into account)) like they did in experiment 11, I would have to convert the variable to a string, store the string using DATA, and then read it off bit by bit to send it to the Hitatchi HD44780U in the display. I don't know how to convert the variable to a string, so this approach wasn't possible for me (I am still going through the Stampworks experiments). Does anyone know how to do that?
·
Instead, I used the lowest level approach possible and used If statements (and nested ones) to weed out a single digit of the variable, add 48 to it (to make it a standard ASCII number), then sent it to the display, and then do the next digit if it had more digits. This was really painful to do and required me to write it so that it would repeat everything multiple times for the different amounts of digits (I also threw in one digit in case the rawSpd some how <10).
·
My question is whether or not there is an easier way to do all of this. My dad now tells me that I should have used more subroutines (for getting digits) and loops....
My program:
'·· {$STAMP BS2}
'·· {$PBASIC 2.5}
'
' =========================================================================
'
[noparse][[/noparse] Program Description ]
'
' This program displays the results of an RCTIME command and "Micro-seconds" on a paralell LCD.
'
[noparse][[/noparse] I/O Definitions ]
E·············· PIN···· 1······················ ' Enable pin
RW············· PIN···· 2······················ ' Read/Write
RS············· CON···· 3······················ ' Register Select
LcdBus········· VAR···· OUTB··················· ' 4-bit LCD data bus
Speed·········· PIN···· 14····················· ' Pot pin
'
[noparse][[/noparse] 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
LcdLine2······· CON···· $C0···················· ' DDRAM address of line 2
'
[noparse][[/noparse] Variables ]
char··········· VAR···· Byte··················· ' character sent to LCD
idx············ VAR···· Byte··················· ' loop counter for printing to LCD
idx2··········· VAR···· Byte··················· ' loop counter for the spaces between rawSpd and microseconds
rawSpd········· VAR···· Word··················· ' RCTIME output variable
newchar········ VAR···· Byte··················· ' Space for
'
[noparse][[/noparse] EEPROM Data ]
· Msg············ DATA··· "Micro-Second", 0
'
[noparse][[/noparse] Initialization ]
· DIRL = %11111110····························· ' setup pins for LCD
· PAUSE 100···································· ' let the LCD settle
Lcd_Setup:
· LcdBus = %0011······························· ' 8-bit mode
· PULSOUT E, 3
· PAUSE 5
· PULSOUT E, 3
· PULSOUT E, 3
· LcdBus = %0010······························· ' 4-bit mode
· PULSOUT E, 1
· char = %00001100····························· ' on, no crsr, no blink
· GOSUB LCD_Cmd
· char = %00000110····························· ' inc crsr, no disp shift
· GOSUB LCD_Cmd
'
[noparse][[/noparse] Program Code ]
Main:
· char = LcdCls································ ' clear the LCD
· GOSUB LCD_Cmd
· PAUSE 5
· GOSUB Read_Speed····························· ' gets R/C circuit speed
· DEBUG ? rawSpd
· idx = Msg
Write_Message:
·IF (rawSpd < 10) THEN························· ' if rawSpd is single digit
··· char = rawSpd
··· char = char + 48··························· ' char + (ASCII of 0) to get ASCII of rawSpd
··· GOSUB LCD_Out
··· PAUSE 5
··· FOR idx2 = 1 TO 3··························· ' put in a couple spaces to standardize placement of "microseconds"
····· char = LcdDispR
····· GOSUB LCD_Out
··· NEXT
··· DO··········································· ' loop to print microseconds
····· 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
··· PAUSE 400···································· ' let me have enough time to see the LCD before erasing
··· ENDIF
·IF (rawSpd > 9) THEN···························· ' if rawSpd has 2 or 3 digits
···· IF (rawSpd <100)THEN························ ' weeds out the 3 digit numbers
······· char = rawSpd DIG 1······················ ' gets first digit
······· char = char + 48························· ' gets ASCII by normalizing to ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· char = rawSpd DIG 0······················ ' gets second digit
······· char = char + 48························· ' gets ASCII by normalizing to ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· FOR idx2 = 1 TO 2························ ' puts in some spaces for microseconds
········· char = LcdDispR
········· GOSUB LCD_Out
········· NEXT
······· DO··········································· ' loop to print microseconds
········· 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
······· PAUSE 400
····· ELSE··········································· ' all the rest are three digit
······· char = rawSpd DIG 2·························· ' get first digit
······· char = char + 48
······· GOSUB LCD_Out
······· PAUSE 5
······· char = rawSpd DIG 1··························· ' gets second digit
······· char = char + 48······························ ' gets ASCII by normalizing TO ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· char = rawSpd DIG 0··························· ' gets third digit
······· char = char + 48······························ ' gets ASCII by normalizing TO ASCII 0
······· GOSUB LCD_Out
······· PAUSE 5
······· char = LcdDispR······························· ' one space for micro second
······· GOSUB LCD_Out
······· DO··········································· ' loop to print microseconds
········· 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
······· PAUSE 400
····· ENDIF
· ENDIF
GOTO Main
'
[noparse][[/noparse] Subroutines ]
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
Read_Speed:
· HIGH Speed··································· ' charge cap
· PAUSE 1······································ ' for 1 millisecond
· RCTIME Speed, 1, rawSpd······················ ' read the pot (in 2 micro second units...)
· RETURN