Shop OBEX P1 Docs P2 Docs Learn Events
Seventeen bytes into an EEPROM — Parallax Forums

Seventeen bytes into an EEPROM

RandyRandy Posts: 79
edited 2007-03-13 04:23 in BASIC Stamp
I need to store and retrieve 17 bytes of data to an EEPROM. I have a program that stores temperature data and a time/date stamp into a 24LC128 EEPROM and sends it to StampDAQ upon request. It has been flawless while saving 16 or fewer bytes of info. Then I got this brilliant idea to add one more byte of data and poof! I can't figure out how to do this.··I think·the 24LC128 is writing 16 bytes at a time regardless of what I send (15, 16, 17, etc) but I am not sure and the data sheet isn't clear to me in this regard. If I increment the write address by 16, saving the address for the next write cycle,·and increment the read by 16 in a·FOR NEXT·loop all is well. If I have less than 16 bytes of data I don't provide a variable for the extra data·and the data is fine. If I have fewer than 16 bytes and I change the address and the step value by a matching number I get garbage, like 16 bytes with 15 places to put it or reading some data a second time. I have tried two seperate IC2IN and IC2OUT lines with 16 bytes each and ignoring the extra data but I am not getting consistant results. I don't have enough variables to capture all the data past 17 bytes so I don't know what it is. Is there a limit to the amount of data the IC2 instructions allow?·HELP! I am chasing my tail.

I did not attach the code as there are five slots and lots of PUT's and GET's moving data from slot to slot not to mention all the commented out variety of changes I have tried that has made it dificult to read. The code works fine with 16 or fewer bytes.

Randy

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-11 19:54
    EEPROMs need time to store the data, but can write a small block at a time. They call this a "page". Different size EEPROMs and different manufacturers have different page sizes ranging from 16 bytes to 128 or 256 bytes. If you send an EEPROM bytes that cross a "page" boundary, the address actually wraps around and bytes past the "page" boundary will get written at the beginning of the page rather than on the next one.

    The easiest thing to do is to write 16 bytes, do a PAUSE 5, then write the 17th byte (and pause for that to finish as well). Do the same kind of thing any time the EEPROM address crosses a "page" boundary (any multiple of 16). The manufacturer's datasheet usually gives the page size.
  • RandyRandy Posts: 79
    edited 2007-03-11 21:51
    The EEPROM has 64 byte pages. I did try the PAUSE, I used 50 rather than 5, while trying to write the 17th to as many as 32 bytes. I am wondering if maybe the stamp or the IC2 protocal has a limitation although the manual does not make mention of one.
  • stamptrolstamptrol Posts: 1,731
    edited 2007-03-11 22:33
    Randy,
    Without seeing your code, we're sort of guessing. Couple of possibilities:

    If you're using SEROUT to send data from an array, and one value is 0, (an ASCII Null) it will terminate the transmission.

    If you're using I2COUT, everything has to be in units of bytes (8 bits each) and include addresses, etc. Similar to SEROUT, if you're sending data from an array and the string encounters a NUL, it terminates the transmission. See the Helpfile under SEROUT and I2Cout.

    Cheers,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tom Sisk

    http://www.siskconsult.com
    ·
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-03-11 22:51
    Hi Randy,
    It would help if you can make a small program that illustrates the problem, apart from your multislot program. Usually somewhere along the line of doing that the problem resolves itself. From your description I am not sure how your array of data bytes is entered into the I2C command or the variations you have tried.

    Are you moving the data from scratchpad to eeprom? Are you using block writes, or single byte writes?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • RandyRandy Posts: 79
    edited 2007-03-12 03:27
    I did write a smaller program to see what was going on. After several changes it started working in the form I first tried. I had tried that form several times as it just seemed right. Made the same change to the full program and it is still wack. Even the small program is pretty lenthy but in a nutshell this is what it does. Ten channels of temperature data from an A/D are put into the scratchpad, using PUT command. Comparisons are made to previous data to determine if that data is to be writen to an EEPROM. When called for the data is gotten from the scratchpad, using GET command, time is taken from a RTC as well as the next EEPROM address to be used from the clock RAM. It is sent as following:

    I2COUT SDA,$A0,ee_add.HIGHBYTE\ee_add.LOWBYTE,[noparse][[/noparse]secs,mins,hrs,date,month,year,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11]

    32 is then added to the address (ee_add = ee_add + 32)and it is saved in the clock RAM for the next write.
    When a dump of the saved data is called a start address and the next address are gotten from the RTC RAM. 32 is subtracted from the next address, as it has not yet been writen to, giving the last address. It is then read using a FOR/NEXT loop as follows:

    FOR ee_add = startadd TO last_add STEP 32
    I2CIN SDA,$A1,ee_add.HIGHBYTE\..ete, etc as the write command. The next line is "NEXT".

    The values are all bytes. If you counted you will see eleven bytes when I said there are ten temperatures, one has potental to be below zero so it is a word value. I split it into high and low bytes for the EEPROM.

    The full version is the same except one less temperature needing one less variable and using 16 instead of 32 for the loop and address value. It has beeen running fine for months. When I add the tenth temperature it shows in the LCD as well as in the message board of StampDAQ which also use the GET command. I just can't save it. Now I am quite confussed as the small program works. I tried the same code several times when making changes as I just could not see why it would not work. Then it did. Maybe banging your head enough times is a solution. I put the short version together a second time using cut and paste to be certain that I didn't miss type something. Added only the extra variable and changed the 16's to 32's. It works as the small program but not the full one. Am I repeating myself? Sorry but the last few days have been taking me in circles.

    Randy
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-12 03:46
    This is complicated enough so that you would really have to post the source code involved (as an attachment please). It's not enough to just describe it. It might be helpful to post both the working small version and the broken large version.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-03-12 05:08
    The command as written is a block write of 17 bytes:
    I2COUT SDA,$A0,ee_add.HIGHBYTE\ee_add.LOWBYTE,[noparse][[/noparse]secs,mins,hrs,date,month,year,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11]

    If ee_add is always a multiple of 32 it should work fine, because 32 divides 64 evenly so there is never going to be an issue of crossing page boundaries.

    I don't see how it is going to work if there are 17 bytes and you increment the address by 16. It just doesn't fit! Am I missing something? The next secs value is going to be written on top of the previous val11.

    If you have 17 bytes and increment the address by 17, it will fit, but then you have to deal with the possibility that it will cross page boundaries. In that case you can't use the I2COUT command as written above. The simplest sort of routine of that sort would be something like this:

    spBuffer2eeprom: ' enter with all values in scratchpad buffer, and ee_add for first write.
    FOR idx = 0 to nValues-1
    GET idx, value
    I2COUT SDA,$A0,ee_add.HIGHBYTE\ee_add.LOWBYTE,[noparse][[/noparse]value]
    ee_add = ee_add + 1
    NEXT ' save ee_add back to clock ram

    That is not as fast as the block write, but it does not have issues with page boundaries. It is fairly easy to increase or decrease the number of values, because it is a simple transfer of data from one memory buffer to another. I like to keep memory access routines modular and easy to isolate from the rest of the program.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • RandyRandy Posts: 79
    edited 2007-03-12 16:19
    Tracy,

    The incrementing by 16 is only used when there are 16 or fewer variables. When I have 17 variables I used 32 to increment the loop. The page is 64 bytes so it should work well.·I will look at using your suggested·routine as it will save space in the EEPROM. I just don't understand why the code I have is not working.



    Thanks

    Randy
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-03-12 18:34
    Well, try to post a snippet that does not work the way you expect. For example, fill an array of 17 bytes with fake but systematic data and try it. That should lay to rest doubts you have about the I2C command and the eeprom per se. If you can't make the snippet Not work, that means there is an issue somewhere else in your program in misused variables, variable wrong size, bad alias, bad pointer etc etc. Those issues you have to resolve by other debugging methods. I know it can sometimes seem like you're chasing your tail, but there is always a resolution that usually comes as a smack in the face!

    value VAR byte(17)
    idx VAR Nib
    ee_add VAR Word
    ' put values in eeprom
    FOR ee_addr=0 TO 4095 STEP 32
       FOR idx=0 TO 16  ' create dummy values
          value(idx) = ee_add + idx
          DEBUG DEC value(idx),32
      NEXT
      DEBUG CR
      I2COUT SDA,$A0,ee_add.HIGHBYTE\ee_add.LOWBYTE,[noparse][[/noparse]STR value\17]
    NEXT
    
    ' read out and compare
    FOR ee_addr=0 TO 4095 STEP 32
      I2CIN SDA,$A1,ee_add.HIGHBYTE\ee_add.LOWBYTE,[noparse][[/noparse]STR value\17]
       FOR idx=0 TO 16
          DEBUG DEC value(idx),32
      NEXT
      DEBUG CR
    NEXT
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • RandyRandy Posts: 79
    edited 2007-03-13 04:23
    Hi Tracy,

    In the test program that I had put together I eliminated the temperature routine and replaced it with a routine that generated sequential numbers so I could see if there was missing or duplicate values. As I said earlier at some point it started working okay and I don't know why. Carefully checking the original - full - program for differences I found none but it would still not work. The seventeenth byte of data returned the same data over and over, all the other bytes would change appropriately. The first slot only runs at power up and it writes 32 zeros to the EEPROM so when viewing data downloads it will show a time/date of 00/00/00 12:00 AM and 0 in the ten data positions. The extra 15 zeros are not read, the are just lost. This lets me know that there was a power failure. The EEPROM address is kept in the clock with a backup supply so it does not lose its place and over write saved data if there is an outage. This part always did read correctly, it was all the data after that that would only read 16 bytes correctly and the 17th wrong. Anyway I decided to write 128 zeros and see if the 17th byte of the first four reads would have a zero in them. It wrote and read the correct data in all 17 positions. Why? I then went back to just 32 zeros as it had been for tens if not hundreds of runs and it is working correctly. Once again, why? I am happy that it is working and happy that it is working with the original code with which I never did understand where there was a problem. I would like to know why and more so I am fearfull that this glich will return tomorrow, next week, in several months....I know there was a reason for it that I am not seeing.

    Any ideas or should I just pretend it was a dream and move on?

    Thanks to everyone that has replied. If I ever put together a schematic and get all my garbage notes out of the code I will post this in finished projects. Assuming the glitch doesn't reappear and I get my hammer.

    Randy
Sign In or Register to comment.