Shop OBEX P1 Docs P2 Docs Learn Events
Problem with Numbers object — Parallax Forums

Problem with Numbers object

AdisharrAdisharr Posts: 3
edited 2012-03-13 17:51 in Propeller 1
Hi All,

First time posting here - certainly seems to be no end of brain power in this forum :)

I'm just starting out using my Propeller board I purchased a couple years back and have run into an issue using the numbers.spin object.

I have a number of pins attached to a small parallel LCD and have been able to print out characters from a string variable. No problems there. I have been unable to get the Num.ToStr object interface working though.

See code below:
VAR

BYTE    LCD_RS                  'LCD REGISTER SELECT (0=COMMAND, 1=DATA) 
BYTE    LCD_RW                  'LCD READ/WRITE SELECT SIGNAL (0=WRITE, 1=READ)
BYTE    LCD_E                   'LCD OPERATION ENABLE SIGNAL (FALLING EDGE TRIGGERED)
LONG    TEST_NUMBER             'USED IN TEST NUMBERS OBJECT
LONG    STRINGPOINTER           'USED IN TEST NUMBERS OBJECT
BYTE    X                       'INDEX VARIABLE
BYTE    CHAR_INDEX

OBJ

  NUM : "Numbers"

PUB Main

DIRA[0..10]~~                   'SET LCD I/O PINS TO OUTPUT

DELAY(10_000_000)

LCD_RS := 10
LCD_RW := 9

{FORMAT DISPLAY}

LCD_DISPLAY_CTRL
LCD_FORMAT                                

'CLEAR DISPLAY

LCD_CLEAR
LCD_HOME

{PRINT STRING TEST}

DELAY(1_000_000)

REPEAT CHAR_INDEX FROM 0 TO 9

  OUTA[0..7] := TEST_STRING[CHAR_INDEX]
  OUTA[LCD_RS]~~
  OUTA[LCD_RW]~
  OUTA[8]~~
  OUTA[8]~  

{NUMBER TO STRING TEST}

NUM.INIT                        'INITIALIZE NUMBERS OBJECT

TEST_NUMBER := 5678

STRINGPOINTER := NUM.TOSTR(TEST_NUMBER, NUM#DEC)

DELAY(5_000_000)

REPEAT X FROM 0 TO 3

  OUTA[0..7] := BYTE[@STRINGPOINTER][X]
  OUTA[LCD_RS]~~
  OUTA[LCD_RW]~
  OUTA[8]~~
  OUTA[8]~  

  DELAY(200_000)

REPEAT

{------------------------------------------------------------------------------------}

PUB LCD_DISPLAY_CTRL

OUTA[0..7] := �001111         'CONTROL DISPLAY COMMAND
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~                       'SEND ENABLE PULSE
OUTA[8]~

PUB LCD_CLEAR

OUTA[0..7] := �000001         'CLEAR DISPLAY COMMAND
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~                       'SEND ENABLE PULSE
OUTA[8]~

PUB LCD_HOME

OUTA[0..7] := �000010         'HOME DISPLAY COMMAND
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~                       'SEND ENABLE PULSE
OUTA[8]~

PUB LCD_FORMAT

OUTA[0..7] := �111100
OUTA[LCD_RS]~
OUTA[LCD_RW]~

OUTA[8]~~
OUTA[8]~

PUB DELAY(TIME)

WAITCNT(TIME + CNT)

DAT

TEST_STRING   BYTE      "123456789 ",0

The 'Print String' test works fine - the 'Number to string test' just prints garbage.

I've used the print string function in the parallax serial terminal and that seems to work correctly. Any ideas what's going on?

Let me know if you need more information.

Thanks..

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-03-13 00:37
    TEST_NUMBER := 5678
    
    STRINGPOINTER := NUM.TOSTR(TEST_NUMBER, NUM#DEC)
    
    DELAY(5_000_000)
    
    REPEAT X FROM 0 TO 3
    
      OUTA[0..7] := BYTE[[COLOR="red"]@[/COLOR]STRINGPOINTER][X]
      OUTA[LCD_RS]~~
      OUTA[LCD_RW]~
      OUTA[8]~~
      OUTA[8]~  
    
    STRINGPOINTER is an address. So unless you want to display said address I'd get rid of the @ in which case you'll display the first 4 characters of the string.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-03-13 01:19
    Sorry kuroneko, but I think we need to be a little bit more precise with the speach in this case. ALL variables ARE addresses for the compiler! The important question is "What does the variable contain?" and what does the compiler do when using @. STRINGPOINTER CONTAINS an address.

    Let's assume we have the following memory map. (This is only hypothetical
    RAM-Address    Label         Content  Size
          ..
        $1000    STRINGPOINTER   0        Long
        $1004    TEST_NUMBER     0        Long
        $1008    X               0        Long
          ..
        $1200    STRBUFFER       0        Byte array [13]
        $1201                    0
          ..
        $120D                    0
    
    What does your progam do with this memory:

    TEST_NUMBER := 5678
    RAM-Address    Label         Content  Size
          ..
        $1000    STRINGPOINTER   0        Long
        $1004    TEST_NUMBER     [color=red]5678[/color]     Long
        $1008    X               0        Long
          ..
        $1200    STRBUFFER       0        Byte array [13]
        $1201                    0
          ..
        $120D                    0
    
    [sp][/sp]
    [sp][/sp]
    STRINGPOINTER := NUM.TOSTR(...)
    RAM-Address    Label         Content  Size
          ..
        $1000    STRINGPOINTER   0        Long
        $1004    TEST_NUMBER     5678     Long
        $1008    X               0        Long
          ..
    [color=red]
        $1200    STRBUFFER       "5"      Byte array [13]
        $1201                    "6"
        $1202                    "7"
        $1203                    "8"
        $1204                    0
    [/color]
          ..
        $120D                    0
    

    [sp][/sp]
    [sp][/sp]
    STRINGPOINTER := NUM.TOSTR(...)
    RAM-Address    Label         Content  Size
          ..
        $1000    STRINGPOINTER   [color=red]$1200[/color]    Long
        $1004    TEST_NUMBER     5678     Long
        $1008    X               0        Long
          ..
        $1200    STRBUFFER       "5"      Byte array [13]
        $1201                    "6"
        $1202                    "7"
        $1203                    "8"
        $1204                    0
          ..
        $120D                    0
    

    So, what will OUTA be in the first iteration?
    REPEAT X FROM 0 TO 3
    OUTA[0..7] := BYTE[@STRINGPOINTER][X]

    [sp][/sp]
    @STRINPOINTER is equal to $1000, so what whe have is
    OUTA[0..7] := content of the memory location $1000 + 0 (0 coming from X) := 00

    In the next iteration it would be
    OUTA[0..7] := content of the memory location $1000 + 1 (1 coming from X) := 12

    (if I remember right the prop is least significant byte first)

    PS: Adding the missing bit here ;o)
    So, @STRINGPOINTER is NOT what you want!
    You want to have the content of STRBUFFER and it's following bytes.
    STRBUFFER is equal to address $1200 and this value (the address itself) is stored in STRINGPOINTER. So, if you want to read from $1200 you simply say:
    OUTA[0..7] := byte[ STRINGPOINTER ][ i ] which is the same as
    byte[ $1200 ][ i ] or in other words "give me the content of memory location $1200 + i" which is "5"
  • AdisharrAdisharr Posts: 3
    edited 2012-03-13 07:15
    Thanks you very much for the detailed reply - I need to take a little time and digest this but I think this will solve my problem. Looks like to need to spend more time understanding the data formats and how things are referenced :innocent:
  • AdisharrAdisharr Posts: 3
    edited 2012-03-13 17:51
    MagIO2 wrote: »

    PS: Adding the missing bit here ;o)
    So, @STRINGPOINTER is NOT what you want!
    You want to have the content of STRBUFFER and it's following bytes.
    STRBUFFER is equal to address $1200 and this value (the address itself) is stored in STRINGPOINTER. So, if you want to read from $1200 you simply say:
    OUTA[0..7] := byte[ STRINGPOINTER ][ i ] which is the same as
    byte[ $1200 ][ i ] or in other words "give me the content of memory location $1200 + i" which is "5"

    Thank you very much - your initial explanation clued me to try the STRINGPOINTER without the '@' and it worked great :smile::smile::smile:
Sign In or Register to comment.