Shop OBEX P1 Docs P2 Docs Learn Events
Number to text/character conversion — Parallax Forums

Number to text/character conversion

72sonett72sonett Posts: 82
edited 2014-11-13 17:30 in BASIC Stamp
I have a real time clock (RTC) and an LCD connected to a BS2sx. Both work OK separately. I have a subroutine that returns year, month, day, hours & minutes from the RTC and another subroutine that sends single characters to the LCD.

This code gets date/ time from the RTC and shows it OK in a DEBUG screen;
...
GOSUB readRTC    
DEBUG HOME, "20",HEX2 Year,"/",HEX2 Month,"/",HEX2 Date,"-"
DEBUG HEX2 Hours,":",HEX2 Minutes, CR
...
as 2014/11/12-20:54

Now I want to show date & time on an LCD, like:
char = "2"                 ' this is OK
GOSUB SendChar
char = "0"                 ' this too
GOSUB SendChar
char = Year(1)           ' this does not work...
GOSUB SendChar
char = Year(2)           ' this does not work...
GOSUB SendChar
char = "/"                  ' this is OK
GOSUB SendChar
... ' etc
To display correctly on the LCD I need to split the value 14 of the year into the characters ´1´ and ´4´ (similarly for month, day, hour etc). I was thinking of SELECT ... CASE but that would be too long and tedious

How can I do this in a more elegant way?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2014-11-12 12:25
    Is this a serial LCD? If so, you can use the same output editing techniques that you use with DEBUG, SEROUT can output serial I/O to any I/O pin and HEX2 will work the same way. If you have a parallel LCD, your SendChar technique is necessary. Use: char = Year / 16 + "0" for the 1st digit and char = Year // 16 + "0" for the 2nd digit.
  • ElectrodudeElectrodude Posts: 1,646
    edited 2014-11-12 12:30
    You can also use the DIG operator.
    x = 14 DIG 1 ' x = 1
    x = 14 DIG 0 ' x = 4
    

    EDIT: nvm, do what Mike Green said, I forgot RTCs use BCD and not normal decimal
  • 72sonett72sonett Posts: 82
    edited 2014-11-12 12:46
    It is a parallel LCD with a HD44780 chip, similar to http://www.parallax.com/product/603-00006
    Use: char = Year / 16 + "0" for the 1st digit and char = Year // 16 + "0" for the 2nd digit.
    Thanks for the suggestion, I changed the code to
    dispRTC:                          ' Read date/time values
      GOSUB readRTC                   ' and display on the LCD.
       ' this returns  Year = $14,  Month = $11,   Date = $12
       ' Hours = $21 and Minutes = $56
      char = "2"
      GOSUB SendChar
      char = "0"
      GOSUB SendChar
      char = Year / 16 + "0"
      GOSUB SendChar
      char = Year // 16 + "0"
      GOSUB SendChar
      char = "/"
      GOSUB SendChar
      char = Month / 16 + "0"
      GOSUB SendChar
      char = Month // 16 + "0"
      GOSUB SendChar
      char = "/"
      GOSUB SendChar
      char = Date / 16 + "0"
      GOSUB SendChar
      char = Date // 16 + "0"
      GOSUB SendChar
      char = "-"
      GOSUB SendChar
      char = Hours / 16 + "0"
      GOSUB SendChar
      char = Hours // 16 + "0"
      GOSUB SendChar
      char = ":"
      GOSUB SendChar
      char = Minutes / 16 + "0"
      GOSUB SendChar
      char = Minutes // 16 + "0"
      GOSUB SendChar
    RETURN
    

    This now shows "2014/11/12-21:56" on the LCD...
    :smile:
  • Mike GreenMike Green Posts: 23,101
    edited 2014-11-12 14:26
    Great! Now what?
  • Mike GreenMike Green Posts: 23,101
    edited 2014-11-12 14:34
    As far as more elegant is concerned ...

    Create a subroutine called SendHex and a byte variable called hexed like this:

    hexed VAR byte

    SendHex:
    char = hexed / 16 + "0"
    GOSUB SendChar
    char = hexed // 16 + "0"
    GOTO SendChar

    To output some two-digit numbers from the RTC, do:

    hexed = Year
    GOSUB SendHex
    char = "/"
    GOSUB SendChar
    hexed = Month
    GOSUB SendHex

    ... and so on.

    You can get fancier by storing a format string in the EEPROM along with your program by using DATA statements and READ and WRITE and by writing an interpreter for the format string so that your RTC display might look like:

    format DATA "20",1,"/",2,"/",3,"=",4,":",5,0

    You'd do:

    ptr VAR word

    ptr = format
    GOSUB SendForm

    with:

    SendForm:
    READ ptr,char
    ptr = ptr + 1
    IF char = 0 THEN RETURN
    IF char >= 32 THEN
    GOSUB SendChar
    GOTO SendForm
    ENDIF
    hexed = table(char-1)
    GOSUB SendHex
    GOTO SendForm

    A zero byte in the format string terminates the format.
    A byte between 1 and 31 is the index into a table of variable values ("table"). In your case, this is the RTC info.
    Any other byte value is sent to the display as is.
    In your case, "table" is the same as "Year" and you'd use "table VAR Year" to define that alias.
  • 72sonett72sonett Posts: 82
    edited 2014-11-13 04:57
    Mike Green wrote: »
    Great! Now what?
    Big thanks :thumb:.
    As far as more elegant is concerned ... Create a subroutine called SendHex...
    Yes, I could do that.
    ...You can get fancier by storing a format string in the EEPROM along with your program by using DATA statements and READ and WRITE ...
    But that will go at the expense of program space.

    Actually there is also a SmartCard reader attached to the BStamp, as part of an electric gate opening/closing control program. The program has some messages stored in RAM (using PUT). The main loop of the program checks the card reader for a card and displays date & time on the LCD.
    When a card is inserted in the reader, the program checks if it is a valid card by comparing two control characters on the card with two characters coded in the program. If the card is OK, date & time are written to the card and the gate is opened/closed, meanwhile displaying appropriate messages on the LCD (using GET).
  • Mike GreenMike Green Posts: 23,101
    edited 2014-11-13 07:00
    But that will go at the expense of program space.
    Sometimes yes and sometimes no. You have to look at the actual program space used for each type of solution. The 'char = "x" : GOSUB SendChar' over and over again eventually add up to more storage than the DATA string interpreter method.
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2014-11-13 13:18
    This can also be done compactly using the .nib modifiers...
    SendDigit:
         char = hexed.nib1 + "0"
         GOSUB SendChar
         char = hexed.nib0 + "0"
         GOTO SendChar
    
  • 72sonett72sonett Posts: 82
    edited 2014-11-13 13:58
    (For GOTO read GOSUB...)

    This takes up slightly less program space as well, great! :smile:

    But what if ´Month´ were a Nib size variable?
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2014-11-13 17:30
    If month is already a nib-size variable, then just send char = month + "0". Or if hexed is a byte, then this will work,
    [FONT=courier new]hexed = month
    gosub SendDigit[/FONT][FONT=courier new]
    
    SendDigit:   
      char = hexed.nib1 + "0"   
      GOSUB SendChar
      char = hexed.nib0 + "0"
      GOSUB SendChar[/FONT]
    
Sign In or Register to comment.