B4R Tutorial Writing and reading from the EEPROM

The EEPROM is in most cases the only persistent storage available. As a persistent storage we can use it to store data that will not be lost when the board is turned off.

The rEEPROM library allows us to read and write from the EEPROM.

This example shows how to read and write from the EEPROM with ByteConverter object.
We will count the number of times that the program has started.

Make sure to first check the two libraries: rRandomAccessFile and rEEPROM:

SS-2016-04-12_10.57.53.png


The program flow is:
- Check whether the "special mark" is stored in bytes 0 - 1.
B4X:
'bc is a ByteConverter object.
Dim b() As Byte = eeprom.ReadBytes(0, 2)
If bc.IntsFromBytes(b)(0) = SpecialMark Then
bc.IntsFromBytes(b)(0) converts the array of bytes to an array of Ints (each int is made of two bytes) and then returns the first, and only, int from the array.

- If not then this is the first time that our program is running. Store the special mark and set the counter to 0.
B4X:
eeprom.WriteBytes(bc.IntsToBytes(Array As Int(SpecialMark)), 0)
counter = 0
- If we did find the special mark then read the current counter value from bytes 2 - 3.
B4X:
b = eeprom.ReadBytes(2, 2)
counter = bc.IntsFromBytes(b)(0)

- The last step is to increase the counter and write it to bytes 2 - 3:
B4X:
counter = counter + 1
Log("counter: ", counter)
'write the value to the EEPROM.
eeprom.WriteBytes(bc.IntsToBytes(Array As Int(counter)), 2)

The complete code:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private eeprom As EEPROM
   Private bc As ByteConverter
   Private const SpecialMark As Int = 12345
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   
   'without this delay we will miss the first run as the program is reset when the logger
   'is connected.
   Delay(3000)
   Log("AppStart")
   'the special mark is stored in bytes 0, 1
   'the counter is stored in bytes 2,3
   
   'check if this is the first time
   Dim counter As Int
   Dim b() As Byte = eeprom.ReadBytes(0, 2)
   If bc.IntsFromBytes(b)(0) = SpecialMark Then
     'not first time
     b = eeprom.ReadBytes(2, 2)
     counter = bc.IntsFromBytes(b)(0)
   Else
     'write the special mark
     Log("first time")
     eeprom.WriteBytes(bc.IntsToBytes(Array As Int(SpecialMark)), 0)
     counter = 0
   End If
   counter = counter + 1
   Log("counter: ", counter)
   'write the value to the EEPROM.
   eeprom.WriteBytes(bc.IntsToBytes(Array As Int(counter)), 2)
End Sub

Run it and press on the reset button:
B4X:
AppStart
first time
counter: 1
AppStart
counter: 2
AppStart
counter: 3
AppStart
counter: 4
AppStart
counter: 5
AppStart
counter: 6
AppStart
counter: 7
AppStart
counter: 8
 

MbedAndroid

Well-Known Member
Licensed User
Longtime User
for some reason writing a int causes the program to restart. Looks like that the watchdog gets in?
 

positrom2

Active Member
Licensed User
Longtime User
Will EEPROM data be always stored at the same address?
If so, how to minimize wear out?
 

MbedAndroid

Well-Known Member
Licensed User
Longtime User
you need to specify the eprom adress. A page can be stored in 1 time, as the EEprom increments the adress, however the page is limited to a certain length, mostly 32 or 64 bytes, check the eeprom type.
 

positrom2

Active Member
Licensed User
Longtime User
In the above example, what is the Eeprom address?
Does one have to split the array in chunks of page size?
 

MbedAndroid

Well-Known Member
Licensed User
Longtime User
"Special Byte" and "counter" are the adresses. In this case no paging is used, the adress is incremented each call, internally it's stored low/high byte of the Int
the increment you see in
counter = counter + 1
 

positrom2

Active Member
Licensed User
Longtime User
Thank you. I had the feeling that it is related. However, the value of "SpecialMark" looks strange.
What's its range?
 

MbedAndroid

Well-Known Member
Licensed User
Longtime User
Privateconst SpecialMark As Int = 12345
INT thus +/- 0x7fff
see it as a kind of checksum, only if this value 12345 is found, the program knows that the system has been through 1th time start. (counter value will be setted to 0)
you can define any value, but avoid 0 as a ereased eprom might be also 0, confusing the program
 

positrom2

Active Member
Licensed User
Longtime User
The Eeprom must have a fixed starting address. Where does 12345 go?
Does Eeprom.write write at the beginning of Eeprom space and counter is the Offset?
Or am i totally wrong?
 

MbedAndroid

Well-Known Member
Licensed User
Longtime User
eeprom.WriteBytes(bc.IntsToBytes(ArrayAs Int(SpecialMark)), 0)
sorry i wrote it not clearly, my fault
Specialmark is the information, the 0 in this command is the adress

the counter is stored in adress 2 see the command...
eeprom.WriteBytes(bc.IntsToBytes(ArrayAs Int(counter)), 2)

adresses 0,1 are used to store the Integer of SpecialMark value
Adresses 2,3 are used to store the integer of counter value

If you want to define a new adress, take for example 4, 6 etc
 

positrom2

Active Member
Licensed User
Longtime User
Thank you, so in eeprom.WriteBytes(bc.IntsToBytes(ArrayAs Int(SpecialMark)), 0)
at the position of the 0 the offset from EEPROM start address is given...
Unfortunately, when I Ctrl_Click next to the dot in eeprom.write(...) no help pops up....
 
Top