Problems setting eeprom address with word variable

noycesd

New Member
Hi Guys,

I am working on a simple data logger and need some help. The data logger will only be powered while collecting data (from RTC and switch locations) so i need to write the data to the eeprom incrementally. My code below increments by 10 to address 0 (as I will be eventually writing 10 bytes of data), every run through adds 10 to address zero and then saves the new value. I can only get the variable to take values up to a value of 250. How do I access the higher address locations?

Cheers, Si

--------------------------------------------------------------

high 0
pause 150
i2cslave %10100000, i2cfast, i2cword 'initialise eeprom
readi2c 0,(w0) 'read loc 0
pause 50
w1=w0+100 'loc 0 + 10 =b13
writei2c 0,(w1) 'write w1 to loc 0
low 0
pause 200

high 0
i2cslave %10100000, i2cfast, i2cword
readi2c 0,(w0,w1,w2)
PAUSE 20
sertxd ("w0 ",#w0,13,10,"w1 ",#w1,13,10,"w2 ",#w2,13,10)
pause 10
low 0
 

crossthreaded

New Member
The problem seems to be some confusion about the difference between the address size and the data size. Data is always 8 bits, so if you want to store a 16 bit quantity you must read/write 2 bytes, i.e. b1 and b0 to read/write w0.

The way you initialise the i2c looks OK for a 16 bit address.
 

westaust55

Moderator
Having set the command
i2cslave %10100000, i2cfast, i2cword 'initialise eeprom
you are able to use words for the location which are 16-bits = 2bytes (by the use of the 12c parameter).

using the write12c command the full structure is:

writei2c location, (variable1, variable 2, etc)

if you make location a word variable (16 bits) then you can address the full EEPROM range.

By the fact that you are using the i2cword mode flag I assume that you are using a larger EEPROM but which one? 24LC256 ?
 
Last edited:

Eclectica

Member
Hi Si,

If I understand this correctly it would appear that although the address can be specified as word or byte, the data can only be byte.

A word has to be split into high/low bytes:
i.e. w1 = b2 + b3 * 256

so your write w1 would be writei2c 0,(b2,b3)

and your read w0 would be readi2c 0,(b0,b1)

Hopefully this helps.

Regards
Michael
 

noycesd

New Member
sorry I'm confused, i have output from the clock (7 bytes) plus a numerical value 0-9 so that would be 8byte in total. Difficulty is setting the address values for writing new data on each cycle, works fine upto 250 (256 is the actual threshold) then resets. I need to be able to allocate higher values to write more than 25 cycles worth of data.

The address is specified by w1 which I believe is a word variable?
 
Last edited:

westaust55

Moderator
There are two ways to write to the EEPROM:
1. one byte at a time,
2. page writes involving several bytes at a time.

When using page writes for multiple bytes in a single writei2c command, something to be careful of is that most of the EEPROMs work on pages which are in multiples of 8 bytes. If a write crosses a page boundary then it loops back to the first location in that page.

With single byte writes, do something like this:
Code:
for w0=0 to 32767
  writei2c w0, (b1) 
  Pause 10
next w0
With page writes do something like this:
Code:
For w0 = $0000 to $7FFF Step 8
  WriteI2c w0,( b1,b2,b3,b4, b5,b6,b7,b8)
  Pause 10
Next
this method is faster if that is a concern - have read of sped increases of the order of 4 for extended/lots of writes in a row but probably not an issue for datalogging
 
Last edited:

noycesd

New Member
Thanks for the advice...the problem is that the picaxe will only be powered while actually collecting & writing data, so the loop option is not possible. I need to be able to save the location of the last write to the eeprom and then read and increment it when the next power up occurs for the next data logging episode. I don't get how i can set the address value using a variable above the 256 limit.

Si
 

westaust55

Moderator
I was only trying to demostrate how you access more than 256 bytes using the two methods. Using a loop was just a convenient example.
How you get your word variable address sorted is a whole new question.

two things:

1. If you are ultimately going to write data in lots of 10 bytes then you may need to buffer writes with some zeros to keep on the 8 byte multiples if using the page writing method.

2. Assuming that power down is always organised then you could write the value of the EEPROM location variable into the PICAXE EEPROM. So as not to always be writing to the same PICAXE EEPROM location (they have a life of about 100,000 writes) you could cycle through say 16 bytes (or more if room permits - larger PIXAXE's have 256 bytes of internal EEPROM)
By writing zero in the old address position and then the new external EEPROM address. Then on each restart, read thru to the non zero value and resume with that value.
 
Last edited:

noycesd

New Member
I had'nt thought of keep track of the address using the picaxe memory, would this overcome the limit of 256 i am experiencing when tracking the location with the eeprom?

Si
 

hippy

Ex-Staff (retired)
I don't know where this 256 limit is coming from - Best to post your code because it's definitely something to do with your software. What model number of Eeprom are you using ?
 

noycesd

New Member
Code is below, i have been checking the value of the address via sertxd and it never get above 256. I always ensure that the initial value of location 0 is zero, so the address location should step up in increments of 10.



high 0
pause 150
i2cslave %10100000, i2cfast, i2cword 'initialise eeprom
readi2c 0,(w0) 'read loc 0
pause 50
w1=w0+10 'loc 0 + 10 =w1
writei2c 0,(w1) 'write new location w1 to location 0 on eeprom
low 0
pause 200

i2cslave %11010000, i2cslow, i2cbyte 'inialise clock
readi2c 0,(b0,b1,b2,b3,b4,b5,b6) 'read clock
pause 50
i2cslave %10100000, i2cfast, i2cword 'initialise eeprom
writei2c w1,(b0,b1,b2,b3,b4,b5,b6) 'write clock data to eeprom at location w1
pause 50

high 0
i2cslave %10100000, i2cfast, i2cword
readi2c 0,(w0)
PAUSE 20
sertxd ("w0 ",#w0,13,10) 'check loaction of write on eeprom has updated
pause 10
low 0
 

crossthreaded

New Member
I've annotated your code below with what is actually happening
high 0
pause 150
i2cslave %10100000, i2cfast, i2cword 'initialise eeprom
readi2c 0,(w0) 'read loc 0 //read 8 bit value from eeprom address 0 into w0
pause 50
w1=w0+10 'loc 0 + 10 =w1
writei2c 0,(w1) 'write new location w1 to location 0 on eeprom // write 8 bit value from 8 lsb of w1 into eeprom address 0
low 0
pause 200

i2cslave %11010000, i2cslow, i2cbyte 'inialise clock
readi2c 0,(b0,b1,b2,b3,b4,b5,b6) 'read clock
pause 50
i2cslave %10100000, i2cfast, i2cword 'initialise eeprom
writei2c w1,(b0,b1,b2,b3,b4,b5,b6) 'write clock data to eeprom at location w1
pause 50

high 0
i2cslave %10100000, i2cfast, i2cword
readi2c 0,(w0) // read 8 bits from eeprom address 0 into w0
PAUSE 20
sertxd ("w0 ",#w0,13,10) 'check loaction of write on eeprom has updated // output an 8 bit number CRLF
pause 10
low 0
the 8 bit number can't represent more than 255, hence your problem. See the post above on writing w0/w1 as two bytes
 

noycesd

New Member
Ok i'm beginning to understand whats happening, having a slow day can you explain the code needed for two b values a little clearer and how I would increment them? Thanks Si
 

crossthreaded

New Member
Eclectica had it right with the read and writei2c instructions, you have to remember that all the word variables w0-w6 are mapped onto the byte variables, so:
(as eclectica pointed) out, you can consider w1 = b2 + 256 * b3

In fact when you set b3, you modify the top byte of w1, when you set b2 you modify the bottom byte of w1. Since the read and writei2c instructions can only work with 8 bit data (but an 8 or 16 bit address), then you need to write 2 byte registers and read two byte registers, see post #4 in this thread
 

westaust55

Moderator
Ok i'm beginning to understand whats happening, having a slow day can you explain the code needed for two b values a little clearer and how I would increment them? Thanks Si
Keep your word variable (eg w0) as the working pointer and increment the word variable by 8, 10, or what ever you need.

But when it comes to saving and retrieving the value store it using the two corresponding byte variables (eg b1, b0)

You still have not answered my earlier question from post 3 (which Hippy reiterated in post 10) as to which EEPROM you are using . . . . ???
Some smaller EEPROMs only address 256 bytes through a byte size address. Then then use the bits normally for A0 to A2 adress control to select which page (of 256 bytes) that you access
 
Last edited:

noycesd

New Member
I seem to have worked out the incremental section of code using b variables as suggested (still not entirely sure what is happening here but it seems to work). Now i have to get it writing the data which is proving lumpy.

The eeproms are 24LC256 by the way

Thanks for everyones input so far.

Si
 
Top