How to use PROGMEM with SEEEDUINO XAIO

My first post.
After 75 years I'm learning programming for hobby projects. I liked the small size of the SEEEDuino XAIO so shifter my recent project from the Nano and now discovered the Seeeduino does not have EEPROM. So I'm trying to get a few simple integers and floats saved in NVRAM using the PROGMEM feature.

My project is a simple golf score keeping device, battery operated with OLED display. The device allows adjustment of your GHIN (golf handicap index) and then calculates the appropriate PAR for the golf course and hole that you play. I need to adjust the GHIN and save the adjusted float number so it doesn't need to be "reset" each time the device is powered on.

This was quite simple with the Nano using the EEPROM storage, but I can't seem to make the XAIO save to flash and then read it back upon power up.

My code defines the variable GHIN as a float (mine is currently 19.2) and I adjust it in the program code void loop. Then I need to save the adjust GHIN number to flash so it is updated when I turn the device on again.

In void.setup I have this code to read from flash.

float GHIN ;
float savedGHIN ;

void setup() {
..
GHIN = pgm_read_float_near(&savedGHIN);
//this is supposed to read the value from flash but I does not.
...
void loop(){
...
if (singleClick == true && doubleClick == false)
{
const PROGMEM float savedGHIN = {GHIN};
// this doesn't seem to work???
Serial.println(savedGHIN);

// EEPROM.put(0, GHIN);
//thisEEPROM worked when I was using the Nano
singleClick = false;
doubleClick = false;
picTeeColor = true;

The code complies but does not seem to work.

My guess is it's a simple solution, but I've been searching for an answer for several days, Any help for an old guy trying to enjoy retirement would be much appreciated.

Thanks
Jim

Sadly, you can’t PUT progmem data at runtime, you need EEPROM, or NVRAM of some type.

One possibility is an SD card using SPI.

The XIAO has a SAMD21 processor; do a search for samd21 eeprom simulation.

Be aware that flash memory can not be written as often as EEPROM; it wears out faster.

Why would you do that? "19.2" hardly counts as precision - a (16-bit) word would be fine!

I'm curious about your comment that you "can't PUT program data at runtime".
So does this mean you can only PUT during void SETUP()? Seems like all the examples I am finding only operate during void SETUP().

So is it possible to make some variable changes during void LOOP, then call SETUP() again to get the changes committed to NVRAM?

All I want to do is save float numbers to survive a power cycle. They are only set at most once during a power cycle. But I can't seem to find a workable solution for a MCU without an EEPROM.

Are there any other ways?

How do you convert 19.2 into a 16bit word? and save it?

…look into using any type of NVRAM of some type.

Another possibility is an SD card using SPI

This was quite simple with the Nano using the EEPROM storage, but I can't seem to make the XAIO save to flash and then read it back upon power up.

You can use my FlashStorage_SAMD library as Emulated-EEPROM

Have a look at EmulateEEPROM example

Just be aware that The content of the FlashStorage is erased each time a new sketch is uploaded and download / store the previous data before updating the flash with new code. Then upload the data to Emulated-EEPROM, if still necessary.

No problem whatsoever. It's actually 192, and you move the dot. :rofl:

Saving? Well, I'll leave that to the further discussion. Once you figure out how to save a 16 bit word, that is how you do it.

Hello khoih-prog

I am trying to use your library for the Seeeduino XAIO but still can't get the Emulated EEPROM to work. Here is my code. I've tried with int and float and still get "nan" when I try to read or get the stored value.

I have also run your Clear EEPROm example code and it runs fine, and doesn't return any errors. So I assume toe NVRAM is ok.

Any assistance would be much appreciated.

#define FLASH_DEBUG 0
#include <FlashStorage_SAMD.h>
int address = 0;
bool flashTest = true;
float GHIN = 23.3;
// float GHIN;
void setup()
{
Serial.begin(9600);
while (!Serial);
delay(200);
Serial.print(F("\nStart EEPROM_write on ")); Serial.println(BOARD_NAME);
Serial.println(FLASH_STORAGE_SAMD_VERSION);
Serial.print("EEPROM length: ");
Serial.println(EEPROM.length());
}

void loop()
{
while (flashTest)
{
EEPROM.put(address, GHIN);
EEPROM.commit();
flashTest = false;
Serial.print(EEPROM.get(address,GHIN));
}

}

==================================================
Start EEPROM_write on Unknown SAMD21 board
FlashStorage_SAMD v1.3.2
EEPROM length: 1024
23.30

Then modified code to just get GHIN
and I get "nan" instead of my float 23.3
So the response is not a valid float.

=================================================
*/
#define FLASH_DEBUG 0
#include <FlashStorage_SAMD.h>
int address = 0;
bool flashTest = true;
//float GHIN = 23.3;
float GHIN;

void setup()
{
Serial.begin(9600);
while (!Serial);
delay(200);
Serial.print(F("\nStart EEPROM_write on ")); Serial.println(BOARD_NAME);
Serial.println(FLASH_STORAGE_SAMD_VERSION);
Serial.print("EEPROM length: ");
Serial.println(EEPROM.length());
}

void loop()
{
while (flashTest)
{
// EEPROM.put(0, (float)GHIN);
// EEPROM.commit();
flashTest = false;
Serial.print(EEPROM.get(address,GHIN));
}

}

===========================================
Start EEPROM_write on Unknown SAMD21 board
FlashStorage_SAMD v1.3.2
EEPROM length: 1024
nan

I have also tried using a byte put as 233 and the get returns 255.

Well, seems like I missed the fact that each time I update the code, all the NVRAM is reset. So I tried again, just reseting power and I'm still not able to see my saved data.
So it must be something else.

Why not use a very small i2c EEPROM module?

There are even smaller ones than the one shown.

After more work, I am now able to save byte variable, but can't seem to make float work. Still get nan when I try to read a stored float.

Have a look at more complex example StoreNameAndSurname where you can store anything in a whole struct,

typedef struct
{
  char name[100];
  char surname[100];
} Person;

Person owner;
...

 // ...and finally save everything into emulated-EEPROM
EEPROM.put(storedAddress + sizeof(signature), owner);

then read back the whole struct to get data

...
Person owner;

EEPROM.get(storedAddress, signature);


// If the EEPROM is empty then no WRITTEN_SIGNATURE
if (signature == WRITTEN_SIGNATURE)
{
  EEPROM.get(storedAddress + sizeof(signature), owner);

  // Say hello to the returning user!
  Serial.print("Hi "); Serial.print(owner.name); Serial.print(" "); Serial.print(owner.surname);
  Serial.println(", nice to see you again :-)");

Treat float or anything just a simple data type

Thank you all.
I am working now.
Lots of simple amateur coding problems but I'm learning.
I wonder when does the embarrassment of making stupid coding mistakes subside.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.