1

I've search on how to do statistic calculation in EEPROM, but non related. The data that I stored in EEPROM is body temperature. Currently I stored the data using float.

Below is my code for data store in eeprom. I'm stuck at the void function named "printTemp". I know how to calculate average in array using for loop statement, but not EEPROM. From average/mean, I can find standard deviation.

Does anyone have an idea on how can we do calculation using data from EEPROM?

#define LM35 A1
#define READSAMPLES 100

float bt;
int buttonPin1 = D5;     // the number of the pushbutton pin 1 MEASURE
int buttonPin2 = D6;     // the number of the pushbutton pin 2 RESET CYCLE
int buttonState = 0;         // variable for reading the pushbutton status
int ButtonState = 0;         // variable for reading the pushbutton status
int address = 0;      //EEPROM address counter
int count, counT;
int sample[READSAMPLES];

void setup() {

    int contCount = EEPROM.get(5, count) / 10;

}

void loop() {

  buttonState = digitalRead(buttonPin1);
  ButtonState = digitalRead(buttonPin2);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == LOW) { 
        Serial.println("Measuring your Body Temperature:");

        count = counting();
        counT = count / 10;
        Serial.print("Data count entering: ");
        Serial.println(counT);

        writeTemp(); 
  }

  if (ButtonState == LOW) {

        Serial.println("Update New Cycle of body temp..."); 
        printTemp();
        clearEEPROM();
        Particle.publish("DONE new Cycle");

  }

}


void printTemp()
{
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    float cel = EEPROM.read(i);                //read EEPROM data at address i
    //How to find MEAN of all data?
  }
}

void clearEEPROM()
{
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    if(EEPROM.read(i) != 0)                     //skip already "empty" addresses
    {
      EEPROM.write(i, 0);                       //write 0 to address i
    }
  }
  Serial.println("EEPROM erased");
  address = 0;                                  //reset address counter
}

void writeTemp()
{
  //getting the voltage reading from the temperature sensor
  int j;
  float average;
  for (j = 0; j < READSAMPLES; j++)
  {
    sample[j] = analogRead(LM35);        //read sensor value
    delay(50);
  }

  average = 0;
  for (j = 0; j < READSAMPLES; j++)
  {
    average += sample[j];
  }
  average /= READSAMPLES;

  //float mv = ( average / 4096.0) * 3300;
  //float cel = ( mv / 10 ) - 55.01;
  float mv = ( average / 1024.0) * 5000;
  float cel = ( mv / 10 );

  EEPROM.write(address, cel);         //write value to current address counter address

  Serial.print("Sensor value stored at address ");
  Serial.println(address);

  address++;                      //increment address counter
  if(address == EEPROM.length())  //check if address counter has reached the end of EEPROM
  {
    address = 0;              //if yes: reset address counter
  }
}

float counting()
{
  count = count + 10;   // plus 10 is because to give a space for data entering the eeprom for LATER CODE. Just live it here.
    Particle.publish("Start Count =", String(count));
  return count;
}

What I can share from my problem findings are, to do the calculation of statistic from EEPROM data;

  1. we need to know how to read back all the data in EEPROM. As in my code I know how to read the data, but the data cannot be hold because in FOR loop the the process will running until the end of 'i'.
  2. we need to know how many data are there in EEPROM that have entered. To solve this, I'm using count; in order to count the entering data.

I need suggestion links or maybe any idea on how to do statistics in EEPROM.

Thanks.

2 Answers 2

0

Doing that calculation from EEPROM is exactly the same as doing it from any other source. You have a count so you know where the EEPROM data ends. You know where the EEPROM data starts. You know how to read a number out of EEPROM. What is stopping you from creating a for loop to read the i'th address from EEPROM and add all those numbers together just like you would for an array?

for (int i = EEPROM_START; i < EEPROM_END; i++){
   sum = sum + EEPROM.read(i);
}
average = sum / count;

where EEPROM_START and EEPROM_END are supplied by you by knowing what address you started and ended writing at.

0

There are quite a few issues with your program. Averaging is just one of them.

You wrote:

Currently I stored the data using float.

No, you didn't. You stored 8-bit unsigned integers (aka uint8_t).

int contCount = EEPROM.get(5, count) / 10;

Assuming you are using an 8-bit Arduino, this is reading the EEPROM cells at addresses 5 and 6, combining these two readings into a single signed 16-bit number, and storing it in count. Given that these EEPROM cells are also used to store temperature readings, this operation makes no sense at all. BTW, the line above also stores a copy of the newly updated count into a fresh local variable that gets immediately discarded. This also makes no sense.

Later you wrote:

for (int i = 0 ; i < EEPROM.length() ; i++) {
  if(EEPROM.read(i) != 0)  //skip already "empty" addresses
  {
    EEPROM.write(i, 0);    //write 0 to address i
  }
}

There is an EEPROM.update() method meant to do this in a simpler way:

for (int i = 0 ; i < EEPROM.length() ; i++) {
  EEPROM.update(i, 0);  //write 0 to address i unless it is already 0
}

Later:

for (j = 0; j < READSAMPLES; j++)
{
  sample[j] = analogRead(LM35);        //read sensor value
  delay(50);
}

There is no point in storing all the readings in RAM just to compute the average. You can get rid of the sample array and instead:

float average = 0;
for (int j = 0; j < READSAMPLES; j++)
{
  average += analogRead(LM35);  //read sensor value
  delay(50);
}
average /= READSAMPLES;

Later:

float cel = ( mv / 10 );
EEPROM.write(address, cel);
[...]
address++;

This is probably your biggest issue. You may believe you are storing floats, yet EEPROM.write() can only write bytes. Thus the value cel, which is a voltage in centivolts, is implicitly casted to a uint8_t. This means it is rounded down to the nearest integer below it, then wrapped modulo 256. This is quite likely not what you want.

If you really want to store floats, you should replace the last two lines of code above by

EEPROM.put(address, cel);
address += sizeof cel;

but then beware that when reading the EEPROM you should also increment the address in steps of sizeof(float).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.