Shop OBEX P1 Docs P2 Docs Learn Events
Simple String Help — Parallax Forums

Simple String Help

davidpzkdavidpzk Posts: 19
edited 2012-01-17 07:27 in Propeller 1
I wrote a little sample code (below) to teach myself how strings work. I expected the output of the string to be "abc" but instead its "..."

This proves that I dont understand how strings work. Can someone point me in the correct direction here?
con
  _clkmode = xtal1 + pll16x '
  _xinfreq = 5_000_000 '
var
  long count1
obj
  term : "Parallax Serial Terminal" 
PUB Main
term.start(9600)
term.str(string("starting...",13)) 
waitcnt (9000000+cnt) 
term.str(string("starting...",13))
count1[0] := "a"
count1[1] := "b"
count1[2] := "c"  
waitcnt (90000000+cnt)
term.str(count1)

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-16 12:45
    You're asking for trouble if you use anything but bytes to store characters.

    Change the variable section to:
    VAR
      byte count1[4]
    
    

    I think that will fix it.
  • davidpzkdavidpzk Posts: 19
    edited 2012-01-16 13:35
    Code changed as suggested. I still come up with a result of "---" when I expected to have a result of "abc"
    con
      _clkmode = xtal1 + pll16x '
      _xinfreq = 5_000_000 '
    var
      byte count1 [4]
    obj
      term : "Parallax Serial Terminal" 
    PUB Main
    term.start(9600)
    term.str(string("starting...",13)) 
    waitcnt (9000000+cnt) 
    term.str(string("starting...",13))
    count1[0] := "a"
    count1[1] := "b"
    count1[2] := "c"  
    waitcnt (90000000+cnt)
    term.str(count1)
    
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-16 13:41
    Sorry, I missed this the first time.
    term.str([COLOR=#ff0000]@[/COLOR]count1)
    
  • davidpzkdavidpzk Posts: 19
    edited 2012-01-16 13:48
    That was it! Thank you.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-16 14:09
    You are very welcome.


    FYI, this code in the original,
    count1[1] := "b"
    
    assigned "b" to the long after count1 or four bytes after "a". ["a"][0][0][0]["b"][0][0][0]

    If you fix the @ problem in the first code, you'd probably just get "a" displayed since the other three bytes of the long where zero.

    The Propeller Manual explains the way longs, word and bytes are stored (I don't remember where). But as I said earlier, it's a good idea to only use bytes when working with charater arrays. (Unless you're using a pointer to the array which should be a word or long.)

    You can access individual bytes within a long. There are several ways to to this, the method I generally use is byte[@count1 + 1] to access the second byte.

    So if you left count1 as a long and made these changes.
    count1 := "a" 'same as before
      byte[@count1 + 1] := "b"
      byte[@count1 + 2] := "c"
    

    I think this would get you the output you were looking for but it's a really awkward way to do it.
  • davidpzkdavidpzk Posts: 19
    edited 2012-01-16 17:36
    When sending a string to the terminal,

    Why at times does the command

    term.str(count1)

    work fine without the @ sign and other times we need the @ sign?

    term.str(@count1)
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-16 18:04
    davidpzk wrote: »
    Why at times does the command

    term.str(count1)

    work fine without the @ sign and other times we need the @ sign?

    term.str(@count1)
    Assuming count1 refers to the same entity then you're just lucky. But I suspect that's not what you mean. term.str expects an address (to a string), e.g.
    addr := string("Hi there")
      term.str(addr)
    
    will work as advertised (string() returns an address). The other case is when you use an array (VAR or DAT, usually bytes). Simply referring to it by name will give you its first element (which is not normally an address), i.e. array is the same as array[0]. To treat the array as a string we need the @. It returns the address of an array element, i.e. using @array[1] will skip the first character (assuming a byte array).
    VAR
      byte  array[32]
    
    PRI print
    
      term.str(@array[0])   ' print string stored in array
      term.dec( array[0])   ' print array element 0 as number, e.g. first character
      term.tx(  array[0])   ' print array element 0 as character
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-17 00:04
    I'll add an example of when you wouldn't use "@" in the str method parameter.

    If you change your variable section to:
    VAR
      byte count1[4]
      word count2
    

    And make this change. Instead of this:
    term.str(@count1)
    

    Use:
    count2 := @count1
      term.str(count2)
    

    In this case count2 is the address of count1. You could also use the dec method to display the memory location of count1.
    term.dec(count2)
    

    Which, after you've made the "count2 := @count1" assignment, should give you the same output as:
    term.dec(@count1)
    

    For fun you could add a DAT section at the end like this:
    DAT
    myArray  byte "Hello World", 0
    

    And up in the main section of code use:
    term.str(string(13, "myArray location = $"))
      term.hex(@myArray, 4)
    

    Then in the Propeller Tool, use F8, click "Show Hex" and find the location displayed by the terminal window output. You should see "Hello World" in the far right window stored at this location.

    This type of activity helped me understand the whole pointer and location concept.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-01-17 07:05
    Just another thing spotted in the original code:
    term.start(9600)
    term.str(string("starting...",13)) 
    waitcnt (9000000+cnt) 
    term.str(string("starting...",13))
    

    As far as I remember the Propeller Tool is not optimizing. So, it does not recognize that both strings are equal and will really create 2 copies in memory.

    What you can do is create a version of the string in a DAT section and use this ... or ... I think even more effective is to create a function and call this.
    ...
      term.start(9600)
      term.str( @starting )
      waitcnt (9000000+cnt) 
      term.str( @starting )
    ...
    DAT
      starting  byte "starting...",13,0
    

    or
    ...
       term.start(9600)
       strt
       waitcnt (9000000+cnt) 
       strt
    ...
    PUB strt
       term.str(string("starting...",13)) 
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-17 07:27
    I was initially very confused about the "string" command when I first started using the Prop. Hopefully this post will help others better understand it.

    Another (more awkward) way to do what MagIO2 suggests is to have a word variable to store the string's location.
    VAR
      ' other variables
      word startingText
    

    And then early in the program use:
    startingText := string("starting...")
    

    Then any time you wanted to use the string use.
    term.str(startingText)
    

    This is one of those times you don't want to use the "@" operator.

    Again, since it's so much fun, you could add (after you've assigned the string to startingText):
    term.hex(startingText, 4)
    

    You could then look for this location in your code using F8 and "Show Hex". You should find the text "starting..." in the far right window at the location displayed using the above code.

    MagIO2's suggestions on using a string multiple times are much better ways than the way I just described. The method I used was to show what the command "string" is doing and why you don't always need the @ symbol when sending strings to be displayed.
Sign In or Register to comment.