Arduino 纳米崩溃

Arduino Nano Crashed

我编写了相当长的 Arduino 应用程序,当我尝试在我的 Arduino Nano(ATmega328P CPU) 上 运行 它时,我发现它在转向 "Serial.println(F("[= 时崩溃了16=]"));"(第462行),就停在那里打印了"ESP8266_PHP_CONNECTBB"之类的异常东西,不知道为什么SRAM够用了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=='[=10=]'){
      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=='[=10=]'){
      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=='[=10=]'){
      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 '[=10=]'
  {
    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;
  };
}

你最好小心处理程序中的字符缓冲区。 根据我对您的代码的简短观察,我在 ESP8266_MsgTx2Rx() 中发现了错误代码,这些代码被更频繁地调用并且看起来很可疑,因为它应该在崩溃之前被调用。

你确定要读取的字符串的长度将是唯一的一个字节吗?否则,strcpy_P()会导致内存损坏,这可能会导致再次崩溃后面会提到相应的内存。还有一点是...无论何时调用malloc()new,在使用前都应该先检查返回指针的有效性。

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

你最好用strtol(),这样比较安全,有有效的数字字符检查。而且,你没有考虑额外的one-byte字符串末尾的 '\0' 空字符可以防止 atoi().

出现任何问题
int SignListLength=atoi(Temp_Buffer);

我假设崩溃是由上述代码之一引起的。 即使这不是真正的原因,您也需要正确更改代码并更好地检查其他代码以及是否存在相同的潜在问题。使用这种代码,您可能会遇到类似的问题。如果你没有遇到这个问题,那就太幸运了,无论如何,你会遇到这个问题,这取决于无意中引用的 RAM 中的垃圾数据。