Search code examples
arduinoarduino-esp8266

Arduino Nano Crashed


I programmed rather long Arduino application and when I tried to run it on my Arduino Nano(ATmega328P CPU),I found it crashed when it turns to "Serial.println(F("ESP8266_PHP_CONNECTED"));"(Line 462), just stopped there and printed abnormal thing such as "ESP8266_PHP_CONNECTBB", I don't know why did it happened even if the SRAM was enough.this is what I read from monitor

#include <SoftwareSerial.h>;  
#include <EEPROM.h>   
#include <avr/pgmspace.h>;    
#include <MemoryFree.h>;    
//Serial    
SoftwareSerial ESP8266(2,3); // RX, TX    
SoftwareSerial HC05(10,11); // RX, TX    
//Other Sensors
#define MQ135 A0
#define MQ136 A7
//define values    
int MQ135_RAW_VALUE;    
int MQ136_RAW_VALUE;    
//define process status    
enum PROGRESS_STATE{INTERLIZING_ESP8266,INTERLIZING_HC05,    
WIFI_CONNECTING,WIFI_CONNECTED,PHP_CONNECTED,PHP_DISCONNECTED};    
PROGRESS_STATE progress_state=INTERLIZING_ESP8266;    
//define user id/MAC addr/WIFI SSID/WIFI BSSID/WIFI pwd    
/*EPPROM usage    
 * size:1024B(1024b char)    
 * USER_ID:0~49(totally 50b)    
 * USER_MAC:50~99(totally 50b)    
 * WIFI_SSID:100~199(totally 100b)    
 * WIFI_BSSID:200~299(totally 100b)    
 * WIFI_PASSWORD:300~399(totally 100b)    
 */    
String USER_ID="";    
String USER_MAC="";    
String WIFI_SSID="";    
String WIFI_BSSID="";    
String WIFI_PASSWORD="";    
//define websites    
const char WEBSITE_VERIFY_ID[] PROGMEM="http://example.com/mail/ar_get_userid.php?";    
const char WEBSITE_SEND_DATA[] PROGMEM="http://example.com/mail/ar_arduino2server.php?";    
//define ESP8266 return values    
byte ESP8266_RETURN=-1;    
byte ESP8266_TRY_TIME=0;    
const char AT_REQUEST_0[] PROGMEM="1";    
const char AT_REQUEST_1[] PROGMEM="OK";    
const char* const AT_REQUEST[] PROGMEM ={AT_REQUEST_0,AT_REQUEST_1};    

const char AT_RST_REQUEST_0[] PROGMEM="1";
const char AT_RST_REQUEST_1[] PROGMEM="ready";
const char* const AT_RST_REQUEST[] PROGMEM={AT_RST_REQUEST_0,AT_RST_REQUEST_1}; 

const char AT_CWJAP_REQUEST_0[] PROGMEM="2";    
const char AT_CWJAP_REQUEST_1[] PROGMEM="No AP\r\n\r\nOK";    
const char AT_CWJAP_REQUEST_2[] PROGMEM="WIFI CONNECTED\r\nWIFI GOT IP\r\n\r\nOK";    
const char* const AT_CWJAP_REQUEST[] PROGMEM={AT_CWJAP_REQUEST_0,AT_CWJAP_REQUEST_1,AT_CWJAP_REQUEST_2};            //"OK"<->"WIFI CONNECTED\nWIFI GOT IP\nOK"    

const char AT_CWQAP_REQUEST_0[] PROGMEM="2";    
const char AT_CWQAP_REQUEST_1[] PROGMEM="OK\r\nWIFI DISCONNECT";    
const char AT_CWQAP_REQUEST_2[] PROGMEM="ERROR";    
const char* const AT_CWQAP_REQUEST[] PROGMEM={AT_CWQAP_REQUEST_0,AT_CWQAP_REQUEST_1,AT_CWQAP_REQUEST_2};      

const char AT_CWJAP_ACCESS_0[] PROGMEM="2";    
const char AT_CWJAP_ACCESS_1[] PROGMEM="WIFI CONNECTED\r\nWIFI GOT IP\r\n\r\nOK";    
const char AT_CWJAP_ACCESS_2[] PROGMEM="FAIL";    
const char* const AT_CWJAP_ACCESS[] PROGMEM={AT_CWJAP_ACCESS_0,AT_CWJAP_ACCESS_1,AT_CWJAP_ACCESS_2};              //"OK"<->"WIFI CONNECTED\nWIFI GOT IP\nOK"    
const char AT_CIPSTAMAC_REQUEST_0[] PROGMEM="1";    
const char AT_CIPSTAMAC_REQUEST_1[] PROGMEM="OK";    
const char* const AT_CIPSTAMAC_REQUEST[] PROGMEM={AT_CIPSTAMAC_REQUEST_0,AT_CIPSTAMAC_REQUEST_1};    

const char AT_CIPSTART_ACCESS_0[] PROGMEM="2";    
const char AT_CIPSTART_ACCESS_1[] PROGMEM="CONNECT\r\n\r\nOK";    
const char AT_CIPSTART_ACCESS_2[] PROGMEM="ERROR";    
const char* const AT_CIPSTART_ACCESS[] PROGMEM={AT_CIPSTART_ACCESS_0,AT_CIPSTART_ACCESS_1,AT_CIPSTART_ACCESS_2};              //"OK"<->"CONNECT\nOK"    

const char AT_CIPSEND_ACCESS_0[] PROGMEM="3";    
const char AT_CIPSEND_ACCESS_1[] PROGMEM=">";    
const char AT_CIPSEND_ACCESS_2[] PROGMEM="ERROR";    
const char AT_CIPSEND_ACCESS_3[] PROGMEM="CLOSED";    
const char* const AT_CIPSEND_ACCESS[] PROGMEM={AT_CIPSEND_ACCESS_0,AT_CIPSEND_ACCESS_1,AT_CIPSEND_ACCESS_2,AT_CIPSEND_ACCESS_3};       //">"<->"OK\n>","ERROR"<->"link is not valid\nERROR"    

const char AT_GET_REQUEST_0[] PROGMEM="3";    
const char AT_GET_REQUEST_1[] PROGMEM="SEND OK";    
const char AT_GET_REQUEST_2[] PROGMEM="SEND FAIL";    
const char AT_GET_REQUEST_3[] PROGMEM="CLOSED";    
const char* const AT_GET_REQUEST[] PROGMEM={AT_GET_REQUEST_0,AT_GET_REQUEST_1,AT_GET_REQUEST_2,AT_GET_REQUEST_3};//"OK"<->"SEND OK","FAIL"<->"SEND FAIL"    

const char AT_GET_MSG_0[] PROGMEM="<START>";    
const char AT_GET_MSG_1[] PROGMEM="<END>";    
const char* const AT_GET_MSG[] PROGMEM={AT_GET_MSG_0,AT_GET_MSG_1};    

const char AT_CIPCLOSE_0[] PROGMEM="2";    
const char AT_CIPCLOSE_1[] PROGMEM="CLOSED\r\n\r\nOK";    
const char AT_CIPCLOSE_2[] PROGMEM="ERROR";    
const char* const AT_CIPCLOSE[] PROGMEM={AT_CIPCLOSE_0,AT_CIPCLOSE_1,AT_CIPCLOSE_2};             //"OK"<->"CLOSED\nOK"    
//main    
void setup() {
  pinMode(MQ135,INPUT);
  pinMode(MQ136,INPUT);
  Serial.begin(9600);
  Serial.println(F("INTERLIZING_SYSTEM"));
  ESP8266.begin(9600);
  HC05.begin(9600);
    for(int i=0;EEPROM.read(i)!=0;i++){
      USER_ID.concat((char)EEPROM.read(i));
    }
    for(int i=50;EEPROM.read(i)!=0;i++){
      USER_MAC.concat((char)EEPROM.read(i));
    }
    for(int i=100;EEPROM.read(i)!=0;i++){
      WIFI_SSID.concat((char)EEPROM.read(i));
    }
    for(int i=200;EEPROM.read(i)!=0;i++){
      WIFI_BSSID.concat((char)EEPROM.read(i));
    }
    for(int i=300;EEPROM.read(i)!=0;i++){
      WIFI_PASSWORD.concat((char)EEPROM.read(i));
    }
    Serial.println(F("INTERLIZED_SYSTEM"));
    delay(100);
}
//ESP8266 sender and receiver(return values)
String ESP8266_MsgTx2Rx(String Msg,int Delay,const char* const SignList[],bool DebugSign)
{
  char*Temp_Buffer;
  ESP8266.println(Msg);
  if(DebugSign){
    Serial.println(Msg);
  }
  delay(Delay);
  String ReturnMsg="";
  char LastReturnChar=0;
  Temp_Buffer=new char[1];
  //Temp_Buffer=Num
  strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[0])));
  int SignListLength=atoi(Temp_Buffer);
  delete(Temp_Buffer);
  boolean ReturnFull=false;
  while(true)
  {
   while(ESP8266.available() > 0)
   {
    char ReturnChar=(char)(ESP8266.read());
    if(ReturnChar==' '&&LastReturnChar==' '){
      continue;
    }
    if((ReturnChar>=32&&ReturnChar<=126)||ReturnChar=='\r'||ReturnChar=='\n'||ReturnChar=='\0'){
      LastReturnChar=ReturnChar;
      ReturnMsg+=ReturnChar;
    }
   }
   for(int i=1;i<=SignListLength;i++){
    Temp_Buffer=new char[50];
    strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[i])));
    if(DebugSign){
      Serial.print(i);
      Serial.print(" "+ReturnMsg+" < - > ");
      Serial.println(Temp_Buffer);
  }
    //Temp_Buffer=SignList[SignListLength]
    if(ReturnMsg.lastIndexOf(Temp_Buffer)!=-1){
      ReturnFull=true;
      ESP8266_RETURN=i;
      delete(Temp_Buffer);
      break;
    }
    delete(Temp_Buffer);
   }
   if(ReturnFull){
    Temp_Buffer=new char[50];
    strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[ESP8266_RETURN])));
    //Temp_Buffer=SignList[ESP8266_RETURN]
    ReturnMsg.replace(Msg+"\r\n","");
    ReturnMsg.replace(Msg.substring(Msg.indexOf("+"),Msg.length()),"");
    ReturnMsg.replace(Msg.substring(Msg.indexOf("+"),Msg.indexOf("?")),"");
    ReturnMsg.replace("\r\n\r\n","\r\n");
    String SpecialReplacer="\r\n";
    SpecialReplacer.concat(Temp_Buffer);
    SpecialReplacer.concat("\r\n");
    ReturnMsg.replace(SpecialReplacer,"");
    String AddReturnMsg="";
    AddReturnMsg.concat(Temp_Buffer);
    ReturnMsg=AddReturnMsg+"_"+ReturnMsg;
    delete(Temp_Buffer);
    return ReturnMsg;
   }
  }
}
//ESP8266 receiver (no return value)
void ESP8266_MsgTx2Rx(String Msg,int Delay,const char* const SignList[])
{
  //read from Flash Rom
  char*Temp_Buffer;
  ESP8266.println(Msg);
  delay(Delay);
  String ReturnMsg="";
  char LastReturnChar=0;
  Temp_Buffer=new char[1];
  //Temp_Buffer=Num
  strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[0])));
  int SignListLength=atoi(Temp_Buffer);
  delete(Temp_Buffer);
  boolean ReturnFull=false;
  while(true)
  {
   //get data from ESP8266
   while(ESP8266.available() > 0)
   {
    char ReturnChar=(char)(ESP8266.read());
    //delete space
    if(ReturnChar==' '&&LastReturnChar==' '){
      continue;
    }
    //delete special words
    if((ReturnChar>=32&&ReturnChar<=126)||ReturnChar=='\r'||ReturnChar=='\n'||ReturnChar=='\0'){
      LastReturnChar=ReturnChar;
      ReturnMsg+=ReturnChar;
    }
   }
   for(int i=1;i<=SignListLength;i++){
    Temp_Buffer=new char[50];
    strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[i])));
    //Temp_Buffer=SignList[SignListLength]
    if(ReturnMsg.lastIndexOf(Temp_Buffer)!=-1){
      ReturnFull=true;
      ESP8266_RETURN=i;
      delete(Temp_Buffer);
      break;
    }
    delete(Temp_Buffer);
   }
   if(ReturnFull){
     Temp_Buffer=new char[50];
     strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[ESP8266_RETURN])));
     //Temp_Buffer=SignList[ESP8266_RETURN]
     ReturnMsg.replace(Msg+"\r\n","");
     ReturnMsg.replace(Msg.substring(Msg.indexOf("+"),Msg.length()),"");
     ReturnMsg.replace(Msg.substring(Msg.indexOf("+"),Msg.indexOf("?")),"");
     ReturnMsg.replace("\r\n\r\n","\r\n");
     String SpecialReplacer="\r\n";
     SpecialReplacer.concat(Temp_Buffer);
     SpecialReplacer.concat("\r\n");
     ReturnMsg.replace(SpecialReplacer,"");
     String AddReturnMsg="";
     AddReturnMsg.concat(Temp_Buffer);
     ReturnMsg=AddReturnMsg+"_"+ReturnMsg;
     delete(Temp_Buffer);
     //return ReturnMsg;
   }
  }
}

//ESP8266收信息
String ESP8266_Rx(int Delay,char Start[],char End[])
{
  //read from Flash Rom
  char*Start_Temp_Buffer;
  char*End_Temp_Buffer;
  String Start_Get="";
  String End_Get="";
  delay(Delay);
  String ReturnMsg="";
  char LastReturnChar=0;
  boolean ReturnFull=false;
  while(true)
  {
   //read from ESP8266
   while(ESP8266.available() > 0)
   {
    char ReturnChar=(char)(ESP8266.read());
    //delete space
    if(ReturnChar==' '&&LastReturnChar==' '){
      continue;
    }
    //delete special word
    if((ReturnChar>=32&&ReturnChar<=126)||ReturnChar=='\r'||ReturnChar=='\n'||ReturnChar=='\0'){
      LastReturnChar=ReturnChar;
      ReturnMsg+=ReturnChar;
    }
   }
   Start_Temp_Buffer=new char[10];
   End_Temp_Buffer=new char[10];
   strcpy_P(Start_Temp_Buffer, (char*)pgm_read_word(&(Start)));
   strcpy_P(End_Temp_Buffer, (char*)pgm_read_word(&(End)));
   Start_Get=Start_Temp_Buffer;
   End_Get=End_Temp_Buffer;
   delete(Start_Temp_Buffer);
   delete(End_Temp_Buffer);
   if(ReturnMsg.lastIndexOf(End_Get)!=-1){
     ReturnFull=true;
   }
   if(ReturnFull){
    ReturnMsg.substring(ReturnMsg.indexOf(Start_Get)+Start_Get.length(),ReturnMsg.indexOf(End_Get)-1);
    return ReturnMsg;
   }
  }
}
//HC05 receiver(mianly use to get user data from HC05 and receive "OK" when sending msg to HC05)
String HC05_MsgRx()
{
 String HC05_ReturnMsg="";
 int Length=0;
 while(1)
 {
  char ReturnChar=-1;
  while (HC05.available())
  {
   //use byte type to read
   ReturnChar=(char)HC05.read();
   HC05_ReturnMsg.concat((char)ReturnChar);
  }
  if(ReturnChar==0)//stop if read '\0'
  {
    Serial.println(HC05_ReturnMsg);
    return HC05_ReturnMsg;
  }
 }
}
//HC05 sender(mainly use to send MAC addr)
bool HC05_MsgTx(String Msg,int Delay)
{
 HC05.println(Msg);
 delay(Delay);
 String HC05_SEND_MSG_CORRECTION=HC05_MsgRx();
 if(HC05_SEND_MSG_CORRECTION.indexOf("OK")!=-1){
  return true;
 }
 else{
  return false;
 }
}

void Interlizing_Esp8266(){
  Serial.println(F("INTERLIZING_ESP8266"));
  //user data stored in EPPROM
  if(USER_ID.length()!=0&&WIFI_SSID.length()!=0){
    Serial.println(F("ESP8266_WIFI_BINDED"));
    progress_state=WIFI_CONNECTING;
    return;
  }
  ESP8266.listen();
  String AT_CWJAP_RETURN=ESP8266_MsgTx2Rx("AT+CWJAP_DEF?",2000,AT_CWJAP_REQUEST,false);
  switch(ESP8266_RETURN){
    //Wifi unbinded
    case 1:{
      Serial.println(F("ESP8266_WIFI_UNBINDED"));
      progress_state=INTERLIZING_HC05;
      break;
    }
    //Wifi binded
    case 2:{
      Serial.println(F("ESP8266_WIFI_BINDED"));
      progress_state=WIFI_CONNECTED;
      break;
    }
    default:break;
  }
}

void Interlizing_Hc05(){
  //get user data from bluetooth
  HC05.listen();
  Serial.println(F("INTERLIZING_HC05"));
  String HC05_REQUIRE_NEW_RETURN=HC05_MsgRx();
  USER_ID=HC05_REQUIRE_NEW_RETURN.substring(HC05_REQUIRE_NEW_RETURN.indexOf(F("<USERID>"))+8,HC05_REQUIRE_NEW_RETURN.indexOf(F("</USERID>")));
  WIFI_SSID=HC05_REQUIRE_NEW_RETURN.substring(HC05_REQUIRE_NEW_RETURN.indexOf(F("<SSID>"))+6,HC05_REQUIRE_NEW_RETURN.indexOf(F("</SSID>")));
  WIFI_BSSID=HC05_REQUIRE_NEW_RETURN.substring(HC05_REQUIRE_NEW_RETURN.indexOf(F("<BSSID>"))+7,HC05_REQUIRE_NEW_RETURN.indexOf(F("</BSSID>")));
  WIFI_PASSWORD=HC05_REQUIRE_NEW_RETURN.substring(HC05_REQUIRE_NEW_RETURN.indexOf(F("<PASSWORD>"))+10,HC05_REQUIRE_NEW_RETURN.indexOf(F("</PASSWORD>")));
  Serial.println("+++"+USER_ID+"+++");
  Serial.println("+++"+WIFI_SSID+"+++");
  Serial.println("+++"+WIFI_BSSID+"+++");
  Serial.println("+++"+WIFI_PASSWORD+"+++");
  //write to EPPROM
  for(int i=0;i<USER_ID.length();i++){
    EEPROM.write(i,USER_ID.charAt(i));
  }
  for(int i=0+USER_ID.length();i<50;i++){
    EEPROM.write(i,0);
  }
  for(int i=100;i<WIFI_SSID.length();i++){
    EEPROM.write(i,WIFI_SSID.charAt(i));
  }
  for(int i=100+WIFI_SSID.length();i<200;i++){
    EEPROM.write(i,0);
  }
  for(int i=200;i<WIFI_BSSID.length();i++){
    EEPROM.write(i,WIFI_BSSID.charAt(i));
  }
  for(int i=200+WIFI_BSSID.length();i<300;i++){
    EEPROM.write(i,0);
  }
  for(int i=300;i<WIFI_PASSWORD.length();i++){
    EEPROM.write(i,WIFI_PASSWORD.charAt(i));
  }
  for(int i=300+WIFI_PASSWORD.length();i<400;i++){
    EEPROM.write(i,0);
  }
  //get MAC addr
  ESP8266.listen();
  USER_MAC=ESP8266_MsgTx2Rx(F("AT+CIPSTAMAC?"),200,AT_CIPSTAMAC_REQUEST,false);
  USER_MAC.replace(":","");
  //write to EPPROM
  for(int i=50;i<USER_MAC.length();i++){
    EEPROM.write(i,USER_MAC.charAt(i));
  }
  for(int i=50+USER_MAC.length();i<100;i++){
    EEPROM.write(i,0);
  }
  //get MAC addr
  HC05.listen();
  while(!HC05_MsgTx(USER_MAC,200));
  progress_state=WIFI_CONNECTING;
}

void Wifi_Connecting(){
  ESP8266.listen();
  Serial.println(F("WIFI_CONNECTING"));
  bool WIFI_CONNECTION_STATE=false;
  while(!WIFI_CONNECTION_STATE){
    String AT_CWJAP_ACCESS_RETURN=ESP8266_MsgTx2Rx("AT+CWJAP_CUR=\""+WIFI_SSID+"\",\""+WIFI_PASSWORD+"\",\""+WIFI_BSSID+"\"",2000,AT_CWJAP_ACCESS,false);
    switch(ESP8266_RETURN){
      //succeed in connecting to Wifi
      case 1:{
        Serial.println(F("ESP8266_WIFI_CONNECTED"));
        progress_state=WIFI_CONNECTED;
        WIFI_CONNECTION_STATE=true;
        break;
      }
      //failed to connect to Wifi
      case 2:{
        Serial.print(F("ESP8266_WIFI_CONNECTION_FAIL: "));
        Serial.println(ESP8266_RETURN);
        progress_state=WIFI_CONNECTING;
        break;
      }
      default:break;
    }
  }
}

void Wifi_Connected(){
  Serial.println(F("WIFI_CONNECTED"));
  String AT_CIPSTART_ACCESS_RETURN=ESP8266_MsgTx2Rx(F("AT+CIPSTART=\"TCP\",\"www.yiuliu.cn\",80"),500,AT_CIPSTART_ACCESS,false);
  switch(ESP8266_RETURN){
    //succeed in connecting server
    case 1:{
      Serial.println(F("ESP8266_PHP_CONNECTED"));
      progress_state=PHP_CONNECTED;
      break;
    }
    //failed to connect server
    case 2:{
      Serial.print(F("ESP8266_PHP_CONNECTION_FAIL: "));
      Serial.println(ESP8266_RETURN);
      progress_state=WIFI_CONNECTING;
      if(++ESP8266_TRY_TIME>=5){//connection timeout,restart application
        Serial.println(F("ESP8266_PHP_CONNECTION_TIMEOUT"));
        String AT_RST_REQUEST_RETURN=ESP8266_MsgTx2Rx(F("AT+RST"),1000,AT_RST_REQUEST,false);
        progress_state=INTERLIZING_ESP8266;
        break;
       }
       break;
     }
     default:break;
  }
}

void Php_Connected(){
  Serial.println(F("PHP_CONNECTED"));
  bool SUCCESS_GET_VERIFY=false;
  if(USER_ID==""){//binded
    //get MAC addr
    ESP8266.listen();
    USER_MAC=ESP8266_MsgTx2Rx(F("AT+CIPSTAMAC?"),200,AT_CIPSTAMAC_REQUEST,false);
    USER_MAC.replace(":","");
    //get user id
    String GET_REQUEST="GET ";
    GET_REQUEST.concat(WEBSITE_VERIFY_ID);
    GET_REQUEST.concat("mac=");
    GET_REQUEST.concat(USER_MAC);
    String AT_CIPSEND_ACCESS_RETURN=ESP8266_MsgTx2Rx("AT+CIPSEND="+GET_REQUEST.length()+2,200,AT_CIPSEND_ACCESS,false);
    switch(ESP8266_RETURN){
      //succeed in opening socket
      case 1:{
        Serial.println(F("ESP8266_PHP_CONNECTED(GET_VERIFY)"));
        progress_state=PHP_CONNECTED;
        Serial.println(F("GET"));
        String AT_GET_REQUEST_RETURN=ESP8266_MsgTx2Rx(GET_REQUEST,200,AT_GET_REQUEST,true);
        switch(ESP8266_RETURN){
          //succeed in sending,ready to get return value
          case 1:{
            Serial.println(F("ESP8266_PHP_SEND_SUCCESS(GET_VERIFY)"));
            String AT_GET_MSG_RETURN=ESP8266_Rx(1000,AT_GET_MSG[0],AT_GET_MSG[1]);
            if(AT_GET_MSG_RETURN.equals(F("none"))){//lost bind
              Serial.println(F("ESP8266_BIND_LOST(GET_VERIFY)"));
              progress_state=INTERLIZING_HC05;
              String AT_GET_REQUEST_RETURN=ESP8266_MsgTx2Rx("AT+CWQAP",200,AT_CWQAP_REQUEST,false);
              //clear eeprom
              for(int i=0;i<400;i++){
                EEPROM.write(i,0);
              }
              USER_ID="";
              USER_MAC="";
              WIFI_SSID="";
              WIFI_BSSID="";
              WIFI_PASSWORD="";
            }
            else{//user has been verified
              SUCCESS_GET_VERIFY=true;
              String AT_CIPCLOSE_RETURN=ESP8266_MsgTx2Rx(F("AT+CIPCLOSE"),200,AT_CIPCLOSE,false);
              Serial.print(F("ESP8266_VERIFY_SUCCESS(GET_VERIFY):"));
              Serial.println(USER_ID);
              USER_ID=AT_GET_MSG_RETURN.substring(AT_GET_MSG_RETURN.indexOf(F("<USERID>"))+8,AT_GET_MSG_RETURN.indexOf(F("</USERID>")));
            }
            break;
          }
          //fail to send,socket closed
          default:{
            Serial.print(F("ESP8266_PHP_SEND_FAIL(GET_VERIFY): "));
            Serial.println(ESP8266_RETURN);
            progress_state=WIFI_CONNECTED;
            break;
          }
        }
        break;
      }
      //fail to start socket
      default:{
        Serial.print(F("ESP8266_PHP_CONNECTION_FAIL(GET_VERIFY):"));
        Serial.println(ESP8266_RETURN);
        progress_state=WIFI_CONNECTED;
        break;
      }
    }
  }
  else{//new bind
    Serial.println(F("ESP8266_BIND_NEW_GOT(GET_VERIFY)"));
    SUCCESS_GET_VERIFY=true;
  }  
  if(SUCCESS_GET_VERIFY){//send data
    //get sensor data
    MQ135_RAW_VALUE=analogRead(MQ135);
    MQ136_RAW_VALUE=analogRead(MQ136);
    //connect to server
    char*Temp_Buffer;
    Temp_Buffer=new char[50];
    strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(WEBSITE_SEND_DATA)));
    String GET_REQUEST="GET ";
    GET_REQUEST.concat(Temp_Buffer);
    GET_REQUEST.concat("type=toilet&user_id="+USER_ID+"&mq135_raw="+MQ135_RAW_VALUE+"&mq136_raw="+MQ136_RAW_VALUE);
    delete(Temp_Buffer);
    String AT_CIPSEND_ACCESS_RETURN=ESP8266_MsgTx2Rx("AT+CIPSEND="+GET_REQUEST.length()+2,200,AT_CIPSEND_ACCESS,false);
    switch(ESP8266_RETURN){
      //succeeded openning socket
      case 1:{
        Serial.println(F("ESP8266_PHP_CONNECTED(SEND_DATA)"));
        progress_state=PHP_CONNECTED;
        String AT_GET_REQUEST_RETURN=ESP8266_MsgTx2Rx(GET_REQUEST,200,AT_GET_REQUEST,false);
        switch(ESP8266_RETURN){
        //send succeeded
        case 1:{
          Serial.println(F("ESP8266_PHP_SEND_SUCCESS(SEND_DATA)"));
            String AT_GET_MSG_RETURN=ESP8266_Rx(1000,AT_GET_MSG[0],AT_GET_MSG[1]);
            if(AT_GET_MSG_RETURN.equals("error")){//lost bind
              Serial.println(F("ESP8266_BIND_LOST(SEND_DATA)"));
              progress_state=INTERLIZING_HC05;
              String AT_GET_REQUEST_RETURN=ESP8266_MsgTx2Rx(F("AT+CWQAP"),200,AT_CWQAP_REQUEST,false);
              //clear eeprom data
              for(int i=0;i<400;i++){
                EEPROM.write(i,0);
              }
              USER_ID="";
              USER_MAC="";
              WIFI_SSID="";
              WIFI_BSSID="";
              WIFI_PASSWORD="";
            }
            else{//send sensor data
              String AT_CIPCLOSE_RETURN=ESP8266_MsgTx2Rx(F("AT+CIPCLOSE"),200,AT_CIPCLOSE,false);
              int DELAY=atoi(AT_GET_MSG_RETURN.substring(AT_GET_MSG_RETURN.indexOf(F("<DALAY>"))+7,AT_GET_MSG_RETURN.indexOf(F("</DALAY>"))).c_str());
              Serial.print(F("ESP8266_SEND_DATA_SUCCESS(SEND_DATA),NEXT_SEND_DELAY"));
              Serial.println(DELAY);
              delay(DELAY);
            }
            break;
          }
          //fail to send,socket closed
          default:{
            Serial.print(F("ESP8266_PHP_SEND_FAIL(SEND_DATA): "));
            Serial.println(ESP8266_RETURN);
            progress_state=WIFI_CONNECTED;
            break;
          }
         }
         break;
       }
       //fail to start socket
       default:{
         Serial.print(F("ESP8266_PHP_CONNECTION_FAIL(SEND_DATA): "));
         Serial.println(ESP8266_RETURN);
         progress_state=WIFI_CONNECTED;
         break;
       }
    }
  }
}

void loop() {
  switch(progress_state){
    //judge if WIFI is binded
    case INTERLIZING_ESP8266:
    {
      Interlizing_Esp8266();
      Serial.print(F("Free:"));
      Serial.println(freeMemory());
      break;
    }
    case INTERLIZING_HC05:
    {
      Interlizing_Hc05();
      Serial.print(F("Free:"));
      Serial.println(freeMemory());
      break;
    }
    case WIFI_CONNECTING:
    {
      Wifi_Connecting();
      Serial.print(F("Free:"));
      Serial.println(freeMemory());
      break;
    }
    case WIFI_CONNECTED:
    {
      Wifi_Connected();
      Serial.print(F("Free:"));
      Serial.println(freeMemory());
      break;
    }
    case PHP_CONNECTED:
    {
      Php_Connected();
      Serial.print(F("Free:"));
      Serial.println(freeMemory());
      break;
    }
    default:break;
  };
}

Solution

  • You'd better be careful to deal with character buffers in your program. Based on my short observation on your code, I found erroneous codes in ESP8266_MsgTx2Rx() which is being called more frequently and looks suspicious because it's supposed to be called around before the crash.

    Are you sure the length of the string to be read will be the only one byte? Otherwise, strcpy_P() will cause memory corruption which might cause another crash when the corresponding memory would be referred to later on. Another point is ... Whenever calling malloc() or new, you should check the validity of the returned pointer first before using it as well.

    Temp_Buffer=new char[1];
    strcpy_P(Temp_Buffer, (char*)pgm_read_word(&(SignList[0])));
    

    You'd better use strtol() which is much safer with valid digit character check. Moreover, you didn't consider additional one-byte for the '\0' null character at the end of the string which would prevent any issue from atoi().

    int SignListLength=atoi(Temp_Buffer);
    

    I'm assuming that the crash would be caused by one of the above codes. Even though this is not the real cause, you need to change the code properly and better check other codes as well whether or not there is the same potential issue. With this kind of codes, you might be encountering the similar issues. If you don't have the issue, then that's just lucky and anyway, you will have the issue depending on the garbage data in RAM which is unintentionally referred to.