How to save sensor value in EEPROM? (ESP8266)?

Hi, I would like to save the height of a tank in case of power outage with EEPROM and every time I reboot the board. However, I could not do so after using EEPROM.commit() , EEPROM.read and EEPROM.write as the reading of the height tank changes every time I tried to reboot it . Am I using it wrongly?

How could I recalibrate the height of the tank if I would like to change to another tank one day, can I just click the RST button on the ESP8266 board?

Thank you

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
#define EEPROM_SIZE 1
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

WidgetLED led1(V2);


 
char auth[] = "";//Enter your Auth token
char ssid[] = "";//Enter your WIFI name
char pass[] = "";//Enter your WIFI password
 
BlynkTimer timer;
bool pinValue = 1;


long duration;
int distance; 
int percentage;
int addr=0;
float tankheight, val;

 
#define trig D7
#define echo D8
#define relay D5
 
void setup() {
  Serial.begin(9600);
  EEPROM.begin(EEPROM_SIZE);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(relay, OUTPUT);
  Wire.begin(D2, D1);
  lcd.init();
  lcd.backlight();
  Blynk.begin(auth, ssid, pass);
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  tankheight = duration * 0.034 / 2;
  Serial.print("Tank height");
  Serial.print(tankheight);
  EEPROM.write(addr, tankheight);
  EEPROM.commit();
  val=EEPROM.read(addr);
  Serial.print("Addr");
  Serial.print(val);
  timer.setInterval(1L, Wlevel);
  digitalWrite(relay, HIGH);
}
 


BLYNK_CONNECTED(){
  Blynk.syncAll();

  }
 
BLYNK_WRITE(V0) {
  pinValue = param.asInt();

}



void loop() {
  Blynk.run();
  timer.run();
  WiFi.setSleepMode(WIFI_NONE_SLEEP);

}

void Wlevel(){
  {
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = duration * 0.034 / 2;
  percentage= map(distance,val,10 ,0, 100);
 
  Blynk.virtualWrite(V1, percentage);  

  if(percentage<0)
  {
    percentage = 0;
  }
  else if(percentage>100)
  {
    percentage = 100;
  }

 }
  

 if (pinValue == 1)
    {
       if (percentage < 100)
       {
          digitalWrite(relay, LOW);
          Serial.print("Water level:");
          Serial.print(percentage);
          Serial.print("%");
          Serial.println(" Pump is ON");
          led1.on();
          lcd.setCursor(0,0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: ON  (AUTO)");
          
       } 
       
       else 
       {
          digitalWrite(relay, HIGH);
          Serial.println("Water level is 100%   Pump is OFF");
          led1.off();
          lcd.setCursor(0, 0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: OFF (AUTO)");
          
       }
    }
   else
    {
      digitalWrite(relay, HIGH);
      Serial.print("Water level:");
      Serial.print(percentage);
      Serial.print("%");
      Serial.println("System is OFF, Check Blynk");
      lcd.setCursor(0,0);
      lcd.print("Water Lvl:");
      lcd.print(percentage);
      lcd.print("%  ");
      lcd.setCursor(0,1);
      lcd.print("System is OFF   ");
      led1.off();
      
    }

   } code here

One obvious problem is that tankheight and val are declared as floats but EEPROM.write() writes a single byte and EEPROM.read() reads a a single byte

Take a look at EEPROM.put() and EEPROM.get()

Also, this needs to be adjusted accordingly.

Use:

const size_t eepromSize = sizeof(float);

I have tried to use EEPROM.put() and EEPROM.get() but I am getting error messages with

'template T& EEPROMClass::get(int, T&)'

and

no matching function for call to 'EEPROMClass::get(int&)'

This does not happen if I used EEPROM.write and EEPROM.read.

Still it does not save my previous tank height. As what I have found, I tried to use EEPROM.begin(512) but it still does not work.

Please post the full sketch that you tried

Sure... I have changed to EEPROM.begin(512) as what I have read from other forum.

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);


WidgetLED led1(V2);


 
char auth[] = "";//Enter your Auth token
char ssid[] = "";//Enter your WIFI name
char pass[] = "";//Enter your WIFI password
 
BlynkTimer timer;
bool pinValue = 1;


long duration;
int distance; 
int percentage;
int addr=0;
float tankheight, val;

 
#define trig D7
#define echo D8
#define relay D5
 
void setup() {
  Serial.begin(9600);
  EEPROM.begin(512);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(relay, OUTPUT);
  Wire.begin(D2, D1);
  lcd.init();
  lcd.backlight();
  Blynk.begin(auth, ssid, pass);
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  tankheight = duration * 0.034 / 2;
  Serial.print("Tank height");
  Serial.print(tankheight);
  EEPROM.put(addr, tankheight);
  EEPROM.commit();
  val=EEPROM.get(addr);
  Serial.print("Addr");
  Serial.print(val);
  timer.setInterval(1L, Wlevel);
  digitalWrite(relay, HIGH);
}
 


BLYNK_CONNECTED(){
  Blynk.syncAll();

  }
 
BLYNK_WRITE(V0) {
  pinValue = param.asInt();

}



void loop() {
  Blynk.run();
  timer.run();
  WiFi.setSleepMode(WIFI_NONE_SLEEP);

}

void Wlevel(){
  {
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = duration * 0.034 / 2;
  percentage= map(distance,val,10 ,0, 100);
 
  Blynk.virtualWrite(V1, percentage);  

  if(percentage<0)
  {
    percentage = 0;
  }
  else if(percentage>100)
  {
    percentage = 100;
  }

 }
  

 if (pinValue == 1)
    {
       if (percentage < 100)
       {
          digitalWrite(relay, LOW);
          Serial.print("Water level:");
          Serial.print(percentage);
          Serial.print("%");
          Serial.println(" Pump is ON");
          led1.on();
          lcd.setCursor(0,0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: ON  (AUTO)");
          
       } 
       
       else 
       {
          digitalWrite(relay, HIGH);
          Serial.println("Water level is 100%   Pump is OFF");
          led1.off();
          lcd.setCursor(0, 0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: OFF (AUTO)");
          
       }
    }
   else
    {
      digitalWrite(relay, HIGH);
      Serial.print("Water level:");
      Serial.print(percentage);
      Serial.print("%");
      Serial.println("System is OFF, Check Blynk");
      lcd.setCursor(0,0);
      lcd.print("Water Lvl:");
      lcd.print(percentage);
      lcd.print("%  ");
      lcd.setCursor(0,1);
      lcd.print("System is OFF   ");
      led1.off();
      
    }

   }

Your syntax for EEPROM.get() is not quite correct

EEPROM.put(addr, tankheight);
EEPROM.commit();
//val = EEPROM.get(addr);
EEPROM.get(addr,val);
Serial.print("Addr");
Serial.print(val);

Hmmm not sure if I understand it.....
Do you mean that the "val=EEPROM.get(addr);" is wrong ?

I am supposed to read back the tank height that I write into "addr", is this the problem?

I am just new to programming so I am trying to understand more programming jargon......

Thank you

Yes.

Two parameters are needed to call this function. The first is an int containing the address that is to be written, and the second is the object you would like to read from that address.

EEPROM.get(addr, val);

https://www.arduino.cc/en/Reference/EEPROMGet

The esp8266 uses an area of its flash memory to emulate an EEPROM, and because of that you need to add the EEPROM.begin(size) and EEPROM.commit() when using the EEPROM.h library with the esp8266.

Other than that modifcation, the standard EEPROM.h library syntax is supported by the Arduino core for the esp8266.

Since the ESPs don't actually have EEPROM (they simulate it using FLASH), I just store configuration data as text files in a SPIFFS or LittleFS filesystem. It's simple, and they are then human-readable.

Since your sketch determines the tank height based on a measurement in setup(), each time the ESP8266 resets it will automatically re-determine the tank height anyway. The way you're using the EEPROM currently doesn't improve anything about your system. Also notice you're not reading the EEPROM anywhere, nor do I see a logical need to do so given the measurement that's done on startup...

I have no clue to change the format of the code, could you guide me please?

The above comments explained it very clear. I suggest you google EEPROM. get and EEPROM. put. There are plenty of examples out there

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