TransWikia.com

Arduino I2C external 32Kb fram data organization

Arduino Asked by Steven Gangaram on September 25, 2021

Hey guys I am a noob when it comes to data structures and storing types of data, I have been recently working on a project where I needed to store long term data for later retrieval. I decided to buy a Adafruit 10$ 32kb i2c fram Which works, it can store a byte Of data per address which I can successfully do, I can also read those bytes on any address no problem.

One issue I first came across was storing floats into the chip which only took bytes, After googling I managed to spit a float using a union successfully and also storing those in a 4 byte array. Now I did this with 3 different float values which means every 4 bytes stored is basically one split float value.

The second issue is how do I retrieve this data in an organized way and also as a float. I found out you can use a union to do the opposite as well. But how do I tell my code to read every 4 bytes and convert back to float?

Is there a system that can allow me to store data in a structured way using the arduino? Like a time stamped data using an external rtc? Such that when I click retrieve it will print that data in an organized fashion.

One Answer

It'll be easier if you use a struct, not a union. Store all the data you want to preserve in a struct, then cast a pointer to it to be a byte pointer and just treat it as an array of bytes and read and write those bytes to the FRAM.

The union you were using explicitly did the same thing, but it's not easy to scale to multiple items.

Some caveats about what you can safely keep in the struct:

  • do not store pointers in it. A char array is fine because the entire array will take up space in the struct. A char * is not because all you'll save is the value of the pointer, not what it points at.

  • do not store objects (like String) in it. You don't know (and shouldn't know) how the object is composed internally. If need to use objects, they should have serialize and deserialize methods which would store or restore the contents of an object into an array of bytes which you could then store or restore with the FRAM.

Also remember that the C/C++ sizeof function (used below) tells you the size of thing at compile-time. So if you use it on a struct it will tell you the number of bytes it takes to store the struct. If you use it on a char *, it will tell you the number of bytes in a pointer to a char, not the number of bytes in the C string that the char * points at. If you use it on an object - like String str; sizeof(str); - it will tell you how many bytes it takes to store the String object, which will include the length of the string it stores.

Psuedo-code follows. There are more compact ways to write this; I'm aiming for clarity here.

#include <Arduino.h>

struct program_data {
  float first_thing;
  unsigned long second_thing;
  char third_thing[55];
  char fourth_thing;
  uint16_t fifth_thing;
} data;

void save_data(struct program_data *data_ptr) {
  byte *ptr = (byte *)data_ptr;

  for(size_t i = 0; i < sizeof(struct program_data); i++)
    store_byte_in_fram(ptr[i], i);
}

void restore_data(struct program_data *data_ptr) {
  byte *ptr = (byte *)data_ptr;

  for(size_t i = 0; i < sizeof(struct program_data); i++)
    retrieve_byte_from_fram(ptr[i], i);
}

// call when you want to save your data
  save_data(&data);

// call when you want to restore your data
  restore_data(&data);

Correct answer by romkey on September 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP