Shop OBEX P1 Docs P2 Docs Learn Events
BS2E Internal EEPROM DataLogging — Parallax Forums

BS2E Internal EEPROM DataLogging

skynuggetskynugget Posts: 172
edited 2008-11-20 22:37 in BASIC Stamp
hey all, I've come across a lot of post about this, but i cant seem to pull it together in my head, so I'm sorry if I'm beating a dead horse with this.

I would like to store a couple values in program bank 7 of my bs2e. its basically a "timestamp" consisting of:

day byte
month byte
year byte
hour byte
min byte
sec byte
value byte

so basically i want to write 3 words and a byte to the eeprom bank till the eeprom fills up then start over, then read it back for display on an lcd.


if anyone has a good post/article/snippet i would really appreciate it.

thanks in advance!

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-30 17:17
    Have you read the Stamp Basic Manual's chapters on the READ / WRITE / STORE / DATA statements?
  • skynuggetskynugget Posts: 172
    edited 2008-10-30 17:25
    thanks mike, i have many times, but this time i finally registered the part where the b2e can only write to the program slot its is currently running, Which sends me back to the drawing board....

    i guess i could pass the values through scratchpad to a routine in slot 7 that writes to its eeprom?
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2008-10-30 17:31
    skynugget -

    Take a look at this application information supplied by Dr. Tracy Allen on his web site:
    http://www.emesystems.com/BS2pe.htm


    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When all else fails, try inserting a new battery.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-30 17:33
    You can also share variables between programs in different slots. Read the chapter on the RUN statement for details. What you're proposing (a short program in each slot to be used for logging) is the usual solution on the BS2e and BS2sx which don't have the STORE statement.

    There's a Nuts and Volts Column on multi-slot programming. I don't remember which issue, but it should be easy to find on Parallax's Nuts and Volts Columns index.
  • skynuggetskynugget Posts: 172
    edited 2008-10-30 17:41
    thanks bruce, ill take a look at it.

    thanks again mike, you are correct... the article you are thinking of is nv87 on multislot programming. ive got my head wrapped around its contents, this is my first multislot program, couldnt have gotten this far without it [noparse]:)[/noparse] (thanks jon!)

    is anyone aware of some examples of "the usual solution" work around for a lack of the store command?

    Post Edited (skynugget) : 10/31/2008 12:59:24 AM GMT
  • skynuggetskynugget Posts: 172
    edited 2008-10-30 18:14
    looks like dr allen did all of the work for us again...
    www.emesystems.com/BS2SX.htm#datalogger

    hopefully i can wrap my head around it, thanks for the nudge bruce, and thanks for the page tracy!
  • skynuggetskynugget Posts: 172
    edited 2008-11-11 02:38
    hey all heres what i have so far:
    ' {$STAMP BS2e}
    ' {$PBASIC 2.5}
    
    
    MaxAdr        CON       1900       ' number of log locations in bank leaves 148 bytes
    logfile       DATA      (MaxAdr) ' reserves bytes for the logfile
    
    
    EEadr         VAR      Word       ' address for memory write and read
    task          VAR      Nib       ' where to go for branch
    idx           VAR      Nib          ' counter
    timestamp     VAR      Byte(6)   ' timestamp byte array - hrs,mins,secs,mths,date,yr,tagnum
    
    
    Init:
      FOR idx = 0 TO 5              ' get array values from spram
        GET 8 + idx, timestamp(idx)
      NEXT
    
      GET 1, task    ' what to do??
      BRANCH task, [noparse][[/noparse]Read_EE, Write_EE]
      RUN 0
    
    Read_EE:
      'read 
      RUN 0
    
    Write_EE:
      GET 2, Word eeadr           ' get last eeprom spot
    
      FOR idx = 0 TO 5                    ' loop through bytes in array
        WRITE EEadr//MaxAdr,timestamp(idx)  ' write byte
        EEadr = EEadr + 1 // MaxAdr         ' increment with rollover
      NEXT
    
      PUT 2, Word eeadr
      DEBUG ? eeadr
      RUN 0
    
    



    im having trouble figuring out my read sub,_ee id like for my read statement to cycle through and populate an array stating at the last timstamp(0) spot in the eeprom and store it in spram for display elswhere.

    any ideas?
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2008-11-11 06:02
    If you have a real time clock with ram and battery backup, that is a good place to store the EEadr pointer, so it won't get lost at reset.

    I think there should be two pointers: One is EEadr as you have it, to point to the next location to write a group of 7 bytes. The other, call it EEzero, should point to the oldest location, which will always be the next one to read out. At the start, EEzero and EEadr both point to location zero. But then as data is written, EEadr advances. Nothing happens to EEzero until the EEadr pointer wraps around and catches up with the EEzero pointer. If that happens, then EEzero has to advance too, always in front of EEadr. EEzero always points to the oldest data, which you will want read first. The two pointers chase one another around the circular buffer. I'm not sure, does that make sense in light of what you are trying to figure out?

    The math becomes a little easier if the size of the buffer is an integer multiple of the record size, for example, 271 * 7 = 1897, instead of 1900.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • skynuggetskynugget Posts: 172
    edited 2008-11-11 13:37
    thanks tracy! yeah i have a 1302, and i was planning on cramming my ee pointers on the clock ram when i got the whole deal worked out.

    i think im mopping up what your spilling with the double pointer, and the eeprom size. hopefully ill have time to play tonight and post my results.

    basically what im trying to do here is scroll up and down the timestamp records in the eeprom and show them on a lcd.


    thanks again tracy, and everyone else for that matter!
  • skynuggetskynugget Posts: 172
    edited 2008-11-12 04:46
    hey, its not very pritty or clever, and the program takes up a little more eeprom then i would like, but o well..

    ' {$STAMP BS2e}
    ' {$PBASIC 2.5}
    
    
    MaxAdr        CON       1610     ' number of log locations in bank leaves 148 bytes
    logfile       DATA      (MaxAdr) ' reserves bytes for the logfile
    
    
    EEadr         VAR      Word       ' address for memory write and read
    EEZero        VAR      Word
    task          VAR      Nib       ' where to go for branch
    
    idx           VAR      Byte         ' counter
    timestamp     VAR      Byte(6)   ' timestamp byte array - hrs,mins,secs,mths,date,yr,tagnum  to be sent to eeprom
    logdata       VAR      Byte(6)   ' log data - hrs,mins,secs,mths,date,yr,tagnum read from eeprom
    
    Init:
      FOR idx = 0 TO 6              ' get array values from spram
        GET 8 + idx, timestamp(idx)
      NEXT
    
      GET 2, Word eeadr           ' get last eeprom spot
      GET 4, Word EEZero
    
      GET 1, task    ' what to do??
      BRANCH task, [noparse][[/noparse]Write_EE, Read_EE_Up, Read_EE_Down, Last_Write]
      RUN 0
    
    
    Write_EE:
      FOR idx = 0 TO 6                    ' loop through bytes in array
        WRITE EEadr//MaxAdr,timestamp(idx)  ' write byte
        EEadr = EEadr + 1 // MaxAdr         ' increment with rollover
      NEXT
    
    
      PUT 2, Word eeadr
    
      DEBUG CR, DEC4 eeadr
      GOTO last_write
      RUN 0
    
    Read_EE_Up:
      FOR idx = 0 TO 6
        READ EEZero//MaxAdr,LogData(idx)
        EEZero = EEZero + 1 // MaxAdr
      NEXT
    
      PUT 4, Word eezero
    
      FOR idx = 0 TO 6
        'DEBUG DEC2 logdata(idx)
        PUT idx + 16, logdata(idx)
      NEXT
    
      RUN 0
    
    Read_EE_Down:
    
      FOR idx = 6 TO 0
        EEZero = EEZero + (MaxAdr -1) // MaxAdr
        READ eezero,logdata(idx)
      NEXT
    
      PUT 4, Word eezero
    
      FOR idx = 0 TO 6
        'DEBUG DEC2 logdata(idx)
        PUT idx + 16, logdata(idx)
      NEXT
      RUN 0
    
    Last_Write:
      EEZero = (EEadr -7) // EEAdr   ' set read pointer 7 bytes from last eerprom write
      GOTO Read_EE_up
    
      PUT 4, Word eezero
    
      RUN 0
    
    



    i ended up making 2 subs for the reading the eeprom... 1 to read up the eeprom(up button press), and one to read down the eeprom(downButton Press). also there is a sub Last write, then i use to display the last entry written.

    tracy, or anyone else do you see any problems or have any suggestions?

    many thanks!
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2008-11-12 19:28
    Always be careful with the subtraction and the // operator. This:
    EEZero = (EEadr -7) // EEAdr ' set read pointer 7 bytes from last eerprom write
    will run into trouble when EEadr runs over to zero. Instead, add a number that is 7 less than the modulus, like this:
    MaxAdr7 CON MaxAdr-7
    EEZero = (EEadr + MaxAdr7) // EEAdr ' set read pointer 7 bytes from last eerprom write
    The same caveat applies to the EE_read_down routine, but I see you already did that.

    I didn't understand that you want to intersperse writing the data with reading it back. Right? There are separate slot entry points for each function. I think you need one more pointer and a flag.

    EEadr points to the location to write the next data.
    EEzero points to the location of the oldest data, which will be fixed until the memory is full, after which it will track one step ahead of EEadrs
    EEfullflag is zero until the memory fills up, becomes 1 at the same time that EEzero starts to lock step with EEadr.

    EEreap This is the read pointer, which has to stay within the bounds of the data that has been collected, and may be different from EEadrs or EEzero.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com

    Post Edited (Tracy Allen) : 11/12/2008 7:39:58 PM GMT
  • skynuggetskynugget Posts: 172
    edited 2008-11-12 21:26
    thanks for the math advice tracy!

    in this instance i dont care if the eeprom fills up, when it fills up i would like it just to go back to 0 and rewrite the old entries.

    you still think i need more pointers?
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2008-11-12 23:24
    Well, it depends on devilish details. You know best what will be expected for you user interface!

    As it stands now, it will work fine to wrap for both writing and reading once the memory is full. You have it arranged so that every time a write occurs, that sets the eezero pointer to the most recent reading. What happens if a person is stepping through the readings and suddenly a new reading comes along and shifts the read pointer? You see, I don't really know if that would even happen or be disconcerting!

    When you press up or down for reading, what do you want to happen when it comes to either end? Stop, or wrap around? If the recording has just started and there are not yet 1610 bytes (230 records) recorded, then the read could go into eeprom areas that have not yet been recorded. Maybe that is not a problem.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • skynuggetskynugget Posts: 172
    edited 2008-11-13 02:53
    Wow now i get it.!!!
    i thought about the eeprom issue, figured the math was to hard to do, but now i dont!
    i debated last write sub for a while, but i figured id always want the last record to pop up so i know it was the last record from the start. i think i might be able to run some code in my "display slot" that could alias a record number now though as well. thanks for the attention dr.allen!
  • skynuggetskynugget Posts: 172
    edited 2008-11-20 22:37
    Yeah So im at my wits end... this really doesn't make any sense to me. The following code works good, except for one really odd behavior. When the program enters at Write_EE the value of EERead that gets PUT in ram spot 4 and 5 remains 0 (my other program slots see ) in spot 4 and 5). When the program enters at Read_EE_Up or READ_EE_Down, the value is retreavable as suspected.

    When i coment out
    eeread = eewrite

    at the top of sub Write_EE, it works like i think it should, but then i loose my functionality. when this sub writes an eeprom entry, i would like it to read it back to me as soon as its done with writing.

    ' {$STAMP BS2e}
    ' {$PBASIC 2.5}
    
    
    MaxAdr        CON       1610      ' number of log locations in bank leaves 148 bytes
    Maxadr1       CON       MaxAdr - 1
    MaxAdr7       CON       MaxAdr - 7
    logfile       DATA      $5E(MaxAdr) ' reserves bytes for the logfile
    
    EERead        VAR      Word
    EEWrite       VAR      Word       ' address for memory write and read
    
    
    
    task          VAR      Nib       ' where to go for branch
    
    idx           VAR      Byte         ' counter
    timestamp     VAR      Byte(6)   ' timestamp byte array - hrs,mins,secs,mths,date,yr,tagnum  to be sent to eeprom
    logdata       VAR      Byte(6)   ' log data - hrs,mins,secs,mths,date,yr,tagnum read from eeprom
    
    Init:
      'DEBUG CLS
      FOR idx = 0 TO 6              ' get array values from spram
        GET 8 + idx, timestamp(idx)
      NEXT
    
      GET 2, Word EEWrite           ' get last eeprom spot
      GET 4, Word EEread
    
      GET 1, task    ' what to do??
      BRANCH task, [noparse][[/noparse]Write_EE, Read_EE_Up, Read_EE_Down]
      RUN 0
    
    
    Write_EE:
      eeread = eewrite                    ' set eeread at last written bit for imideate display after
      FOR idx = 0 TO 6                    ' loop through bytes in array
        WRITE EEWrite//MaxAdr,timestamp(idx)  ' write byte
        EEWrite = EEWrite + 1 // MaxAdr         ' increment with rollover
    
      NEXT
    
      PUT 2, Word EEWrite
      DEBUG CRSRXY, 0,4,"WRITE: ", DEC4 EEWrite
    
    
    Read_EE_Up:
      DEBUG CRSRXY ,0,5, "READUP: ",DEC4 eeread
    
      FOR idx = 0 TO 6
        READ EERead//eewrite,logdata(idx)
         EERead = EERead + 1 // eewrite
      NEXT
    
      PUT 4, Word EERead
    
    
      FOR idx = 0 TO 6
        PUT idx + 16, logdata(idx)
      NEXT
    
      RUN 0
    
    
    Read_EE_Down:
      DEBUG CRSRXY,0,6, "READD: ",DEC4 eeread
    
      FOR idx = 6 TO 0
        EERead = EERead + MaxAdr1 // MaxAdr
        READ EERead,logdata(idx)
      NEXT
    
      IF eewrite <> 0 AND logdata = $5E THEN eeread = eewrite : GOTO read_ee_down
    
      PUT 4, Word EERead
    
      FOR idx = 0 TO 6
        PUT idx + 16, logdata(idx)
      NEXT
    
      RUN 0
    
    
Sign In or Register to comment.