Shop OBEX P1 Docs P2 Docs Learn Events
DATA Statements with Variables — Parallax Forums

DATA Statements with Variables

hmlittle59hmlittle59 Posts: 404
edited 2007-12-12 06:55 in BASIC Stamp
Hello Everyone

I have a Data Statement such as...Data "Cost is $", Dollar, ".00", were (Dollar var byte) is defined. The Editor will not except it. It returns the error saying that it needs to be a constant. I changed...Dollar...to a constant and it was excepted...How can I get around this?

1) I need to place a variable statement within a DATA statement.
2) Text in front and Text after the variable

Any help...Thanks

hmlittle59

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-10 02:31
    You can't put a variable statement within a DATA statement. It is all constant.

    You're right with #2. You can have the text before the variable part and the
    text after the variable part and furnish the variable part separately.
  • aliniousalinious Posts: 51
    edited 2007-12-10 03:34
    One thing to remember is that the DATA command stores values (constant data) in the BASIC Stamp's EEPROM (Electronically Erasable Programmable Read Only Memory). Typically, the EEPROM is used to store (constant) data that rarely changes due to the finite life expectancy of the EEPROM.

    I would probably take a look at the WRITE command in the BASIC Stamp Editor's Help file in order to store a variable's value in the BASIC Stamp's EEPROM.

    My question is, what are you trying to do by storing text that needs to be in front of and after a variable?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "I learn when I succeed, but I learn more when I fail."

    Alan Balich

    SX/C Wiki - sxcwiki.alanbalich.com
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-12-10 21:18
    I think I see what you’re trying to do…and what I would do is replace ‘dollar’ with a 0 byte and terminate your entire data statement with a 0 byte, such as:

    DATA "Cost is $", $00, ".00", $00

    Then your display routine can read characters from the data statement until the 0 byte is reached at which time it will display the value then continue reading the data statement from the last index until it reaches the next 0 byte, terminating.

    I hope this helps. Take care.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-12-10 21:38
    Backing up just a little, what you're trying to accomplish with the DATA statements is advantgeous only if the string needs to be used in more than one place in your program or if you're using something other than the built-in output statements (SEROUT, LCDOUT, etc.) to display the data. If neither of these conditions applies, it's easier and less memory-intensive just to include everything in the output arguments, viz:

    SEROUT, iopin, baud, [noparse][[/noparse]"COST is $", DEC cost, ".00"]
    
    
    


    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-12-10 23:16
    Phil,
    I don't agree that including everything in the output arguments is necessarily less memory intensive. Each character stored as an output argument occupies 14 bits, whereas in a data statement the same character occupies only 8 bits. The break even point comes at only about a 15 byte string...
    eestr1  DATA "The cost of a shoestring is ",0
    adrs=eestr1
    DO
      READ adrs,char
      DEBUG char
      adrs=adrs+1
    LOOP WHILE char
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-12-10 23:51
    hmlittle,

    For output of strings to the EMIC speech syth, I've used tags embedded in the fixed eeprom data. For example hex $95 embedded in the speech string would stop the direct output of the characters and instead branch to a routine that points to wordVariable(1) and outputs that to the EMIC using format number 5. In this situation, bit7=1 will not otherwise occur in the speech string, so that is what flags a control byte. There are thus 8 possible variables and 16 possible formats that can be embedded in the speech string to be played back, using the fixed data plus the current values of the variables at run time. It of course takes a playback subroutine to fetch the eeprom strings.

    eestr1  DATA "The cost of a shoestring is $80 dollars",0    ' $80 is embedded flag, not cost!!!
    adrs=eestr1
    cost = 2  ' 2 dollars
    DO
      READ adrs,char
      IF char.bit7 THEN GOSUB variableOut
      DEBUG char
      adrs=adrs+1
    LOOP WHILE char
    END
    
    variableOut
      DEBUG DEC cost,CR
    return
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-12-11 02:49
    Tracy,

    You're right about the space required by embedded output lists. Wow! It's a bit of a shock, really, since other PBASIC tokens are stored so efficiently. (So much for logical assumptions!) There must be a command token associated with each character.

    Anyway, I think I'd assign a higher number to the break-even point, if you want to compare apples with apples. Here are two programs that do the same thing in two different ways. First, the way I suggested (84 bytes):

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    io    CON 16
    baud  CON 84
    
    vars  VAR Word(3)
    
    vars(1) = 99
    
    SEROUT io, baud, [noparse][[/noparse]"The price of popcorn is $", DEC vars(1), ".00 a barrel.", CR]
    END
    
    
    


    Second, a more generic version of your program (112 bytes, including 40 bytes of DATA):

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    io    CON 16
    baud  CON 84
    
    vars  VAR Word(3)
    addr  VAR Word
    char  VAR Byte
    
    msg1 DATA "The price of popcorn is $", $81 , ".00 a barrel.", CR, 0
    
    addr = msg1
    vars(1) = 99
    GOSUB Print
    END
    
    Print:
      DO
        READ addr, char
        IF (char & $80) THEN
          SEROUT io, baud, [noparse][[/noparse]DEC vars(char & $7f)]
        ELSEIF (char) THEN
          SEROUT io, baud, [noparse][[/noparse]char]
        ELSE
          EXIT
        ENDIF
        addr = addr + 1
      LOOP
      RETURN
    
    
    


    By my calculations, this puts the break-even closer to a string of 77 characters, which still isn't all that much.

    I do like your idea of embedding tags in the string to signify variables. I only wish PBASIC were a little more expressive when it comes to aliasing and pointers, so a program like this could be made more readable. But that's for another thread. (Oh, right. 'Been there, already. wink.gif )

    -Phil
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-11 03:01
    The big advantage of the second scheme is when you're using a BS2p/pe/px with the multiple slots and STORE statement which simplifies moving the messages to other slots where the space they occupy doesn't affect your program in slot 0.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-12-11 18:12
    I was thinking of a less ambitious program to compare apples to oranges. The breakeven point comes at around 45 characters in the following comparison. With the DEFINE verbose=1, the single DEBUG with argument list takes 68 bytes of program memory + 0 data. With verbose=0, the program loop method takes 25 program bytes + 45 data, total 70.

    ' {$STAMP BS2pe}
    ' {$PBASIC 2.5}
    #DEFINE verbose=1
    #IF verbose #THEN
    
    DEBUG "The quick brown fox jumps over the lazy dog."
    END
    
    #ELSE
    
    adrs VAR byte
    char VAR Byte
    DATA "The quick brown fox jumps over the lazy dog.",0
    DO
      READ adrs,char
      DEBUG char
      adrs=adrs+1
    LOOP WHILE char
    END
    
    #ENDIF
    



    You are right about there being a command token associated with each byte, a "push literal" onto the expression stack. Other tokens are associated with various modifiers. The SEROUT command once set up reinvokes the interpreter to peel tokens and data off onto the expression stack an element at a time, and the the SEROUT then sends the characters it finds on the expression stack.

    Fourteen bits per literal character is an average. It varies from 9 to 16 bits depending on the ascii value, and low ascii codes take less. The way the literal push token works, it can be more efficient for smaller values. Binary-valued codes like 32=space are a special case and all take 9 bits. The same mechanism is used any time there is an argument list of indeterminate length.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-12-11 18:35
    Tracy,

    I'm a bit confused by your description of how SEROUT uses the stack. Given the hardware involved (a small PIC for the BS2), there's not enough RAM to stack a string of any ponderable length to be peeled off for output later. Does the compiler chunk the output string into shorter segments? It must also have to stack things in reverse order so they come off in the correct order.

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-12-11 19:01
    It doesn't need much RAM because it only chews off one element at a time, not the entire list. For example, the SEROUT would set up the baud rate and pin etc, and then back to the interpreter to push literal "T" onto the expression stack, and control passes back to SEROUT to send the "T", and then back to the interpreter to push literal "h", and then back to SEROUT to send the "h" and so on. If the interpreter encounters say a DEC modifier instead of a push literal, then it has to do a different kind of work to translate the selected variable into characters on the expression stack. It is possible to get an "expression too complex" but I have hardly ever run into that. A double zero bit, 00, when in the position of a token, is the list and command terminator.

    All this is covered in fascinating detail in Brian Forbes' book.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-12-11 19:16
    Tracy,

    Ah so. I've ordered the book on your recommendation. Thanks for the pointer! Now, somebody needs to write one for the BS2p series!

    -Phil
  • hmlittle59hmlittle59 Posts: 404
    edited 2007-12-11 20:53
    Hello Everyone

    All my other request combined never generate this kind of help. Thanks a bunch. I'm using the code like Phil's,
    (SEROUT, iopin, baud, [noparse][[/noparse]"COST is $", DEC cost, ".00"]) showed. I needed the shorts code possible for my Main Menu. I've rewritten this code so much to get the size down I hardly recognize it. I have 9 byte free and all seems to be working GREAT. Thanks Again.

    I'm using " PCB Artist " to layout my board and I don't have a clue what i'm doing. I've put most of the components on the screen and now have to connect them. I have two Proto Boards from Parallax and with help from Mike I gotten started there but it's been slow. With the software part done, maybe i can focus more on the next two phases. Getting it from paper to CAD has been even more of a challenge.

    1) Has anyone used this Software before?
    2) Are there any Public Domain files for the BS2 Micro's that I can just import in?
    3) Any advise for some who just doesn't have a cluse


    Thanks for any help
    hmlittle59
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-12-12 05:45
    Phil, good choice. I think you will really enjoy that book. There are lots of good insights between the lines for writing efficient PBASIC code. Have you also read the stuff by Chuck McMannis on the BS1? I think Brian used that as his starting point. It would not be much of a stretch to continue and extend it to the BS2p series. Just a few more commands. Multibank commands, RUN, STORE, GET, PUT, IOTERM, AUXIO and MAINIO won't hold any big surprises. Ones like I2Cxxx and LCDxxx are almost certainly the same as SEROUT in the way that they parse the argument lists.

    When I was working in the original BS2, I was constantly up against the out of memory condition or vanishing free space, and had to go back to pruning and shaving here and there. The text prompts went into DATA statements and became super-abbreviated. Time delays where possible became say 1024 instead of 1000, just to save a few bits. Condition statements cut to the bone. Math statements condensed to the point of incomprehensibility. Now the BS2pe is a luxury--all that space! But of course nature abhors a vacuum.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-12-12 06:55
    Tracy,

    No, I haven't read McMannis, nor have I ever used the BS1. It's probably because the BS2 came along before I'd ever paid the BASIC Stamp line much attention. But the BS2 and BS2p series have become classics in their own right and — in my mind at least — retain durable standing against even the Propeller's siren song of power and capacity. Perhaps that's just my inherent minimalism talking. In any event, I truly believe the Stamps have ample staying power to justify further enhancements to their dev tools, thereby unlocking even greater ease of use. Given Forbes' book and the twin luxuries of time and treasure, I suppose one could dive in and do that job himself. I'm one for three — or will be once the book arrives! smile.gif

    -Phil
Sign In or Register to comment.