Esp8266 wemosd1 mini Fridge Thermostat

Im currently trying to build a fridge thermostat. Im using a similar code that i used for an hvac controler.
The issue is that im saving my laterst settings to the eprom and works very well up until im using a negative value as my setpoint. the moment i use a negative value and restarts the esp8266 wemos d1 mini it returns the setpoint to 255 and so forth but if i use 0 or any other positive value it works just fine
Cant seem to work this out so i decided to ask for help.

Im using an wemos d1 mini board with a ds18b20 temp sensor and a relay module. my code follow:

#include <BlynkSimpleEsp8266.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ArduinoOTA.h>
 
#define UpdateFrequency (60 * 1L)  //How often a new temperature will be read
#define RelayPin D1
#define ONE_WIRE_BUS D2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Timer for temperature updates
BlynkTimer timer;

//WiFi and Blynk connection variables
char auth[] = "****************"; // Blynk token 

//Thermostat variables
int TempDes = 2; //Desired temperature setting
int PreviousTempDes;
int TempAct = 70; //Actual temperature, as measured by the DS18B20 sensor
int LastRead = 2; 

// Preference variables
int Hysteresis_C = 5;
int TempCorrection = 0; //Used to adjust readings, if the sensor needs calibration

// Current condition variables
boolean Cooling = true; //default is false
boolean FanState = 0; // is the fan on or off?

bool Connected2Blynk = false;

void Uptime()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V6, millis() / 1000);
}

void setup() {
  Serial.begin(9600);
  delay(10);
  
  //Creates an AP if no wifi credentials are stored
  WiFiManager wifi;
  wifi.autoConnect("DindoGeladeira"); 
//  delay(30);  
  Blynk.config(auth);  // in place of Blynk.begin(auth, ssid, pass);
  Blynk.connect(3333);  // timeout set to 10 seconds and then continue without Blynk
  while (Blynk.connect() == false) {}
    // Wait until connected
  Serial.println("Connected to Blynk server");
  ArduinoOTA.setHostname("DindoGeladeira"); 
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
    
  //Initialize the fan relay. Mine is "off" when the relay is set LOW.
  pinMode(RelayPin,OUTPUT); 
  digitalWrite(RelayPin,LOW);

  
  //Load any saved settings from the EEPROM
  EEPROM.begin(20);  
  Serial.println(F("STARTUP : LOADING SETTINGS FROM MEMORY"));
  Serial.println(F(""));
  GetPresets();

  PreviousTempDes = TempDes; 
  
  //MenuReset();

  timer.setInterval(UpdateFrequency, TempUpdate); // Update temp reading and relay state
  timer.setInterval(UpdateFrequency, Uptime); // Update temp reading and relay state
}

//******************************************************************************************************************************************************

// Main loop
void loop() {
  Blynk.run();
  timer.run();
  ArduinoOTA.handle();
}


//******************************************************************************************************************************************************

bool isFirstConnect = false; // Keep this flag not to re-sync on every reconnection

// This function will run every time Blynk connection is established
BLYNK_CONNECTED() {
  if (isFirstConnect) {
    // Request Blynk server to re-send latest values for all pins
    Blynk.syncAll();

    isFirstConnect = false;
  }
}


void CheckConnection(){
  Connected2Blynk = Blynk.connected();
  if(!Connected2Blynk){
    Serial.println("Not connected to Blynk server"); 
    Blynk.connect(3333);  // timeout set to 10 seconds and then continue without Blynk  
  }
  else{
    Serial.println("Connected to Blynk server");     
  }
}


// This is the decision algorithm for turning the HVAC on and off
void TempUpdate (){
    {
  OtherUpdates(); //Refeshes dashboard information
  sensors.requestTemperatures();                  // Polls the sensors.
  TempAct = sensors.getTempCByIndex(0);   // Stores temperature. Change to getTempCByIndex(0) for celcius.
  Blynk.virtualWrite(V0, TempAct);         // Send temperature to Blynk app virtual pin 0.
  Serial.print(F("Actual temperature: "));
  Serial.println(TempAct);
}
// Decision algorithm for running HVAC
if (Cooling)
        //If I'm home, it's Summer, and the temp is too high, turn the relay ON
        if (TempAct >= TempDes + (Hysteresis_C)){
          FanState = 1;
          Fan();
        }
        //Turn it off when the space is cooled to the desired temp - a few degrees
        else if (TempAct <= TempDes  && FanState){
          FanState = 0;
          Fan();
        }
     }

//Match temp gauge to slider in Blynk app 
BLYNK_WRITE(V3){
  TempDes = param.asInt();
  Blynk.virtualWrite(V1,TempDes);
}

// Updates dashboard information on the Blynk app
void OtherUpdates(){
  Blynk.virtualWrite(V1,TempDes); //Update desired temp on the dashboard   
   if (TempDes != PreviousTempDes){ //update the EEPROM if desired temperature had changed.
    EEPROM.write(3,TempDes);
    EEPROM.commit();
    Serial.print(F("New desired temperature saved: "));
    Serial.println(TempDes);
    PreviousTempDes = TempDes;  
   }
}
// Turn the HVAC on or off
    void Fan(){
      digitalWrite(RelayPin,FanState); // Relay turns fan on with LOW input, off with HIGH
      Blynk.virtualWrite(V7,FanState * 1023);// fan "ON" LED on dashboard
      Blynk.virtualWrite(V8,HIGH);// fan "ON" Graph
      Serial.print(F("Fan state: "));
      Serial.println(FanState);
    }

    
//Retrieves saved values from EEPROM
void GetPresets(){
{
  TempCorrection = EEPROM.read(0);
  if ((TempCorrection < 0) || (TempCorrection > 10)){
    TempCorrection = 0;
    Serial.println(F("No saved temperature correction."));
  }
  else{
    TempCorrection -= 5; // 5 was added at EEPROM save to account for negative values
    Serial.print(F("Temperature correction: "));
    Serial.print(TempCorrection);
    Serial.println(F(" degrees."));      
  }

  Cooling = EEPROM.read(4);
  Hysteresis_C = EEPROM.read(2);
  if ((Hysteresis_C < 0) || (Hysteresis_C > 2)){
      Hysteresis_C = 5;
  }
  
  if (Cooling){
    Serial.println(F("Season setting: Cooling / heating"));
    Serial.print(F("Cooling hysteresis: "));
    Serial.print(Hysteresis_C);
    Serial.println(F(" degrees."));   
    
  TempDes = EEPROM.read(3);
  if ((TempDes < 0)){
    TempDes = 0;
    Serial.println(F("No saved temperature setting."));
  }
  else {
    Serial.print(F("Desired temperature: "));
    Serial.print(TempDes);
    Serial.println(F(" degrees."));   
  }
  Serial.println("");
     }
  }
}

Hope to find some light on this. Cant seem to find a workaround.

The problem is the type of variable that you’re using, but rather than trying to fix this problem, you should stop using EEEPROM and switch to either SPIFFS or LittleFS to store this data (or use Blynk to store these values and reft5rieve them via a Blynk.syncVirtual command).

EEPROM memory has a predicted life of around 100,000 read/write operations. You are potentially writing to EEPROM memory 16 times per second (more about that later), so if your temperature changes slightly between readings (which it won’t, as you’re using integers as your temperature variables - bore about that later too), you could kill your EEPROM within 10,000 seconds (2.8 hours).

SPIFFS was the replacement for EEPROM, but is now in ‘Maintenance only’ mode.

LittleFS is the current supported file storage system for the ESP8266/ESP32.

Blynk could be used to store data, but it can only be used if the Blynk server is accessible. In your situation, it would probably be better to use LittleFS.

Timer Frequency

Your update frequency is 60ms (60 x 1 = 1) and BlynkTimer measures its timing frequency in milliseconds. This means that both timers will attempt be called at precisely the same time, 16 times per second. As you are using a single-threaded processor, only one of these functions can actually be processed at any one time, so TempUpdate will execute, then Uptime will execute next time the void loop is processed.
Both of these functions contain Blynk.virtualWrite commands.

TempUpdate contains one Blynk.virtualWrite and calls OtherUpdates which also contains one Blynk.virtualWrite and conditionally calls Fan which contains two Blynk.virtualWrite commands

Uptime contains one Blynk.virtualWrite commands.

This means that you are attempting to do five Blynk.virtualWrite commands every 60ms, or 80 Blynk.virtualWrites per second.
Attempting to do more than 10 Blynk.virtualWrites per second, or one Blynk.virtualWrite every 10ms will cause problems. I assume that your simultaneous overlapping timers, and the restrictions coded into BlynkTimer are preventing you from flooding the Blynk server and being disconnected.

Variable Types and Hysteresis

You’ve chosen to use integers for your variable types, which means that your refrigerator has a maximum resolution of +/- 1 degree Celsius.

If your target temperature is 2 degrees then it has to rise to 3 degrees or fall to 1 degree before there is a difference between the actual and target temperatures.
However, your badly written TempUpdate function uses >= and <= operators, so its only the hysteresis value which prevent both if statements from being true.
Your hysteresis value is only used in your decision to switch the cooling mechanism on (despite your comments that indicate calling the Fan function with FanState = 1 will turn your relay off). As your Hysteresis_C value is set to 5, the cooling mechanism will turn on when the temperature in the fridge is 7 degrees above target, and off when it is exactly at the target temperature.

Hope this helps!

Pete.

1 Like

Good afternoon Pete

Thank you so much for your response. This actually helps alot yes. I will redo the coding to adapt to LittleFS for sure. I did not know this will kill my eprom since im no expert in this area and only like building arduino projects for own use purposes.

I will redo my coding and try to post it back here. I have e similar project that already uses littleFS for my garage door. So i think I might be able to to this.

Thanks again
Max Daniller

LittleFS write the data to different places. I have been writing to littleFS every second for two years. 65 million writes and I still haven’t destroyed my device.

1 Like