Shop OBEX P1 Docs P2 Docs Learn Events
DATA Strings and easier way to access them? — Parallax Forums

DATA Strings and easier way to access them?

SlatsSlats Posts: 6
edited 2006-07-21 10:46 in General Discussion
Hello all.... tia for any help...

I was wondering if there is an easy way to solve this problem?· I've done some searching on the forum with little luck.
I know we can use READ to z-strings stored in DATA statments, but is there a better way to access multiple strings?·

For example, suppose I have the following strings stored

stringdata:
· DATA· "String1",0
· DATA· "Stringsasdfa",0
· DATA· "newString asdfas",0

Is there any easy way to access "Stringasdfa" using an index?

Right now I just do this...

stringdata0:
· DATA· "String1",0
stringdata1
· DATA· "Stringsasdfa",0
stringdata2
· DATA· "newString asdfas",0

But I have lots of data to store!· It's for a basic menu system for me.· A similar sample with code is attached...

Thanks,
Mike
a.SXB 1.7K

Comments

  • BeanBean Posts: 8,129
    edited 2006-07-19 19:00
    Mike,
    There are a number of ways to access multiple strings.

    1) Simply read through all the strings (counting the zeros) until you find the one you want
    2) Make them fixed length and offset the read position by stringnumber * length
    3) Prefix each string with a byte count. Read the byte count then offset the read position by that value
    4) Make a seperate data section with a list of string lengths, then add that value to the offset

    If the string data is > 255 bytes you'll have to use word variables. Like this:

    tmpW1 = StringData ' Get address of start of string data
    tmpW1 = tmpW1 + offset ' Adjust address to start of which string I want
    DO
      READ tmpW1, temp1 ' Start reading the string
      IF temp1 = 0 THEN EXIT ' Stop reading if we get a zero
      INC tmpW1 ' Move to next character
    LOOP
    
    


    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com

    "Remember, you are unique, just like everyone else." Unknown.
    ·
  • SlatsSlats Posts: 6
    edited 2006-07-19 19:10
    Thanks Bean I'll give it a try... I think the prefix with the length may be best...
  • JDOhioJDOhio Posts: 72
    edited 2006-07-19 22:02
    I have also implemented a menu using fixed widths (option 2 in Bean's post). In this manner, I don't have to search for the end of the string. I made the menus fixed width because I want the display to show only that menu item. For example, say I have the following menu items:

    DATA "First",0
    DATA "Second",0

    I write Second to the display (I have a 2x16 LCD) and "Second" shows on the display. If I now write First to the display, it appears as "Firstd" because 'Second' has six characters and 'First' has five characters. When I fix the width to the width of the display:

    DATA "First
    ",0 'both have sixteen characters where the dashes would be spaces in my
    DATA "Second
    ",0 'code but I wanted it to display correctly in the post

    Now, Second will display "Second" and First will display "First" because the line is always overwritten.

    I'd like to hear more about your menu implementation. I have mine operational. I have a main menu and each item on the main menu has a single sub menu. My intent is to have each sub menu item perform an action but I haven't got that far.

    Joe
  • SlatsSlats Posts: 6
    edited 2006-07-20 10:54
    Joe,

    Thanks for the info... I've also just started. My implementation allows for up to 16 menu items and 16 sub menus per menu item... (upper nibble of byte = menu, lower nibble of byte = submenu)...

    I'm working on ways to trim the if statements down to something more managable... my next post! I'll start a new thread for the optimization... watch for it in the next few days....

    I'm sure we can swap code and look for advantages....

    Thanks,
    Mike
  • SlatsSlats Posts: 6
    edited 2006-07-20 13:04
    Still stuck.... sorry, I must be missing something...

     temp3 = 1   'index starts at 0, so send 2nd string
     temp4 = 0   ' current offset
     do while temp3 > 0
       read menumain + temp4, temp5
       temp4 = temp4 + temp5
       inc temp4     'For 0 at the end of string
       dec temp3
     loop
     
     do 
       inc temp4     'For string size byte
       read menumain + temp4, temp5
       exit if temp5 = 0
       LCD_OUT temp5
       INC temp4
     loop
    

    MenuMain:
      DATA 11,"asdfklke ka", 0
      DATA  8,"mike8cha", 0
    

    The menu has been changed to protect the innocent! [noparse]:)[/noparse]· However, this is not behaving as expected... the only difference between this code and the original LCD_STR code is the lack of supporting the Z flag...· but when I add

    ········menumain = menumain + Z it fails because menumain is a string pointer I believe.... so is that what is failing here?· If so... I would like to just extend LCD_STR to include a third parameter (index) that would handle this... but I had problems doing that as well...

    For reference here is the LCD_OUT and LCD_STR as they exist today...

    ' -------------------------------------------------------------------------
    ' Use: LCD_OUT theByte {, count }
    ' -- sends "theByte" to LCD [noparse][[/noparse]optional] "count" times
    ' -- "count" defaults to 1 if not specified
    LCD_OUT:
      temp1 = __PARAM1    ' save the byte
      IF __PARAMCNT = 2 THEN   ' "count" specified?
        temp2 = __PARAM2    ' yes, save
      ELSE
        temp2 = 1     ' no, set to 1
      ENDIF
      DO WHILE temp2 > 0
        SEROUT LcdTx, LcdBaud, temp1  ' transmit to LCD
        DEC temp2
      LOOP
      RETURN
    
    ' -------------------------------------------------------------------------
    ' Use: LCD_STR [noparse][[/noparse] string | label ]
    ' -- "string" is an embedded literal string
    ' -- "label" is DATA statement label for stored z-String
    LCD_STR:
      temp3 = __PARAM1                              ' get string offset
      temp4 = __PARAM2                              ' get string base
      DO
        READ temp4 + temp3, temp5                   ' read a character
        IF temp5 = 0 THEN EXIT                      ' if 0, string complete
        LCD_OUT temp5                      ' send the byte
        INC temp3                                   ' point to next character
        temp4 = temp4 + Z                           ' update base on overflow
      LOOP
      RETURN
    
    

    Thanks,
    Mike
  • Dave HeinDave Hein Posts: 6,347
    edited 2006-07-20 15:42
    Mike,

    You are incrementing temp4 twice in the second loop. Instead of printing "mike8cha" you are printing "mk8h". Move the first "inc temp4" statement before the "do" statement.

    Dave
  • SlatsSlats Posts: 6
    edited 2006-07-20 19:00
    Yeah, Caught that a little late!

    So here is my final solution!

    ' -------------------------------------------------------------------------
    ' Use: LCD_STRW2 [noparse][[/noparse] string | label ], index
    ' -- "string" is an embedded literal string
    ' -- "label" is DATA statement label for stored z-String
    ' -- "index" is the strings (see example)
    LCD_STRW2:
      tw1 = __WPARAM12                  'strings base address
      temp3 = __PARAM3                  'index into strings
      if temp3 <> 0 then                ' if 0 then offset  = 1 no need to do work!
        do while temp3 > 0
          read tw1, temp6               'Read offset of current string
          tw1 = tw1 + temp6             'Add offset to current position
          dec temp3
        loop                            'next string 
      endif
      READ tw1, temp5                   'Save ByteCount for this string
      inc tw1                           'Step from ByteCount to string
    
      DO
        READ tw1, temp6                    ' read a character
        IF temp6 = 0 THEN EXIT             ' if 0, string complete
        LCD_OUT temp6                      ' send the byte
        INC tw1                            ' point to next character
        tw1 = tw1 + Z                      ' update base on overflow
      LOOP
     
     
      do while temp5 < 21
        LCD_OUT 32                       'Send spaces to fill the rest of the line
        inc temp5
      loop  
      RETURN
    

    MenuMain:
      DATA 13,"Temperature", 0
      DATA  10,"Humidity", 0
      DATA  12,"Irrigation", 0
    


    Let me start·by explaining the DATA statements...· The byte prior to the string is the the count in bytes of the entire line (including the count and 0)

    EG... if you wanted one called "hello world" it would be:

    ······· DATA· 13,"hello world",0

    I then use these bytecounts to determine how far forward to move the start of the string... I also use this bytecount to determine the number of spaces needed to fill the line on my LCD (4x20) to handle overwritting a longer string with a shorter one!

    Feel free to comment/fix! [noparse]:)[/noparse]

    Thanks,
    Mike
  • BeanBean Posts: 8,129
    edited 2006-07-20 19:07
    Mike,
    Looks cool.
    If you test __PARAMCNT you could make it work for literal strings too.
    If __PARAMCNT is 2 then it's a literal string, if __PARAMCNT is 3 then it's a label and an index.

    Then you could do:

    LCD_STRW2 MainMenu, 1
    LCD_STRW2 "Testing"
    LCD_STRW2 MainMenu, 2

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com

    "Remember, you are unique, just like everyone else." Unknown.
    ·
  • JDOhioJDOhio Posts: 72
    edited 2006-07-20 22:07
    Mike,

    I was following this thread and wondered how I might store my menu items without spaces. I have a DO loop that also calls LCD_OUT but it is in a separate function. I was going to try modifying it to return the number characters it writes and use that to write spaces to the display like you do at the end of LCD_STRW2. I'll let you know.

    Did you have some thoughts on how you would indicate the active menu item on the screen? I display a right-pointing arrow as a cursor in the first column. To move to another item, I use a four-position switch to navigate (eg, down moves the cursor to the next item and up moves it to the previous item). There is some administration to provide for moving the menu around on the screen but that might be a different post.

    Joe
  • SlatsSlats Posts: 6
    edited 2006-07-21 10:46
    I only show the menu title and the active menu item so I don't have this issue if I'm understanding you correctly...

    IE..

    My display shows:

    Main Menu
    Blah1

    Pressing one of my direction keys (left or right) produces the next menu item...

    Main Menu
    Blah 2

    etc...

    I then have a select key which selects the current shown menu item to do work on that item...

    Thanks,
    Mike
Sign In or Register to comment.