Shop OBEX P1 Docs P2 Docs Learn Events
BS2pe EEPROM sequential write of data series — Parallax Forums

BS2pe EEPROM sequential write of data series

Andy McLeodAndy McLeod Posts: 40
edited 2006-11-15 18:40 in BASIC Stamp
I have a stand alone pressure data logger which will be activated be a single push button. When the button is pushed, the stamp collects data through the LTC1298 for a fixed period of time determined by the total number of samples programmed.

My question is this - How do I write the data in the format xxxx (0-4095) to eeprom for each capture sequence and have the stamp recognize where in eeprom (bank vs. address) it must start to write to on the next sequence, which may be minutes to days later.

Comments

  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-11-14 20:21
    Andy,
    ·
    ·· When you say a “fixed length of time”, are you using an RTC?· Many have RAM on-board which can be battery-backed to hold the counter value for the EEPROM.· If power outage isn’t an issue, you can simply store the counter value in a variable and WRITE it to EEPROM at the end of the sequence (specific location).· That way when the system comes up later it can retrieve that value for the next sequence.· The counter location can be reset using a DATA statement during program download.· Take care.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Andy McLeodAndy McLeod Posts: 40
    edited 2006-11-14 20:51
    Chris-

    I am using the DS1302 for real time stamping at the start of the acquisition. I'm guessing that I can WRITE to the DS1302 RAM a value for STORE and WRITE and retreive those values? Ever done something like that? Got code?
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-11-14 21:04
    Andy,
    ·
    ·· That is correct!· You can store up to 31 bytes into the RAM.· If you are using a battery it will be backed up.· I do have some example code linked below for accessing the RAM.· I also have another example I can try to find which actually loads the RAM on startup for certain values.· It’s pretty painless.

    http://forums.parallax.com/showthread.php?p=531080

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-11-14 21:23
    Andy,
    ·
    ·· I’ll tell you what…Looking back at my other code I am a little embarrassed at how I did things.· Very efficient at the time, but I’ve since learned a lot.· Let me post three routines for you…The first is the Initialization routine for my Digital Alarm Clock program.· It calls the Get_RAM routine.· I also posted the Set_RAM routine.· The Get_RAM routine is called during initialization only.· Set_RAM is called whenever one of the affected variables is updated.· There are 10 bytes being saved here.· The names should give you an idea what they are.· I hope this helps.· Take care.

    ' -----[noparse][[/noparse] EEPROM Data ]-----------------------------------------------------
    Defaults:       DATA    $30, $06, $30, $07, $00, $21, $55, $05, $02, $C3
    
    ' -----[noparse][[/noparse] Initialization - DS1302 ]-----------------------------------------
      GOSUB Get_RAM                         ' Initialize DS1302
    
    ' -----[noparse][[/noparse] Initialization - MAX7219 ]----------------------------------------
      GOSUB Display_Test                    ' For Debugging Purposes
      FOR index = 0 TO 7                    ' 4 Registers & 4 Values
        LOOKUP index, [noparse][[/noparse]Scan, 5, Brite, 15, Decode, $FF, ShutDn, 1], ioByte
        SHIFTOUT DataIO, Clock, MSBFIRST, [noparse][[/noparse]ioByte]
        IF (idxOdd = No) THEN No_Load       ' Wait For Value To Be Shifted
        PULSOUT MAX7219, 5
    No_Load:
      NEXT
    
    ' -----[noparse][[/noparse] Initialization - DS1804 ]-----------------------------------------
      GOSUB Reset_Volume                    ' Make Sure Volume Is Down
    
    ' -----[noparse][[/noparse] Initialization - Other ]------------------------------------------
      GOSUB Dimmer                          ' Restore Dimming State
    
    


    ' -----[noparse][[/noparse] Subroutines - DS1302 ]--------------------------------------------
    Set_RAM:
      index = CWPr                          ' Write Protect Register
      ioByte = WPr0                         ' Clear Write Protect
      GOSUB RTC_Out                         ' Send Command
      ioByte = 0                            ' Address Of Alarm 1 Minutes
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = a1Mins                       ' Set Alarm 1 Minutes
      GOSUB RTC_Out                         ' Write Value
      ioByte = 1                            ' Address Of Alarm 1 Hours
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = a1Hrs                        ' Set Alarm 1 Hours
      GOSUB RTC_Out                         ' Write Value
      ioByte = 2                            ' Address Of Alarm 2 Minutes
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = a2Mins                       ' Set Alarm 2 Minutes
      GOSUB RTC_Out                         ' Write Value
      ioByte = 3                            ' Address Of Alarm 2 Hours
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = a2Hrs                        ' Set Alarm 2 Hours
      GOSUB RTC_Out                         ' Write Value
      ioByte = 4                            ' Address Of Dimmer Start Minute
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = d1Mins                       ' Set Dimmer Start Minute
      GOSUB RTC_Out                         ' Write Value
      ioByte = 5                            ' Address Of Dimmer Start Hour
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = d1Hrs                        ' Set Dimmer Start Hour
      GOSUB RTC_Out                         ' Write Value
      ioByte = 6                            ' Address Of Dimmer End Minute
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = d2Mins                       ' Set Dimmer End Minute
      GOSUB RTC_Out                         ' Write Value
      ioByte = 7                            ' Address Of Dimmer End Hour
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = d2Hrs                        ' Set Dimmer End Hour
      GOSUB RTC_Out                         ' Write Value
      ioByte = 8                            ' Address Of Dimmer Level Setting
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = dSet                         ' Set Dimmer Level Setting
      GOSUB RTC_Out                         ' Write Value
      ioByte = 9                            ' Address Of Flags
      index = WrRam | (ioByte << 1)         ' Write RAM Mode + Address
      ioByte = flags                        ' Set Flags
      GOSUB RTC_Out                         ' Write Value
      RETURN
    
    



    Get_RAM:
      index = CWPr                          ' Write Protect Register
      ioByte = WPr1                         ' Set Write Protect
      GOSUB RTC_Out                         ' Send Command
      ioByte = 0                            ' Address Of Alarm 1 Minutes
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      a1Mins = ioByte                       ' Restore Alarm 1 Minutes
      ioByte = 1                            ' Address Of Alarm 1 Hours
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      a1Hrs = ioByte                        ' Restore Alarm 1 Hours
      ioByte = 2                            ' Address Of Alarm 2 Minutes
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      a2Mins = ioByte                       ' Restore Alarm 2 Minutes
      ioByte = 3                            ' Address Of Alarm 2 Hours
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      a2Hrs = ioByte                        ' Restore Alarm 2 Hours
      ioByte = 4                            ' Address Of Dimmer Start Minutes
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      d1Mins = ioByte                       ' Restore Dimmer Start Minutes
      ioByte = 5                            ' Address Of Dimmer Start Hours
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      d1Hrs = ioByte                        ' Restore Dimmer Start Hours
      ioByte = 6                            ' Address Of Dimmer End Minutes
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      d2Mins = ioByte                       ' Restore Dimmer End Minutes
      ioByte = 7                            ' Address Of Dimmer End Hours
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      d2Hrs = ioByte                        ' Restore Dimmer End Hours
      ioByte = 8                            ' Address Of Dimmer Level Setting
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      dSet = ioByte                         ' Restore Dimmer Level Setting
      ioByte = 9                            ' Address Of Flags
      index = RdRam | (ioByte << 1)         ' Read RAM Mode + Address
      GOSUB RTC_In                          ' Get Value
      flags = ioByte                        ' Restore Flags
      RETURN
    
    



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Andy McLeodAndy McLeod Posts: 40
    edited 2006-11-15 13:56
    Chris-

    Very elegant code. I have only3 bytes of programspace left, though.

    Consider: SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]%0\1,RTCCmd\5,%11\2,Value]

    Which of those values are the byte addresses?
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2006-11-15 16:12
    Hi Andy,

    If you are using a BS2pe, you have 8 slots available for program. When you say you have only 3 bytes of program space left, do you mean in slot 0 only, or in all 8 slots?

    Also, the BS2pe has a total of 16 slots, and 8 of them are available for programs and all 16 can be available for storing data (total of 32k bytes). Are you using that to store your data sequences, or are you storing the data sequences in an external eeprom?

    concerning:
    > SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]%0\1,RTCCmd\5,%11\2,Value]

    The address is the 5 bits, RTCCmd. The command frames the 5 bit address in a couple of other bits and sends the whole thing lsb first. It might be easier to see with simple examples:

    To write a single byte to the RAM, the address can be from 0 to 30 decimal.

    SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]%11000000,Value] 'writes value to location 0.

    SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]%11000010,Value] 'writes value to location 1. Etc. OR....

    SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]%11000000 + (location<<1),Value] 'writes a value to "location", which is shifted left one to put it in the proper place. And...



    Note lsb=0 for a write and it will =1 for a read. The msb is always 1. The bit next to the lsb selects either 1:RAM 0:clock&control

    All writes to the clock register and RAM have to be done with the write protect bit set to zero:
    SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]$8E,0] ' enable writes
    ' ....
    SHIFTOUT Dta, Clk, LSBFIRST, [noparse][[/noparse]$8E,$80] ' disable writes

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

    Post Edited (Tracy Allen) : 11/15/2006 4:16:06 PM GMT
  • Andy McLeodAndy McLeod Posts: 40
    edited 2006-11-15 18:02
    Tracy-

    1. Based on the memory map in the editor, I appear to have only 3 bytes left to work with. This comes after I got an "out of variable space" (?) error and reworked my code to fit better.

    2. My original code uses STORE 8 to STORE 15 to put data. I do this to guarentee the 0 - 8 banks are available for programmng. I know you use the BS2pe extensively, do you use external eeprom in addition to the internal?

    3. Thank you for the descrition of the SHIFTOUT command. I'll get on a rewrite this afternoon using your description.
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-11-15 18:18
    Andy,
    ·
    ·· The slots are not available as one contiguous block in the Memory Map so what you’re seeing is a single 2K slot that is full.· As with the upper data banks you’re using you need to switch banks in order to run the next program.· In the help file see the RUN command.· This of course will require you to do a little re-thinking on organization of your program.· You will have to split main functions up into two slots.· Common subroutines will need to be in both slots, and to preserve variables across slots you need to declare them all exactly the same in all slots you use.· There is a Nuts & Volts article that covers multi-bank programming as well.· I hope this helps.· Take care.

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


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2006-11-15 18:40
    Chris answered the question. Lucky you have a lot more program space to expand into! I recommend putting initialization code into slot 0, then RUN into slot 1 for the main program loop. You can put routines for setting the clock and other such setup/configuration in their own slot too.

    I do use an external flash memory on my data loggers, but that may not be necessary on your system if the additional slots of the BS2pe are sufficient.

    I do concur with Chris on using the DS1302 (battery or capacitor backed) to hold the memory pointers.
    In order to spread out the wear on the eeprom, I store a couple of pointers. One to the base location of the current session, and one to the next free location, where you will write the next data byte. When starting a new run, the basepointer is set equal to the next free location pointer. The logging wraps around from the end of the available memory and back to the beginning, and with successive sessions, the two pointers chase one another around the memory array.

    You asked about memory pointers, to select slot and address. If the memory pointer goes from 16384 to 32767 (in slots 8 to 15), then the slot and address for writing a byte is:
    STORE pointer/2048 + 8
      WRITE pointer//2048,  value  ' the //2048 is really not necessary, but that is the effect
       pointer=pointer+1
       if pointer>32767 THEN pointer=16384   ' wrap around
       IF pointer = basepointer THEN  ??    '  memory is full, and you can either stop logging, or wrap, or ???
    



    To store 12 bit values, you will be storing word values, so the pointer might be incremented by 2. There are lots of ways you can tune this.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
Sign In or Register to comment.