24LC256 Datalogger speed

sghioto

Senior Member
What is the maximum sample or number of readings a 18X used as a datalogger can write to a 24LC256 eeprom in one second. I'm not talking about the Picaxe 18X Datalogger kit or assembly, but a 18X programed as a custom datalogger.

Thanks,
S Ghioto
 

womai

Senior Member
At 8 MHz the 18X executes roughly 4000 commands per second. Even a tight loop (read ADC, store value, and so on) with a single ADC channel read needs maybe 3 - 4 commands (including for-next), that makes approx. 1000 repetitions per second. I2C write of a two-word number - I assume you'll use readadc10 and get 10 bit values - into the EEPROM can run at 400 kHz and comprises an estimated 40 bits of data, so execution time is 0.1ms - thus negligible compared to loop overhead etc.

The Microchip 24LC256 needs 5ms write time and has 64 bytes of buffer, so theoretically you could write 32 word variables within 5ms, but the 18X can't easily store (buffer) them before writing (not enough variables). With just 7 word variables (at least one taken up for the loop counter) it's more likely you write single words, thus you'll log less than 200 values per second.

Wolfgang
 

sghioto

Senior Member
Thanks Wolfgang for the input.
I'm using the standard 4mhz clock and the readadc10,w0 command storing b0 and b1 into seperate address locations in the 24LC256. There are 10 commands between the two write commands and a 5ms pause after each write command. I was expecting about 100 samples per second, but actually getting about 60 per second. Does this sound about right assuming the propagation delays you described ?

Thanks,
S Ghioto
 

womai

Senior Member
Does "storing them into separate addresses" mean you are using two separate I2C write commands, with 5ms pause after each? That would mean

10 commands @ 4 MHz = approx. 10/2000 = 5ms
2 waits of 5ms = 10ms

==> total loop duration of 15 ms, or about 67 samples/sec. That matches your number pretty well.

With that there is quick room for improvement, because you can actually write both bytes in the same I2C command, then you only need to wait once. Just put both bytes in the data parameter list of the i2cwrite command. The 24LC256 has this 64 byte buffer that will take the two bytes easily. Only note that you can't write across a page boundary that way, e.g. first byte at address 255 (page 0) and second at 256 (page 1). But if you put the first one at an even location (0, 2, 4) and the second at the following odd location than this never happens.

Second, I'd recommend increasing the clock frequency to 8 MHz - trivial to do with the "setfreq m8" command. Does not help with the write delay, but reduces the loop overhead by 50%.

With those two improvements I'd expect a performance of

10 commands @ 8 MHz = approx. 10/4000 = 2.5ms
1 waits of 5ms = 5ms

--> total of 7.5 ms or about 150 samples/sec, in other words your sample rate would double!

If you can post your code on this forum then I can see if it could be further optimized.

Wolfgang
 

hippy

Technical Support
Staff member
There's also an issue of how accurately time-spaced you want your readings. If you read ADC's for four consecutive sample you can write those out in one burst but the sample time between each will be significantly less than the period between each set of four samples ...

Code:
  ReadADc10 pin, w0
  ReadADc10 pin, w1
  ReadADc10 pin, w2
  ReadADc10 pin, w3
  I2cWrite adr,(b0,b1,b2,b3,b4,b5,b6,b7)
  Pause 5
In such a situation it may ultimately be better to take just one sample every 5mS and store that; 200 samples per second.

You wouldn't necessarily need an explicit 5mS pause after each write, as you can subtract the time taken to jump to the start of the loop and take another sample. By the time you come to send the next data the previous will have been written by the I2C Eeprom chip. Going to 8MHz wouldn't really help here, increasing instruction execution speed would have to be compensated against by increasing the pause time.

For extra speed you can use two I2C Eeprom chips on the same bus. Having sent to one you can get a sample and send to the other while the first is still writing the data sent to it. 8MHz is more of an advantage here. That's 400 samples per second.

Add more I2C Eeproms and you can achive maximum sampling speed but at some point the actual instruction time exceeds the gains of that. 8MHz is a necessity in this case. With an eight I2C Eeprom maximum you might get 1600 samples per second.

Added : You could also cherry-pick Eeproms to use those with shorter write times, as that's the biggest time waster for a single Eeprom setup. Go to something with a 2mS write time and you instantly get 500 samples per second.
 
Last edited:

Brietech

Senior Member
For those that have the "need for speed" when it comes to i2c:
1) A 28X-1 chip can run at 20 Mhz (2.5X speedup)
2) A 28X-1 chip can also write to i2c at 1 Mhz (2.5X speedup vs. 400 khz), for 24FCXXX parts
3) As long as absolute "time spacing" isn't necessary, you can fill up all of the picaxe's variables and RAM, and write everything as one long chunk (as long as you don't exceed the "page" thing).
4) Using "FRAM" i2c chips from a place like Ramtron, they can operate up at speeds up to 1 Mhz, and have NO WRITE DELAY. They are nonvolatile, just like normal 24LCXXX parts, but much faster (and slightly more expensive).
5) Haven't checked if it works yet, but you might be able to "overclock" the i2c bus to use 800 khz (for the 24FCXXX 1 mhz memory chips) for an 18X chip by setting it into 8 Mhz mode, but then running it in "i2c fast" mode, and telling the i2c setup command you are running at 4 mhz.
 

womai

Senior Member
OK Hippy,

you beat me. Wanted to add the thoughts of rolling the aquisition time into the wait time and using more than one EEPROM when I got home ;)

The only trouble is that in my opinion a constant sample rate is pretty important - otherwise you may just miss the important event you wanted to capture... Second, unrolling the loop into a linear sequence only allows a few 100 samples before you either run out of program space or have to loop around - again causing a pause in the sampling.

The best compromise I guess is doing a loop, writing to several EEPROMS, and timing the execution time with a scope (since every data word is written to an EEPROM, those I2C signals can be used as timing markers.
Dummy-Pulsout's between each acquisition can be used to trim the execution speeds with 5us resolution (at 8 MHz), instead of "pause" which has 0.5ms resolution at 8MHz. The longest sample interval will be the one where the loop wraps around, this one would need the shortest pulsout. Yes I know, execution times can change slightly when you change constants or do any changes in the program, but it should be possible to at least get close. I could offer to help - I have several 24LC EEPROMS lying around and access to a good scope.

Code snippet for two EEPROMS (untested!):

for index = 0 to 0xfffd step 2

ReadADc10 pin, w0
i2cslave SLAVE_ADDRESS1, i2cfast, i2cword
I2cWrite index,(b0,b1)
pulsout DUMMY_PIN, DELAY1 ' make that 2.5ms - execution time

Readadc10 pin, w0
i2cslave SLAVE_ADDRESS2, i2cfast, i2cword
I2cWrite index,(b0,b1)
pulsout DUMMY_PIN, DELAY2 ' make that 2.5ms - execution time

next index


That could achieve 500 samples/sec, and even better if you use more EEPROMS in parallel. Since each sample takes about 5 commands (readadc, i2cslave, i2cwrite, pulsout, and loop wraparound) I'd expect the upper limit to be maybe 8000/5 = 1600 samples/sec.

Wolfgang
 

hippy

Technical Support
Staff member
It would also be possible to synchronise to an external clock, one half waits for a line high the next waits for the low. Turn this into interrupt driven and there should be close to consistent latency times from the pulse change edge to the ReadAdc execution and the I2cWrite. The I2cSlave and switching interrupt polarity is done after everything else to ready for the next interrupt.

The 18X can use an external 32kHz crystal and might be able to generate the 5mS/2.5mS toggling signal, or use a 555.

The only issue is if execution time is too long for the period in which case it has to be extended and maximum sample rate gets reduced.

We're moving more into "what is your application and its needs" than the original "what is maximum sample rate". The actual application will probably dictate the mechanism used.
 

sghioto

Senior Member
Thanks again everyone for your response!

I have a lot of info to digest. As a novice this may take awhile. Getting back to specific need, I was looking to get 100 samples per second as best as possible. Exporting to Excel my time base using "samples taken" represents one second for every 100 samples. Actually 60 samples per second is enough resolution for this project, just an extra step in converting this to seconds in Excel. I am using two seperate write commands but still require the 10 commands in between so the real delay is this. But if I could send just one write command and use the delay between writes then 100 samples is possible as everyone has suggested. Obviously my understanding of writing a word into a 24LC256 needs clarification. I'm assuming you need to write into 2 separate locations in order to preserve the word value. I'm using a for-next command to increment the eeprom address locations.This is my code, try not to get too upset!

startrecord: low 7 ' activates recording led
i2cslave %10100000,i2cfast,i2cword ' address and settings for the 24lc256
for w2 = w2 to 3600 ' counter to store b1 value
w3 = w2 + 3601 ' second counter to store b0 value
readadc10 2,w0 ' read 10 bit value and store word value
writei2c w2,(b1) ' write b1 content of w0 into
pause 5 ' wait 5ms
writei2c w3,(b0) ' write b0 content of w0 into w3 address
pause 5 ' wait 5ms
if stopsw = 0 then stoprecord
loop1: low 7
next w2
 

womai

Senior Member
This your your code, but modified to do just a single write. Yes, you have to write it byte by byte, but can do that in a singloe i2cwrite command:

startrecord: low 7 ' activates recording led
i2cslave %10100000,i2cfast,i2cword ' address and settings for the 24lc256
for w2 = w2 to 7200 step 2 ' counter to store b1 value
readadc10 2,w0 ' read 10 bit value and store word value
writei2c w2,(b1,b0) ' write b1 content of w0 into
pause 5 ' wait 5ms
if stopsw = 0 then stoprecord
loop1: low 7
next w2


That puts the MSB of w0 into one memory location and the LSB into the following.

Wolfgang
 

sghioto

Senior Member
Thanks Wolfgang!!!

Working at 100 samples a second now!

I didn't understand the "step 2" part of the counter command before but do now.

Again thankyou everyone.

S Ghioto
 
Top