Shop OBEX P1 Docs P2 Docs Learn Events
EEPROM Full — Parallax Forums

EEPROM Full

Robot JayRobot Jay Posts: 12
edited 2006-05-29 04:31 in BASIC Stamp
I wrote a program for my BS2 to controll a bipedal robot.· After a certain amount of coding, the BASIC Editor told·me that the EEPROM was full (understandably, because the program I have written is very large.)· So I took my·BS2 stamp out of the BOE and put in my BS2px24 stamp assuming (because of the specs that came with my BS2px) that the BS2px would have a larger EEPROM size.· I downloaded the BASIC Editor v2.2.5, and load and run the program I wrote for the BS2 (changing the ' {$STAMP BS2} line to ' {$STAMP BS2px}).· I run the program and get the same EEPROM Full error.· I have not actually changed the size of the program between the two stamp versions.· Why is this happening?· As far as I can tell, the stamp is not damaged and is being read correctly,· it's just seems that the editor is not reading the correct EPROM size.· Any help will be appreciated.· Thanks!

Comments

  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-05-27 22:35
    The Stamp Editor is reading your stamp correctly...The problem is not with the module, but the fact that a program cannot be any larger than 2K on any Stamp Model.· Your BS2px has·eight 2K slots, compared to the BS2 having only a single 2K slot.· What you need to do is break your program up into modules that cab be chained across slots.· The following Nuts & Volts article should help you out some.· If you still have questions after reading that then reply back here.

    http://www.parallax.com/dl/docs/cols/nv/vol3/col/nv87.pdf


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Robot JayRobot Jay Posts: 12
    edited 2006-05-27 22:57
    Thanks again for the help, Chris.· You're a BASIC Stamp pimp, and I love you for it.· I looked over the article you recommended, and I think I can fix my problem now.
  • T ChapT Chap Posts: 4,217
    edited 2006-05-28 18:46
    Chris

    I just ran into the same issue with maxing out a bs2p40. Is there a simpler way to understand how to take what I have done to this point, without starting over and using the extra ram? I read the article but don't see how to apply it to my existing situation, since it was not planned. I can't runb what I have now, its over by maybe 20 lines which maybe can be reduced back to where it will fit, but there is a long way to go still.

    I do not want to start over hopefully.

    Thanks
  • T ChapT Chap Posts: 4,217
    edited 2006-05-28 19:26
    Well after reading everything that will turn up after searching:

    I backtracked and converted a byte to a nib, and also noticed that I am using a LOT of the following code throughout the prog which is eating up some memory, so the obvious solutionhere is For Next and count to number and move on... right?

    a short of example I am using in a lot of places to blink an led

    LOCK_LATCH_M = 1
    PAUSE 100
    LOCK_LATCH_M = 0
    PAUSE 100
    LOCK_LATCH_M = 1
    PAUSE 100
    LOCK_LATCH_M = 0


    After replacing these with For Next, assuming thatthat is the most pratical conservation method to do the task, what about vaiable name lengths? Does that add to the waste as well? or what about ' comments?
  • SSteveSSteve Posts: 808
    edited 2006-05-28 20:00
    Variable name length and comments do not increase your program size, so don't skimp there. Converting bytes to nibs won't change your program size either, it will just decrease your variable space usage. But that's a good habit nonetheless.

    If you want help decreasing your program's size, it's probably best to attach your entire program. (Be sure to attach it and not just copy it into your message.)

    Any time you see the same code duplicated repeatedly in your program, it's a sure sign that you should make a subroutine.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2006-05-28 20:23
    Variable name lengths and comments have nothing to do with program size.

    If your program has user interaction, pay special attention to prompts and text, in statements like,
    DEBUG "Please enter the time for lock to latch"
    If there is much text like that, you are better off with a short subroutine that reads it out of the DATA eeprom. It takes up a lot more space when it is encoded as part of the command. Also, if it is in DATA statements, you can put it in a different bank and reference it with STORE, READ and WRITE, and free up space in the program bank.

    Initialization routines can often go in one bank, and then shift into another bank for the main running program. And a a third bank can hold the user configuration routines. It all depends on the application of course, and it does take some planning. But you can make the bank structure work for you.

    There are some small ways to save space too. For example, PAUSE 128 will take less eeprom space than PAUSE 100. The Stamp stores the powers of 2 in a particularly efficient manner. It saves ust a few bits, but with the original Stamp I was often in the situation of shaving bit by bit, like a serious backpacker saves fractions of an ounce.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • T ChapT Chap Posts: 4,217
    edited 2006-05-28 21:25
    Ok it is getting somewhat clearer as far as optimization, so thanks for the tips. Where I am still lost is in storing and reading a program. Since you can only load in one program at a time with a limit of 2 k per program, are you loading in one program and writing it to the eeprom, then loading in another and writing it to another area of the eeprom, then writing a third program that calls each program as needed? IN taht case woulnt each program have to "exit" as needed to get to the next program need? The fundamentals weren't clear in the link that has been referenced regarding the temperature example.

    I am trying to find some example of how I would take the 2k program I have now, and add to it so that it all still functions somehow as a whole, simlutaneously. If programs are having to load in and out to maintain real time monitoring of buttons and sensors, while simultaneously maintaining leds for status etc, it does not seem possble that I can simply park the first half of the program and shift it back and forth fast enough to function as needed.
  • T ChapT Chap Posts: 4,217
    edited 2006-05-28 21:33
    Here is what I have so far. There are a lot of duplicate sections that scan for a "slave" panel that has the same i/o's, but instead of OR-ing the inputs together, I wanted to maintain complete control. So there is for example OM for "open master", and OS for "open slave" that has code that is identical except fot the button names. This will likely be where I have to start shaving. It will require a lot more conditions per section to account for both master and slave together. Since this is my first ever basic attempt, I wrote it thinking I had 4000 lines of instructions to play with. Somehow I got it very wrong and ran out way before I was done.
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2006-05-28 23:04
    You have up to 8 programs loaded simultaneously in the eeprom, and in the editor they will appear in 8 separate tabs linked by the directive,
    '{$STAMP BS2P, file1.bsp, file2.bsp, ...}
    Be sure to read up on this in the manual, under editor: advanced compilation. When you complle a program linked in that way, all of the banks are downloaded to your Stamp at one swoop.

    When your program needs to jump from one bank to another, use the RUN N command, where N is 0,..,7. Similarly, to access data stored in different banks, use the STORE N command. Look up those in the manual, too. All the banks share the variables, both RAM and SPRAM, but you have to be sure they are declared in the same order in all the banks that will affect them. Some routines (for user configuration, for example, or for simple data storage) are natural candidates for separate banks. There is no automatic way to jump from a bank to a "subroutine" in another bank, but there are workarounds, essentially by managing your own go and return vectors. The article referenced goes into that. Also, this page (although dated) might have some material of interest:
    www.emesys.com/BS2SX.htm

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • T ChapT Chap Posts: 4,217
    edited 2006-05-29 00:34
    Thanks again Tracy, you have really helped out a lot. My assumption was way off, you CAN run a programs back to back from slot 0 to slot 1 and lose no functionality for buttons etc, at least on the small scale I am do it at. I discovered the "project" button on the OS X MacBS2, made a test program for slot 2 and downloaded the both. Couldnt be easier so far.

    I guess the next test is to see if any variables stated in slot 0 are still in tact in slot 1. If not then I suppose the obvious answer is copy and paste from the first programif in fact the same i/o and var are required in program2. This is just as simple as GOTO, except it is called RUN 1, RUN 2 etc.

    More testing to do, but thanks!
  • SSteveSSteve Posts: 808
    edited 2006-05-29 02:38
    If you're still looking at places to trim bytes, here's an example.

    Original code:
    'CHECK A POS
    
    CHECK_A_POS_M:                        'TOGGLE A  O/C
    MAINIO
    IF OM = 0 THEN CHECK_A_POS_M_DONE
    IF (OM = 1) AND (A_POS = 0) THEN SET_A_1
    IF (OM = 1) AND (A_POS = 1) THEN SET_A_0
    
    'CHECK A POSITION  
    
    CHECK_A_POS_M_DONE:
    RETURN
    
    MAINIO
    SET_A_1:
    A_POS = 1        'TOGGLE A_pos TO 1
    mtrin = %0001    'sets 0001
    STP = 0
    PAUSE 100
    STP = 1
    PAUSE 100
    IF pfin = 0 THEN WAIT_pfin
    strt = 1
    PAUSE 200
    strt = 0
    
    IF OM = 1 THEN HOLD_FOR_A_POS_RELEASE
    RETURN
    MAINIO
    SET_A_0:
    A_POS = 0        'TOGGLE A_pos TO 0
    mtrin = %0000
    STP = 0
    PAUSE 100
    STP = 1
    PAUSE 100
    IF pfin = 0 THEN WAIT_pfin
    strt = 1
    PAUSE 200
    STRT = 0
    IF OM = 1 THEN HOLD_FOR_A_POS_RELEASE
    IF OS = 1 THEN HOLD_FOR_A_POS_RELEASE
    RETURN
    
    HOLD_FOR_A_POS_RELEASE:
    IF OM = 1 THEN HOLD_FOR_A_POS_RELEASE
    IF OS = 1 THEN HOLD_FOR_A_POS_RELEASE
    RETURN
    
    



    Trimmed version:
    'CHECK A POS
    
    CHECK_A_POS_M:                        'TOGGLE A  O/C
        MAINIO
        IF OM = 1 THEN 
            IF (A_POS = 0) THEN
                A_POS = 1
                mtrin = %0001
            ELSE                            'A_POS = 1
                A_POS = 0
                mtrin = %0000
            ENDIF
            STP = 0
            PAUSE 100
            STP = 1
            PAUSE 100
            IF pfin = 0 THEN WAIT_pfin
            strt = 1
            PAUSE 200
            strt = 0
    HOLD_FOR_A_POS_RELEASE:
            IF (OM = 1) OR ((A_POS = 0) AND (OS = 1)) THEN HOLD_FOR_A_POS_RELEASE
        ENDIF
    RETURN
    
    



    You really should use indentation in your code. It doesn't add to the program size and it makes it much easier to read. To indent multiple lines in MacBS2, highlight the lines and press Cmd+].

    My version eliminates redundant tests (e.g. you don't need to test for "OM = 1" on one line and "OM = 0" on the next). It also eliminates the duplicated code in SET_A_0 and SET_A_1.

    I noticed that the call to Wait_Pfin falls through into CHECK_LEFT_M which then returns to the main program loop. It never gets back to CHECK_A_POS_M. Is that intentional?

    Here's another example:
    CHECK_LEFT_M:
    MAINIO
    IF lm = 0 THEN check_lm_done
    IF lm = 1 THEN 
    mtrin = %0010
    PAUSE 100
    strt = 1
    PAUSE 200
    strt = 0
    ENDIF
    
    
    HOLD_FOR_LM_RELEASE:
    MAINIO
    IF lm = 1 THEN HOLD_FOR_LM_RELEASE
    IF lm = 0 THEN
    stp = 0
    PAUSE 100
    stp = 1
    mtrin = %0000
    ENDIF
    
    check_lm_done:
    RETURN
    
    



    modified:
    CHECK_LEFT_M:
        MAINIO
        IF lm = 1 THEN 
            mtrin = %0010
            PAUSE 100
            strt = 1
            PAUSE 200
            strt = 0                
    HOLD_FOR_LM_RELEASE:
            IF lm = 1 THEN HOLD_FOR_LM_RELEASE
            stp = 0
            PAUSE 100
            stp = 1
            mtrin = %0000
        ENDIF
    RETURN
    
    



    The first "IF lm = 0" was unnecessary. You only need to enclose the whole routine in the "IF lm = 1" test. The second "IF lm = 0" was unnecessary because the previous line had tested for lm = 1.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • T ChapT Chap Posts: 4,217
    edited 2006-05-29 02:55
    Ssteve you are right, I missed that RETURN or go to main actually since it is just as well to start over after a move from the top. I really like the edits, I'll stufy it and apply it right now. This is all simple stuff, but rather overwhelming for the first Basic attempt.

    Fortunately I learned a little about the Run 0, Run 1 etc. I am now thinking of cleaner faster ways to run my code now that it is pretty simple just to copy your setup over, and keep adding conditions. What I am thinking is to make Program one be just the If condition page for speed, then, have another program with all the work code. Question is, I doubt it would be easy to for exmple Run 1 Check_A_Position_M. I am guessng it would have to reask all the questions again which wouldn't be bad, but a nicer way would be to go straight to the appropriate label in slot 1(based on conditions) from slot 0 and strat working, rather than scanning for conditions from scratch.

    Idon't sdee a methodf yet though.

    Thank a lot for the schooling
  • SSteveSSteve Posts: 808
    edited 2006-05-29 04:10
    Since all the program slots share the same variable space, you can use a variable as a flag between programs and jump to a subroutine based on that flag. For example program 0 could scan for all the conditions then set a value in the variable flag to indicate the action to take then perform RUN 1. The first line in the program in slot 1 would be something like this:

    ON flag GOTO SUB1, SUB2, SUB3, SUB4 ' Perform appropriate action

    Beware of a common stumbling block when sharing variables between programs. You have to have your variables declared exactly the same in every program. It's best to define all your variables in one location in program 0 and then copy that code to all your other programs.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • T ChapT Chap Posts: 4,217
    edited 2006-05-29 04:24
    VERY COOL! will try it now. Thanks

    I haven't seen ON command, so I assume you are illustrating:

    if flag = x then sub1

    or to use the flag for more than two options:

    if flag = %1111 goto sub3
  • SSteveSSteve Posts: 808
    edited 2006-05-29 04:27
    The ON command is on page 277 of the BASIC stamp syntax manual v2.1. For some reason it's not in the drop-down combo box in the MacBS2 help file.

    Edit: It is in the MacBS2 help file, just not in the drop-down index. Select "OUTPUT" and then scroll up a few pages.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows
  • T ChapT Chap Posts: 4,217
    edited 2006-05-29 04:31
    Aha got it That's the only place I looked was in the help!
Sign In or Register to comment.