The use of the ESP8266 in the world of IoT

User avatar
By Rawest
#70817 Below is my code for a sketch that includes multiple GET and a POST request to my server in order to operate a temperature controller with a relay. After a few days, the nodeMCU just stops posting the temperature to the server.

Code: Select all
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <TextFinder.h>
#include <String.h>
//include this library for MAC address reassigning. (For Hotel WiFi)
extern "C" {
  #include <user_interface.h>
}

//Use this to reassign mac address of the ESP8266 (Hotel WiFi)
bool wifi_set_macaddr(uint8 if_index, uint8 *macaddr);

// Data wire is plugged into pin 2
#define ONE_WIRE_BUS D1

//Pass oneWire intance to communicate with any oneWire devices
OneWire oneWire(ONE_WIRE_BUS);

//Pass oneWire reference to Dallas Temperature
DallasTemperature sensors(&oneWire);

WiFiClient client;
TextFinder finder( client );

const char* ssid = "ATT6VMY3cI";
const char* password = "6de7yde5umi3";


const char* host     = "www.smallbatchbru.com"; // Your domain 

bool debugging = true; //whether or not we want to print to the serial port

float f; //current fermentation temp
int setVal; //the value retrieved from setFromSQL.html and desired temp
int highDifference = 2;//desired high and low temp range
int lowDifference = 2;
unsigned long compDelay = 600000; //compressor delay in milliseconds
unsigned long lightLastOff = 0; // used in compressor delay timer
int outOfRange = 70; //Used for sending the email through IFTTT if the temp gets too high inside

int relayPin = D2; //the relay

bool executed = false; //keep track of the sendEmail function to only run once

void setup() {
 
  digitalWrite(D1, HIGH);
  pinMode(D1, OUTPUT);
  Serial.begin(115200);
  pinMode(D4, OUTPUT);

  pinMode(relayPin, OUTPUT);

  // Start with the built-in LED off
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  delay(50);

  // Start up the library for the sensor
  sensors.begin();

  delay(50);

  //Reassign the MAC address to my iPhone address (for Hotel WiFi)
  //uint8_t mac[6] {0x7c, 0x04, 0xd0, 0x17, 0x23, 0x6F};
  //wifi_set_macaddr(STATION_IF, mac);
  //WiFi.hostname("DicksESP");

  WiFiConnect();

}

void loop() {

  delay(100);

  testConnection(); //If the WiFi was interrupted, re-connect to the AP

  delay(2000);

  callTemperatures(); //Call the temperatures from the DS18b20 sensor

  delay(2000);

  getSetTemp(); //GET request that retrieves the temperature from the SQL database

  delay(2000);

  compressorControl(); //Determine whether or not to turn the fridge on or off. There is a 10 minute compressor delay built in

  delay(1000);

  postTemp(); //POST the temperature from the sensor to a PHP file and then to the site

  delay(2000);

  sendEmail(); //Send an email through IFTTT if the fridge is out of the set range.

  delay(2000);
 
}

void WiFiConnect() {

  if (debugging) {
    Serial.print("Connecting to ");
    Serial.println(ssid);
  }

  // Connect to the WiFi access point
  WiFi.begin(ssid, password);
 
  /*While the WiFi is not connected, print some periods in half
   * second intervals and turn off the light
   */
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    if (debugging) {
      Serial.print(".");
    }
  }
  if (debugging) {
    Serial.println("WiFi connected"); 
    Serial.println("IP address: " + WiFi.localIP());
  }

  /*Turn on the light once the WiFi is connected*/
  digitalWrite(LED_BUILTIN, LOW);
 
}

void testConnection() {

  // If the WiFi isn't connected, re-connect the WiFi
  if (WiFi.status() != WL_CONNECTED) {

    digitalWrite(LED_BUILTIN, HIGH);
    WiFiConnect();
   
  }
 
}

void callTemperatures() {

  if (debugging) {
    Serial.println("Requesting temperartures...");
  }
  sensors.requestTemperatures();
  if (debugging) {
    Serial.println("DONE");
    Serial.print("Temperature for the device 1 (index 0) is: ");
    Serial.println(sensors.getTempFByIndex(0));
   }
  f = sensors.getTempFByIndex(0);
}

void compressorControl() {

  /* If the temperature from the probe is less than or equal
   *  to the set value, then turn the compressor off
   */
 
  if (f <= setVal - lowDifference) {
    digitalWrite(relayPin, LOW);
    digitalWrite(D4, LOW);
  }

  /* Not really necessary, but I assigned the
  current time to millis to help visually keep track of current millis */
 
  unsigned long currentMillis = millis();

  /* If the temperature from the probe is greater than the set value AND it has been more than 10 minutes
   *  since the compressor last shut off; then turn the compressor back on
   */
   
  if ((f > setVal + highDifference) && (currentMillis - lightLastOff) >= compDelay) {
    lightLastOff = millis();
    digitalWrite(relayPin, HIGH);
    digitalWrite(D4, HIGH);
  }
  if (debugging) {
    Serial.print("Setting in compressor control: ");
    Serial.println(setVal);
    Serial.println();
  }
 
}

void postTemp() {
 
    String temp = "f=";
    String currentData = temp+f;
 
    if (client.connect("www.smallbatchbru.com", 80)) {
    if (debugging) {
      Serial.println("Connected to POST");
    }
    client.println("POST /controller/fermTempPHP.php HTTP/1.1");
    client.println("Host: www.smallbatchbru.com");
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(currentData.length());
    client.println();
    client.print(currentData);
   }   else {
      if (debugging) {
        Serial.println("POST connection failed");
      }
    }
  if (!client.connected()) {
   if (debugging) {
    Serial.println();
    Serial.println("disconnecting.");
   }
  }

  client.flush();

  client.stop();

}

void getSetTemp() {

  if (client.connect("www.smallbatchbru.com", 80)) {
    if (debugging) {
      Serial.println("Connected...getting SQL value");
    }
    client.println("GET /controller/setFromSQL.html HTTP/1.1");
    client.println("Host: www.smallbatchbru.com");
    client.println("Connection: close");
    client.println();
  } else {
      if (debugging) {
        Serial.println("Connection to get SQL value failed");
      }
    }

  if (client.connected()) {
     finder.find("<p>");
     setVal = finder.getValue();
     if (debugging) {
      Serial.print("The temperature setting from the database is: ");
      Serial.println(setVal);
     }
  }  else {
       if (debugging) {
        Serial.println("Client not available");
       }
    }

  if (!client.connected()) {
    if (debugging) {
      Serial.println();
      Serial.println("disconnecting");
    }
    client.flush();
    client.stop();
    while (true);
  } 
}

/*
void sendEmail() {

  if (f > outOfRange && executed == false) {
    if (client.connect("maker.ifttt.com", 80)) {
      if (debugging) {
        Serial.println("Connected to Maker Webhooks");
      }
      client.println("POST /trigger/out_of_range/with/key/mv8BNkmZZIGrhCF9aUFtaBFJ_xys-L0d3pF1VCQ7rFa HTTP/1.1");
      client.println("Host: maker.ifttt.com");
      client.println("Connection: close");
      client.println();
    } else {
      if (debugging) {
        Serial.println("Could not connect to Maker WebHooks");
      }
    }

  if (!client.connected()) {
      if (debugging) {
        Serial.println();
        Serial.println("disconnecting");
      }
      client.flush();
      client.stop();
      while (true);
    }

   executed = true;
   
  }
 
}
*/

User avatar
By Rawest
#70964
philbowles wrote:CAVEAT: i haven't looked at your code, but a few general pointers might help:

a) timer overflow. Try to get a handle on EXACTLY how many seconds "a few days" is...does the number look strangely familiar?
b) possible slow memory leak. sprinkle some print functions showing the value of ESP.getFreeHeap() at strategic points...or in a (say) 30minute timer call. IS the value going steadily down? If you, u got leaks
c) most likely (and hardest to find, hardest to fix) heap fragmentation...you may well need to overhaul your code and/or do a strategic reboot at certain intervals (dirty, but works...)

hope this point you in the right direction


Thanks! I’ll add a reboot for now and start looking for leaks