[Submission] Flashee-eeprom library: eeprom storage in external flash

I am having a similar problem with the flashee library. I have a function that saves a value to the flash eeprom via a function exposed to the cloud api.

This function only writes to the flash eeprom when I go to the spark api URL and enter the correct value.

The core immediately reads back the contents of the memory address and the value is correct.

When the spark core starts up the first thing it does is read that value written to the flash eeprom.

From there I can power cycle the core several times and the value persists, but maybe 1 out of 10 times the value is randomized or full of FF. If I power cycle the core a few more times the value comes back on itā€™s own.

Is this possibly an issue related to wear leveling?

@goseese, after lots of testing that is exactly my suspicion. Iā€™m so happy you are experiencing the issue, for the sake of debugging, and that you have found steps to reproduction as simple as restart and watch the data change. I think this will help lead to a fairly easy process tracking down the problem, and weā€™ll all have a fantastic library to take advantage of. @mdma obviously knows his stuff, and will be back in town soon I believe. Letā€™s make sure to help however we can when he is back, and make sure he knows how much we want to use his library. :slight_smile:

1 Like

I am certainly willing to help test. I would really appreciate this library too. Just in case any body wants to know I have several cores here both white and black and they all have the same issue.

I think this library may help me but wanted to check before trying to port some Arduino code.
My simple need is just to store 3 different int values which should be unchanged even after a reboot. I don't pretend to understand a lot of this low-level coding but What would I need to do in this library to achieve the same thing?In Arduino I was simply using something like -

int thTripValue = EEPROM.readInt(3);
EEPROM.writeInt(3, thTripValue); //Update with new thTripValue

@MagicTech, the Spark EEPROM library ā€œemulatesā€ eeprom using some built-in flash memory. The read and write functions are single byte operations so for for an INT value, you would have to break it up in bytes. What is the range of values for these 3 variables?

Thats what I was afraid of, as I only saw references to writing strings.
My values would be 0-99
Thanks

In my implementation of the library I save the length of my data in the first byte of the address. Then when I read back the value the functions reads the first byte at that address to determine the length. Then it reads the data at start address + 1 for the length.

@MagicTech, though @goseese has a great idea, you only need a single byte to express a value from 0-99 (0-255 actually). So if you declare your values as uint8_t (unsigned 8bit integer), it will work fine and you can use the EEPROM.read and write() without worrying about data size. :smile:

That would work for sure when you know your number will be less then 255.
I needed to save the number like 55254, or sometimes itā€™s a string literal like and API end point, a URL or an access key.

First I convert the value to be saved into a char array via something like

var s_len = sprintf( data, ā€œ%dā€, some_int );

I have a function that is called with write_ee( start_addr, data, length );

The function write_ee writes the value of length to the start address first. In this example it would write 0x05.

Next the write_ee function writes the contents of data to the start address + 1 byte;

To read back the data a read_ee function first reads 1 byte at the start address which will return 0x05.

Then read_ee reads into a char array the contents of the starting address + 1 byte for the length of 0x05

In your example if I was saving the value of 99 it would have a length of 2 since itā€™s saved as a string.

Peekay
When you say use EEPROM.read and write(), do you mean the flash->write() and flash->read() or do you mean I donā€™t have to use this library and just use EEPROM?
Sorry if i am confused.

Ok I think I got it.
I didnt know Spark had a built in EEPROM Lib

EEPROM.write(0 ,tripValue);
int Trip = EEPROM.read(0);
1 Like

@MagicTech, yes as long as tripValue is a declared as type uint8_t :smile:

Yes it is.
For my use, is there any disadvantage to doing it this way?
How do i check the memory usage?
Thanks

@MagicTech, there are 100 bytes of emulated EEPROM available. How often do you expect to write out the values? When you say ā€œcheck the memory usageā€, what exactly do you mean?

In this application, it will not be written very often. A user will set an alarm trip value and the sketch will continuously compare the current live sensor reading to the trip value.

I didnt see anywhere in the Web IDE that it tells me what my program size or memory usage is.

@MagicTech, after a successful compile with the IDE, in the bottom window you will get a message ā€œCode verified! Great workā€ and a little circle with a vertical bar. Clicking that vertical bar will give you the compiler output message detailing the memory usage.

1 Like

Ah. hidden gems.
One last question, With a completely empty sketch. the result is

Output of arm-none-eabi-size:

text data bss dec hex
72984 712 12088 85784 14

In a nutshell:
Flash used 73696 / 110592 66.6 %
RAM used 12800 / 20480 62.5 %

Can you explain?

@MagicTech, I got this with a blank sketch:

Output of arm-none-eabi-size:

text	data	bss	dec	hex
72088	704	12060	84852	14

In a nutshell:
Flash used	72792 / 110592	65.8 %
RAM used	12764 / 20480	62.3 %

The reason for these numbers is that the Core firmware is compiled and included along with your sketch. So all the code used to manage the wifi and connect to the cloud along with all the other functions are in there. The only thing not included is the 20kb of bootloader.

Peekay
Although I have proved the EEPROM logic works in a small test sketch, I am struggling to get it to work in my larger sketch.
The one difference is I am reading the EEPROM memory in the header at the variable declaration. (before setup())

uint8_t testValue = EEPROM.read(9);

I understand the first read may be garbage but in my code I am setting this variable based on a slider input. So on the next power cycle the set value should persist and it does not.
I guess my dumb question is, is the EEPROM ready to be read in the header?

thanks

Ok I did find a way to move the assignment into the void setup() function and now it works.

2 Likes