Retrieve data using EEPROM.get()

I want to retrieve my data from the EEPROM after the code has finished running. I am trying to use a photon particle and get the data via serial. I want to get and print myData after we run the code. We’re using CoolTerm to read data off of the photon, but it’s not printing myData from the line Serial.print(EEPROM.get(eedress, myData)). I have included our code below. Any suggestions?

#include <flashee-eeprom.h>

void clearEEPROM();
SYSTEM_MODE(SEMI_AUTOMATIC);

int pump = D0;
double flow = 0;
int eedress = 0; //holds eeprom memory address
char myData = myData;
int memoryFull = D7; //LED to indicate that memory is full
int eeprom_size = 1024; // holds eeprom memory size
unsigned long lastTime = 0UL;

void setup() {
    Particle.variable("pump", pump);
    Particle.variable("flow", flow);
    Particle.variable("myData", myData);
    Time.zone(-5);
    pinMode(pump, OUTPUT);
    digitalWrite(pump, LOW);
    pinMode(memoryFull, OUTPUT);
    EEPROM.put(eedress, myData);
    EEPROM.get(eedress, myData);
    Serial.begin(9600);
    delay(5000);
    Serial.println("Sampler 1    Clever-turkey   Flow Meter 1");
    Serial.println("Date   Voltage(V)   Flow(L/min)");
}

void loop() {
    double flow = analogRead(A0);
    double voltage = flow/(4095/3.3);
    double theFlow = -1.5378*(voltage*voltage*voltage*voltage)+6.23*(voltage*voltage*voltage)-8.7603*(voltage*voltage)+5.4769*(voltage)-1.1533;
    String myData = String(Time.format("%Y-%m-%d %H:%M:%S") + ";" + String(voltage) + ";" + String(theFlow) + ";" + String(flow) + "\n");
        if (millis() <= 1550000) {
            digitalWrite(pump, HIGH);
            //Serial.print(myData);
        }
       else
        {
        digitalWrite(pump, LOW);
    }
    Serial.print(EEPROM.get(eedress, myData));
    delay(2000);
}

Not sure what this syntax is supposed to mean

char myData = myData;

But obviously EEPROM.get(eedress, myData) will only return one char.
Is this what you expect?

Also reusing a global variable name for a local variable is generally not considered good practice.

However, the reason for your trouble is that String is not a datatype that stores well via EEPROM since the actual string is not stored in the object. The object only holds a pointer to the string on the heap, but once destructed that pointer will be invalid.

2 Likes

char myData = myData was suppose to be opening a variable that is call-able. I’m having trouble trying to understand how to write the three variables which are all doubles (voltage, theFlow, time) into EEPROM.get().

We tried to to write one of the variables in EEPROM, but this returned nan. Do you have thoughts on how to write it properly and how to pull it after it’s written? Thanks!

You’d create a struct to tie all required variables together into one entity which can be used for EEPROM.put() and EEPROM.get().

2 Likes

@marytovillo, here is a snippet of code from a set of EEPROM routines that I use. This sample will write a struct to address 0:

struct EventLogObject {
    uint8_t type;
    uint32_t timestamp;
};

EventLogObject EventLog;

EventLog.type = 0;
EventLog.timestamp = Time.now();
EEPROM.put(0, EventLog);
3 Likes

I’m sitting here thinking to myself "What the hell is a “Struct” !?! :smile:

Looks useful. Something new to learn about :books:

@RWB, when you finish reading on struct, throw in a “union” for good measure.

Without going into the gory details, here’s what the most complicated data structure looks like for my outdoor weather station:

typedef struct WirelessData 
{
    uint16_t pktType;
    uint16_t devType;
    union 
    {
        struct THPStruct env;
        struct WindStruct wind;
        struct VoltageCurrentStruct elec;
        struct ControlStruct ctl;
        struct NodeStruct node;
    };
} WData;
2 Likes

We made a struct and have it writing to the EEPROM, but now we want to be able to pull the data all at once upon startup. At this time, it’s writing as the loop goes. How will we go about doing this? Thank you!

If you can do it in loop() you’d do it the exact same way in setup()

Does it have to be called in serial to get the data from the EEPROM? We tried to call the EEPROM struct through the serial in the setup() and did not receive the data. This is what we have right now for our code. Thanks!

struct myObject {
    float voltage;
    float theFlow;
    float flow;
    };

void setup() {
    Particle.variable("pump", pump);
    Particle.variable("flow", flow);
    Time.zone(-5);
    pinMode(pump, OUTPUT);
    digitalWrite(pump, LOW);
    pinMode(memoryFull, OUTPUT);
    Serial.begin(9600);
    myObject callStruct;
    EEPROM.get(eedress, callStruct);
    Serial.print(callStruct.voltage);
    Serial.print(callStruct.theFlow);
    Serial.println(callStruct.flow);
    delay(5000);
}

The Serial.print() function has no overload that can take a struct as input parameter. Hence you need to read the data into a variable and use that then.
One way could be as you did it or like this

  Serial.printlnf("%.1f %.1f %.1f", callStruct.voltage, callStruct.theFlow, callStruct.flow);
1 Like

Just to be sure, is it safe to assume you are incrementing the EEPROM index by the size of the structure every time you write your stuct to it?

1 Like

@marytovillo, where in your code do you set the initial value for eedress? That parameter is the address in EEPROM from which you’re reading. I don’t see where you are setting that value for the initial read in setup().