Stability issues Arduino

I’m currently working on a “smarthome” interface to control my shutters, lights and so on over the internet with the use of a MySQL database.

This sketch is the “middleman” between the MySQL database on the one hand (which is being accessed by my smartphone) and another Arduino that is responsible of activating my devices via radio on the other hand (either by receiving UDP packets directly or through the middleman - MySQL database).

Everything works fine but after I guess 1-2 days by “middleman” Arduino keeps crashing. Can someone have a look over my sketch and find some flaws that could cause memory issues?

Much appreciated.

#include <WiFiClient.h>

#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>






const char* ssid = "UM";

const char* passa = "xxxx";
char user[] = "xxxxx";               
char password[] = "xxxxxx";
IPAddress server_addr(35, 157, 16, 43);
WiFiUDP Udp;
unsigned int localUdpPort = 4210;// local port to listen on
unsigned int remoteUdpPort = 4210;// local port to listen on
char incomingPacket[255];// buffer for incoming packets
int abfragemysql = 0;
int statusabfrage = 0;
IPAddress ipa(192, 168, 178, 97);
char statuscheck[14];
WiFiClient client;
MySQL_Connection conn((Client *)&client);


int licht;
int rollade;
int markise;
int tuer;
int esplicht = 9;
int erlaubemysql = 0;
int frage = 9;  
int esponline;
int lichtesp = 9;
int rolladeesp = 9;
int markiseesp = 9;
int tueresp = 9;
int responseandroid;
char status1[0];

char status3[0];
char status4[0];
char mysqlbestaetigung[] = "9";
int neungesendet = 0;



void setup() {
  
  Serial.begin(9600);
  WiFi.begin(ssid, passa);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  
  Udp.begin(localUdpPort);
}




void loop() {
  if (WiFi.status() != WL_CONNECTED)
  {
    WiFi.begin(ssid, passa);
  }

yield();
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    esponline = 1;
    // receive incoming UDP packets
    
    int len = Udp.read(incomingPacket, 255);
    if (len > 0)
    {
      incomingPacket[len] = 0;
       

    }
  erlaubemysql = 1;
 
    statuscheck[0] = incomingPacket[0];
    statuscheck[1] = incomingPacket[1];
    statuscheck[9] = incomingPacket[9];
    Serial.println("Statuscheck9");
    Serial.print(statuscheck[9]);
 if(incomingPacket[1]=='1')
{
   lichtesp=1;
   status1[0] = '1';

}
else if(incomingPacket[1]=='0')
{
  lichtesp=2;
  status1[0] = '2';
}


if(statuscheck[9]== 'a')
{
    rolladeesp = 3;
   
    Serial.println(rolladeesp);
     
  }
  else if (statuscheck[9] == '0')
   {
     rolladeesp = 4;
     Serial.println(rolladeesp);
    
   }






   
  
     incomingPacket[2];
     incomingPacket[3];
     incomingPacket[4];
     incomingPacket[5];
     incomingPacket[6];
  
     incomingPacket[7];
     incomingPacket[8];
   

     incomingPacket[10];
     incomingPacket[11];
     incomingPacket[12];
     incomingPacket[13];
    


    
    Serial.print(statuscheck);
   

  mysqlsenden();
  }


















  if (statusabfrage > 340)
  {
    Serial.printf("Statusabfrage gesendet");
    statusabfrage = 0;
    unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("qx");
    Udp.endPacket();
    yield();
  }




  delay(50);
  statusabfrage++;
  abfragemysql++;
  if (erlaubemysql == 1 && abfragemysql > 340) {
    mysqlabfrage();
  }
}



void mysqlabfrage(){

int head;

  erlaubemysql = 0;
  abfragemysql=0;
 

  if (conn.connect(server_addr, 3306, user, password)) {
     
  row_values *row = NULL;
  char query[] = "SELECT statuss FROM sql11215113.homecontrol";
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  cur_mem->execute(query);
  column_names *cols = cur_mem->get_columns();
do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
  
        head = atoi(row->values[0]);
        responseandroid = (head) % 10; 
        tuer = (head / 10) % 10;
        markise = (head / 100) % 10;
        rollade = (head / 1000) % 10;
        licht = (head / 10000) % 10;
           
    }
  }
  while (row != NULL);
    conn.close();
   
   delete cur_mem;
  

if(rollade == 3 && rolladeesp == 4){
  //ROLLADEN RUNTER
 neungesendet = 1;
statusabfrage = 0;
 for(short z = 0; z < 3; z++){
  

  Serial.println("Fahre Rolladen runter");
 
   unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("vd");
    Udp.endPacket();
    delay(100);
 
    
   }
   delay(200);
      unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("qx");
    Udp.endPacket();
   
   delay(200);

  
}



if(rollade == 4 && rolladeesp == 3){
  //ROLLADEN HOCH
 neungesendet = 1;
 statusabfrage = 0;
 for(short z = 0; z < 3; z++){
  

  Serial.println("Fahre Rolladen hoch");
  
   unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("vu");
    Udp.endPacket();
    delay(100);
   
    
   }
   delay(200);
      unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("qx");
    Udp.endPacket();
   
   delay(200);

  
}









if(licht == 1 && lichtesp == 2){
  //SCHALTE LICHT AN
 neungesendet = 1;
statusabfrage = 0;
 for(short z = 0; z < 4; z++){
  

  Serial.println("Schalte Licht an");
  Serial.print(licht&&lichtesp);
   /*unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("x");
    Udp.endPacket();
    */
    delay(200);
    
    
   }
    
      unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("qx");
    Udp.endPacket();
   
   delay(200);
   
}

if (licht == 2 && lichtesp == 1) {
  neungesendet = 1;
  statusabfrage = 0;
  for(short z = 0; z < 4; z++){
  
/*
  Serial.println("Schalte Licht aus");
  Serial.print(licht&&lichtesp);
    unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("y");
    Udp.endPacket();
    */
    delay(200);
    
   }
     unsigned int udpR = 4210;
    Udp.beginPacket(ipa, udpR);
    Udp.write("qx");
    Udp.endPacket();
   delay(200);
   
    
}
  





   
  


  
  }

  yield();
}















  void mysqlsenden(){
  char test[128];  


  if(licht != lichtesp || rollade != rolladeesp || neungesendet == 1){
 
 /* 
   if(incomingPacket[9]=='a')
  {
    rolladetest[0] = '3';
  };
  if(incomingPacket[9]=='0')
  {
    rolladetest[0] = '4';
  };
*/
   if(incomingPacket[1]=='1')
  {
    status1[0] = '1';
  };
  if(incomingPacket[1]=='0')
  {
    status1[0] = '2';
  };

 

Serial.println(status1[0]);

  if (conn.connect(server_addr, 3306, user, password)&&status1[0]!= NULL) {
    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);



 char INSERT_DATA[] = "UPDATE sql11215113.homecontrol set statuss = (%c%d%d%d%c)";
  sprintf(test, INSERT_DATA,  status1[0], rolladeesp,5,6,mysqlbestaetigung[0]);
  Serial.println(test);
 
Serial.println(mysqlbestaetigung);
cur_mem->execute(test);
  neungesendet = 0;
   
   delete cur_mem;
 conn.close();
  }
 
  }

  }
    incomingPacket[2];
    incomingPacket[3];
    incomingPacket[4];
    incomingPacket[5];
    incomingPacket[6];
    incomingPacket[7];
    incomingPacket[8];
    incomingPacket[10];
    incomingPacket[11];
    incomingPacket[12];
    incomingPacket[13];

It is probably not causing a problem but what is this meant to do ?

    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
    cur_mem->execute(query);
    column_names *cols = cur_mem->get_columns();
    do {
      row = cur_mem->get_next_row();
      if (row != NULL) {

        head = atoi(row->values[0]);
        responseandroid = (head) % 10;
        tuer = (head / 10) % 10;
        markise = (head / 100) % 10;
        rollade = (head / 1000) % 10;
        licht = (head / 10000) % 10;

      }
    }
    while (row != NULL);
    conn.close();

    delete cur_mem;

you are doing the right thing by calling delete on your heap objects, but I'm not sure dynamic allocation is what you want to be doing on a micro. You could also try putting the MySQL_Cursor on the stack...

What is this running on?

could you just work with a static/global object?

UKHeliBob:
It is probably not causing a problem but what is this meant to do ?

The UDP response I get upon sending "qx" to my RF Arduino is stored in IncomingPackets. Its the status of my RF Arduino so that my "middleman" Arduino knows the current status of my devices (on/off).
I didnt implement all "smart" devices yet, so for now I just use the first few incomingPackets for testing.

BulldogLowell:
you are doing the right thing by calling delete on your heap objects, but I'm not sure dynamic allocation is what you want to be doing on a micro. You could also try putting the MySQL_Cursor on the stack...

What is this running on?

could you just work with a static/global object?

Its running on a Nodemcu 1.0 (ESP-12E module).
Sounds like a good idea, I will try it.
What is the limit of static allocation? How much more memory does it need in comparison with dynamic allocation?

jktz90:
Its running on a Nodemcu 1.0 (ESP-12E module).
Sounds like a good idea, I will try it.
What is the limit of static allocation? How much more memory does it need in comparison with dynamic allocation?

the problem isn't "how much memory" but how you use it... There is tons of references here on the forum regarding heap fragmentation and dynamic allocation.

If you don't absolutely need to dynamically instantiate instances run-time, just avoid it completely.

Refactoring what you have is quite trivial since you seem to already understand the libraries you are using.

char status1[0];

char status3[0];
char status4[0];

Arrays that can hold 0 objects are useless.

   status1[0] = '1';

Storing data beyond the end of an array can cause all kinds of problems, like allowing Donald Trump to be elected president. So, now we know who's to blame.

jktz90:
The UDP response I get upon sending "qx" to my RF Arduino is stored in IncomingPackets. Its the status of my RF Arduino so that my "middleman" Arduino knows the current status of my devices (on/off).
I didnt implement all "smart" devices yet, so for now I just use the first few incomingPackets for testing.

At the very least I think that you should comment them out