Seventeen bytes into an EEPROM
Randy
Posts: 79
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
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
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.
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
·
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
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
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
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 Allen
www.emesystems.com
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