Shop OBEX P1 Docs P2 Docs Learn Events
program help — Parallax Forums

program help

rrrr Posts: 63
edited 2006-04-10 18:01 in BASIC Stamp
Hello
·
I am working on a program for an art installation and I need some help with the code.
I am using the OSD video mod to display words on a tv. ·When a viewer activates a button, I want to display a random sequence of words. And when the viewer deactivates the button I want the program to start over.
·
I want to be able to flash random words on the screen. The problem is that I would like the word list to contain at least a hundred words. Is there a better way to do this other than the way done in the attached file? I am also aware that the way I am doing it wont allow a big word set because of program space.
·
Please help…
·
Thanks for your time…
rr
«1

Comments

  • Lee HarkerLee Harker Posts: 104
    edited 2006-04-06 13:46
    rr,
    A couple things cone to mind when looking at your program.
    One is that you don't have to make a seperate routine for each different word. You can store all the words in EEPROM and access them as needed. If you need more memory space, you can add a serial EEPROM for that.
    Another thing you will need to do, it to control the size of your random number. The random number you generate will have to match the number of words you have in memory.
    One thing you didn't mention is whether you wanted the program to display any random word from the list or if you wanted to make sure each activation should pick a unique word from the list with no repeats.
    When you look through a program and see a few lines of code that are repeated almost identically more than a couple times, that's usually a sign that there is an easier and more efficient way to do it. I know my carpel tunnel alarm goes off whenever I see that wink.gif

    Lee
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-06 14:24
    rr,

    ·· Adding to what Lee said, you don't want to have a subroutine for each word since that will cause the program code to grow·fast due to all the branch testing you use.· Even if you use ON...GOTO your list would be extremely long and may not fir on one line.

    ·· Now, if you store the words in DATA statements, you can use the RANDOM value you're choosing to indicate the offset address to get the word from.· As for a hundred different words fitting into the EEPROM with your code, you'd need to know how many total characters were in all 100 words, adding one character each for the 0 termination.· That would give you a better idea.

    ·· If you don't have the room on a BS2 you have two choices.· One is to hang an external EEPROM onto the BS2 and store your words there.· Your second choice is to get a BS2pe or similar which can store more DATA in additional slots.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-06 15:01
    rr,

    ·· Here is an example of printing random words from a list where all the words are the same length.· I did some funny stuff to help with the RANDOM command, but in your situation the value would seem more RANDOM since you're having a user push a button.· This will change the values you see each time.· Anyway, it's just an example of one way of doing this.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • rrrr Posts: 63
    edited 2006-04-06 16:30
    thanks for the help...

    why is this only good for the same size word, and is there a way to do this with different size words.
    also would this work for more than 16 words


    i am really new to programing so if you could put a couple comment lines in the program to tell me what the code is doing that would help a lot...

    thank you for your time.
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-06 16:34
    rr,

    ·· The program I posted could work with as many words as I could fit into the BS2 memory without really changing much of the program at all (mainly just adjusting variable sizes).· The reason for the constant word length is to calculate their position in the memory map.· For words of different lengths you would need a 0 termination between each word, and you would need to find the word in the list each pass since you wouldn't know it's address.·

    ·· Now, if you had the external EEPROM, you could build an address map in the BS2 EEPROM and then you could easily lookup the words again based on that information.· Or, if you had a BS2e or higher something similar could be done using slot1 to store the names, and slot0 would have an address map for them.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-06 22:10
    Chris:

    I'm trying to figure out how to get SEROUT to access the EEPROM data. Would this work?

    addr1    DATA    "Word 1", 0
    addr2    DATA    "Another word", 0
    ...
    addr16    DATA    "Tree", 0
    
    DO
      RANDOM address
      index = address.LOWNIB
      LOOKUP index, [noparse][[/noparse]addr1, addr2, ... addr16], wordStart
      SEROUT pinOut, baud, [noparse][[/noparse]STR wordStart]
      PAUSE 1000
    LOOP
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-06 22:15
    Steve,

    ·· Several changes would need to be made to do what you want to do.· For starters you could just LOOKUP the word like that because it's not at a fixed offset address.· For that many words you would literally need to search for the start of the word by finding the previous 0.· As for your output you've never loaded the variable array wordstart with any data to use that function.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-06 22:42
    Hi, Chris:
    Chris said...
    For starters you could just LOOKUP the word like that because it's not at a fixed offset address.

    That doesn't quite parse. Did you mean couldn't? Either way, I'm not sure I follow. LOOKUP is using the index variable to look for the starting address of the word. The starting addresses of the words are defined by the labels in front of the DATA statements.
    Chris said...
    As for your output you've never loaded the variable array wordstart with any data to use that function.

    The wordStart variable is being loaded by the LOOKUP command.

    I know the general logic of the program works. I've attached the running code. My real question is whether or not the syntax of my SEROUT command would work. (I'm not currently set up to test serial communications.)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-06 23:37
    Steve, I suppose if you put labels in front of all the words in the DATA statements then you could do that.· Yes I did mean couldn't, however I don't know if you could put that many entries in the LOOKUP list.· You could try.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-07 06:34
    But that would be the correct syntax for SEROUT? i.e. having the address of the first character in wordStart:

    SEROUT·pinOut,·baud,·[noparse][[/noparse]STR·wordStart]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Tom WalkerTom Walker Posts: 509
    edited 2006-04-07 12:49
    SSteve,
    PBASIC has no native ability to SEROUT strings. You would have to build a routine to SEROUT each character individually, looking for the null terminator. Is this the question you were asking?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...

    Post Edited (Tom Walker) : 4/7/2006 12:54:04 PM GMT
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-04-07 13:11
    Yes, PBasic does have 'native' ability to SEROUT strings. True, they call them an array of bytes, but that's not a show-stopper.

    So, if you have an array of bytes, and the location following the last string byte is a zero byte, then yes,

    SEROUT SerPin, SerBaud, [noparse][[/noparse]STR wordstart, 13] should output the string. Note that '13' there is kind of important, that tells any recieving program that the string is complete.
  • Tom WalkerTom Walker Posts: 509
    edited 2006-04-07 13:23
    alanlane5,
    Would you believe that I've been "looping through" strings since I started with the Stamp years ago? D'oh!!! Sometimes you get so complacent while jumping from project to project (hardware to hardware, language to language, system to system) that you turn off the "research bit"...thanks for the enlightenment...time for more research.

    SSteve,
    I withdraw my previous statement, and apologize for any confusion.

    ...wanders off, mumbling to himself...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...

    Post Edited (Tom Walker) : 4/7/2006 3:26:26 PM GMT
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-07 14:14
    Tom,

    ·· Even so, you are still correct in that since the DATA is coming from DATA statements, it would still have to be read one character at a time, and sent out one character at a time.· The only way to use the STR function would be to preload the array, but that would still have to be done one character at a time.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Tom WalkerTom Walker Posts: 509
    edited 2006-04-07 15:24
    I KNEW there was a reason I saw doing it that way....just testing [noparse]:)[/noparse]

    Thanks for saving some of my dignity...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-07 16:05
    Tom,

    ·· No problem...The bottom line is that the information will have to be read from the DATA statements one character at a time, regardless of how it's handled elsewhere in the program.

    Steve,

    ·· While I am not ever inclined to do anyone's work for them (you don't learn that way), I am willing to come up with something you can customize.· But you will need to enter all the DATA stements into the code and post it.· I will write a core routine that picks random words from that list and sends them out serially.

    ·· Please be specific on the way the program is supposed to work, including if the button the user presses is active high or active low.· How many words get sent, etc.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-07 17:05
    Hi, Chris:

    Thanks for the offer, but you don't need to write a program for me. I agree that doing is a better way to learn. I'm trying to clarify the SEROUT syntax.
    Chris Savage said...
    since the DATA is coming from DATA statements, it would still have to be read one character at a time, and sent out one character at a time.
    So if the variable "theAddress" contained the address of a zero-terminated string in a DATA statement, would this be the correct way to use SEROUT? (I tested this code and I see the words in the DEBUG terminal, but I don't currently have a way to test SEROUT.)
      READ theAddress, outChar
      DO UNTIL (outChar = 0)
        SEROUT pinOut, baud, [noparse][[/noparse]outChar]
        DEBUG outChar
        theAddress = theAddress + 1
        READ theAddress, outChar
      LOOP
      SEROUT PINOut, baud, [noparse][[/noparse]13]
      DEBUG CR
    
    


    Thanks for your patience.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-07 19:57
    Steve,

    ·· At a glance that looks correct.· That is assuming you've already identified the beginning (start address) of the word you want to send, which will be different than you originally thought considering words of different lengths, zero-terminated.· Good luck.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Paul Sr.Paul Sr. Posts: 435
    edited 2006-04-07 20:58
    Chris Savage (Parallax) said...
    Steve,


    At a glance that looks correct. That is assuming you've already identified the beginning (start address) of the word you want to send, which will be different than you originally thought considering words of different lengths, zero-terminated. Good luck.


    In other words, randomizing the selection of words will be a bear - correct assumption? If so, I would propose using fixed length words (padding all words with spaces to the length of longest word). Random selection could then be driven by a straightforward randomly generated index into the "word stack" - no parser (don't have to keep track of 0's or commas...) for example.

    Make sense?

    Paul
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-07 23:36
    Well, it won't be a bear, necessarily, but as I said, it won't be as straight-forward as the fixed-length message method, that's for sure!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-08 01:30
    rr:

    Here's a program that will print a random word out of a list of 100 variable length, zero-terminated words stored in the stamp's EEPROM. I can't test the SEROUT statement, but the correct output shows up in the debug window.

    -Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • SSteveSSteve Posts: 808
    edited 2006-04-08 01:38
    And while I'm at it, here's a C program that will read a list of whitespace-delimited words from stdin and write the appropriate DATA statements to stdout.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
    c
    c
    420B
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-08 03:26
    Steve,

    ·· That is a similar approach to what I was thinking, except that to save code-space I was going to have a DATA lookup table.· But hey, it works, right.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-08 03:50
    Do you mean like this?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-08 04:16
    Steve,

    ·· Very good, you saved 2% of the EEPROM space and learn/shared a valuable lesson with your peers.· Congratulations!· =)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-08 04:32
    I increased efficiency by 2%?!? Geordi would be proud. smile.gif

    P.S. am I a geek for writing a C program to generate repetitive code?
    main()
    {
        int i, j, addr;
        
        addr=0;
        printf("addresses");
        for (i=0; i<20; i++) {
            printf("\t\tDATA\t");
            for (j=0; j<5; j++) {
                if (j != 4) {
                    printf("WORD addr%d, ", ++addr);
                } else {
                    printf("WORD addr%d\n", ++addr);
                }
            }
        }
    }
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-08 05:01
    Geordi would be most pleased indeed!· I wonder what Dr. Leah Brahms would think?· The real one, not the hologram.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • rrrr Posts: 63
    edited 2006-04-10 02:30
    thanks for all the help.

    i came up with a program using Chris's sample program.

    it works well for my needs but i am sure it could be more efficiant.
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-04-10 05:39
    rr,

    ·· Functionality first, efficiency later.· Of course, to some degree you want to work on both while writing, but if you worry too much about one then you may have trouble with the other until you're more experienced.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-04-10 18:01
    rr said...
    it works well for my needs but i am sure it could be more efficiant
    You can remove the "GOTO choice" line since "choice" is the next line in the program. Same with "IF IN14 = 0 THEN over".

    You can change the list of IF/THEN statements to "ON address // 7 GOTO pick8, pick7, pick6, pick5, pick4, pick3, pick2"

    Any time you see code repeated as in your various "pick" routines, that's a good sign that you should make a subroutine. You could change your "pick" routines to something like this:

    pick8:
        xPos = 7  ' The horizontal position of the word on the display
        WordLength = 8  ' Number of characters in the word
        startAddress = wor8  ' Address where words of this length begin
    GOTO Show_Word
    
    


    This routine displays the words:
    Show_Word:
      SEROUT sout, baud, [noparse][[/noparse]CRSRXY,xPos,6]
      RANDOM address
      index = address.LOWNIB
      FOR charOffset = index * WordLength TO index * WordLength + (WordLength - 1)
        READ startAddress + charOffset, ioByte
        SEROUT Sout,baud, [noparse][[/noparse]iobyte]
      NEXT
    
      PAUSE 400
      SEROUT Sout, baud, [noparse][[/noparse]CLS]
    
      GOTO choice
    



    Here are the variable definitions:
    index            VAR    NIB
    ioByte        VAR    BYTE
    xpos            VAR    NIB
    wordLength        VAR    NIB
    startAddress    VAR    WORD
    charOffset        VAR    BYTE
    
    



    I haven't tested the code, but it should give you an idea of where to go.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
Sign In or Register to comment.