Arduino Keeps crashing

Hi I think my code is off and causing a memory leak that is crashing my Arduino after a few days. can anyone see what is wrong with my code?

// Cooler than 20 degrees then fans on
#include <Wire.h>
#include "WiFiEsp.h"
#include "SoftwareSerial.h"
SoftwareSerial Serial1(9, 8); // RX, TX

char ssid[] = "Mainwifi";
char pass[] = "notforforum";
int status = WL_IDLE_STATUS;
int ledStatus = LOW; //CDB: Serves as a status for the fan on / off
int cTemp;
int cTemp2;
int humidity;
int humidity2;
int fTemp;
int fTemp2;
bool webpageOverride = false; //CDB: add a flag to see if we're in webpage override mode
unsigned long timeSinceOverrideStart; //CDB: variable to store how how long we've been in webpage override mode
unsigned long timeSinceLastCheck = 0; //CDB: millis since we've checked temperature

WiFiEspServer server(80);
RingBuffer buf(8);

#define Addr 0x44
#define Addr2 0x45
#define RelayControl1 4
#define RelayControl2 5
#define RelayControl3 6
#define RelayControl4 7
#define OverrideTimeLength 7200000 //CDB: how long, once we're in override mode, we want to stay in there. Currently 2 hours  7200000

void setup()
{
  Wire.begin();
  Serial.begin(9600);     //SH13
  Serial1.begin(9600);    // wifi
  // wifi START
  pinMode(LED_BUILTIN, OUTPUT);  // digital pin LED as an output.
  WiFi.init(&Serial1);
  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }
  while (status != WL_CONNECTED) {
    Serial.print("Connecting to: ");
    Serial.println(ssid);
    // Connect WPA/WPA2
    status = WiFi.begin(ssid, pass);
  }
  Serial.println("Connected :)");
  // Start port 80
  server.begin();

  pinMode(RelayControl1, OUTPUT);
  pinMode(RelayControl2, OUTPUT);
  pinMode(RelayControl3, OUTPUT);
  pinMode(RelayControl4, OUTPUT);
  digitalWrite(RelayControl1, HIGH);
  digitalWrite(RelayControl2, HIGH);
  digitalWrite(RelayControl3, HIGH);
  digitalWrite(RelayControl4, HIGH);

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop()

{ 
  WiFiEspClient client = server.available();  // listen clients
  if (client) {                               //  client?
    Serial.println("User");             // print
    buf.init();                               // circular buffer
    while (client.connected()) {              // loop user connected
      if (client.available()) {               // if bytes to read from the client,
        char c = client.read();               // read a byte, then
        buf.push(c);                          // push it to ring buffer
        // 2 newline is the end of the HTTP request,  send a response
        if (buf.endsWith("\r\n\r\n")) {
          sendHttpResponse(client);
          break;
        }
        // Check "GET /H" or "GET /L":
        if (buf.endsWith("GET /H")) {
          Serial.println("Turn Fan ON");
          ledStatus = HIGH;
          webpageOverride = true; //CDB: we now want to ignore the sensors, so don't listen to them.
          timeSinceOverrideStart = millis(); //CDB: store when we entered webpage override
          
          digitalWrite(RelayControl3, LOW);
          // digitalWrite(LED_BUILTIN, HIGH);   // turn the fan
        }
        else if (buf.endsWith("GET /L")) {
          Serial.println("Turn Fan OFF");
          ledStatus = LOW;
          webpageOverride = true; //CDB: we now want to ignore the sensors, so don't listen to them.
          timeSinceOverrideStart = millis(); //CDB: store when we entered webpage override
          
          
          digitalWrite(RelayControl3, HIGH);   // turn the fan
        }
      }
    }

    // close the connection
    client.stop();
    Serial.println("Client disconnected");
  }
//DELAY THE SENSING WAS 1000 NOW CHANGED TO 60000
  if (millis() - timeSinceLastCheck > 60000){
    timeSinceLastCheck = millis();
    
    printDataCollected();
    if (webpageOverride){
      //CDB: At this point, we just want the fan to be on. So we do nothing :-)
      if (millis() - timeSinceOverrideStart > OverrideTimeLength) {
        webpageOverride = false; //CDB: If we've been in webpage override for longer than the time we want, stop, and switch back to the sensors.
      }
    } else {
      sensorDecisions(); //CDB: run the temperature / humidity checking algorithm
    }
  }
}

void sendHttpResponse(WiFiEspClient client)

{

  // HTTP headers
  client.println("HTTP/1.1 200 OK");
  client.println("Content-type:text/html");
  client.println();
  client.print("<span id=\"T1\">");
  client.print("The Fan is ");
  client.print("<p5>");
  client.print(ledStatus);
  client.print("</p5>");
  client.println("<br>");
  client.println("Lounge_Temp");
  client.println("<div class=\"LoungeTemp\">");
  client.print("<p1>");
  client.println(cTemp);
  client.print("</p1>");
  client.println("Loft_Temp");
  client.print("<p2>");
  client.println(cTemp2);
  client.print("</p2>");
  client.println("Lounge_Humidity");
  client.print("<p3>");
  client.println(humidity);
  client.print("</p3>");   
  client.println("Loft_Humidity");
  client.print("<p4>");
  client.print(humidity2);
  client.print("</p4>");
  client.print("end");
  client.print("</span>");
  client.println("<br>");
  client.println("Click <a href=\"/H\">here</a> turn the Fan on<br>");
  client.println("Click <a href=\"/L\">here</a> turn the Fan off<br>");
  //  HTTP  ends
  client.println();
}

void sensorDecisions(){
  //CDB: I've broken out the bit that reads the temperature / humidity from the bit that decided what to do with it, so we can still have accurate temperature / humidity readings,
  //even when we're in website override
 if ((20 > cTemp2 ) && (humidity > humidity2 ))
    {
      Serial.println("**** RELAYS ON Temp Higher (withing 2 deg) in loft humidity in loft lower ****");
      digitalWrite(RelayControl1, LOW);
      digitalWrite(RelayControl2, LOW);
      digitalWrite(RelayControl3, LOW);
      digitalWrite(RelayControl4, LOW);
      ledStatus = HIGH; //CDB: update the fan state
    }

    if ((20 < cTemp2 ) && (humidity < humidity2 ))
    {
      Serial.println("Relays off temp ok but humid in loft ");
      digitalWrite(RelayControl1, HIGH);
      digitalWrite(RelayControl2, HIGH);
      digitalWrite(RelayControl3, HIGH);
      digitalWrite(RelayControl4, HIGH);
      ledStatus = LOW; //CDB: update the fan state
    }


    if ((20 > cTemp2 ) && (humidity < humidity2 ))
    {
      Serial.println("Relays Off too cold and too humid in loft");
      digitalWrite(RelayControl1, HIGH);
      digitalWrite(RelayControl2, HIGH);
      digitalWrite(RelayControl3, HIGH);
      digitalWrite(RelayControl4, HIGH);
      ledStatus = LOW; //CDB: update the fan state
    }


   if ((20 > cTemp2 ) && (humidity < humidity2 ))
    {
      Serial.println("Relays off too cold in loft humidity ok  Change");
      digitalWrite(RelayControl1, HIGH);
      digitalWrite(RelayControl2, HIGH);
      digitalWrite(RelayControl3, HIGH);
      digitalWrite(RelayControl4, HIGH);
      ledStatus = LOW; //CDB: update the fan state
    }
}

void printDataCollected()
{

  unsigned int data[6];

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Send 16-bit command byte
  Wire.write(0x2C);
  Wire.write(0x06);
  // Stop I2C transmission
  Wire.endTransmission();
  // delay(300);

  // Request 6 bytes of data
  Wire.requestFrom(Addr, 6);

  // Read 6 bytes of data
  // temp msb, temp lsb, temp crc, hum msb, hum lsb, hum crc
  if (Wire.available() == 6)
  {
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
  }

  //second write and read

  {
    unsigned int data2[6];

    // Start I2C Transmission
    Wire.beginTransmission(Addr2);
    // Send 16-bit command byte
    Wire.write(0x2C);
    Wire.write(0x06);
    // Stop I2C transmission
    Wire.endTransmission();
    //  delay(300);

    // Start I2C Transmission
    Wire.beginTransmission(Addr2);
    // Stop I2C Transmission
    Wire.endTransmission();

    // Request 6 bytes of data
    Wire.requestFrom(Addr2, 6);

    // Read 6 bytes of data
    // temp msb, temp lsb, temp crc, hum msb, hum lsb, hum crc
    if (Wire.available() == 6)
    {
      data2[0] = Wire.read();
      data2[1] = Wire.read();
      data2[2] = Wire.read();
      data2[3] = Wire.read();
      data2[4] = Wire.read();
      data2[5] = Wire.read();

    }

    // Convert the data
    int temp = (data[0] * 256) + data[1];
    cTemp = -45.0 + (175.0 * temp / 65535.0);
    fTemp = (cTemp * 1.8) + 32.0;
    humidity = (100.0 * ((data[3] * 256.0) + data[4])) / 65535.0;

    int temp2 = (data2[0] * 256) + data2[1];
    cTemp2 = -45.0 + (175.0 * temp2 / 65535.0);
    fTemp2 = (cTemp2 * 1.8) + 32.0;
    humidity2 = (100.0 * ((data2[3] * 256.0) + data2[4])) / 65535.0;

    Serial.print("Temp     :");
    Serial.print(cTemp);
    Serial.print(" c     ");
    Serial.print("Temp2      :");
    Serial.print(cTemp2);
    Serial.println(" c  (loft)");
    Serial.print("humidity :");
    Serial.print(humidity);
    Serial.print(" %     ");
    Serial.print("humidity2  :");
    Serial.print(humidity2);
    Serial.println(" %  (loft)");
  }
}

This does not look right:

RingBuffer buf(8);

Please link to the RingBuffer library used..

it's been a while since i did web stuff, but shouldn't you recognize the connection of a client and send a page when that occurs and then separately process a response (e.g. "GET") from the client?

can you use Serial.readBytesUntil()

Hi as usual these forums pose more questions than answers. it is a long time ago since i wrote/plagerised this code. and on the whole it works for a while.
Im not quite sure how the ring buffer works. i think it was to keep it listening for the /H so that the fans could be turned on. so i guess this constant looping can be causing the issue but that is sort of the point of the ringbuffer so i "listens" for the connection and then drops out the loop when it is requested.
I will have a look at serial read and see ho i can work it into the code

Is this code trying to use the ESP32's ringbuffer?

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos_additions.html

If so a lot more code is needed to get the ESP32's freeRTOS ringbuffer to work.

Exactly what is "Arduino" in this case? ESP8266? Memory leak is hardly your problem, if you are using an ESP. WiFi may loose the connection after some time, so you might want to check the status of the WiFi connection and if disconnected then reconnect.

Even if the ESP32's freeRTOS ringbuffer is being used wrongly?

There is no evidence of that being the case, so that would be speculative. For now, I'm assuming the RingBuffer Arduino library is used even though it is not included in the posted source code.

You only connect and check the connection once, during setup.

Consider breaking out the connection code into its own function. Then check the connection status at the beginning of the loop function. If it's not connected, then run the connection function again.

Hi i like this. looks like it might help. I will give a try and report back

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