Arduino Nano坠毁

时间:2018-03-12 19:10:06

标签: arduino arduino-esp8266

我编写了相当长的Arduino应用程序,当我尝试在我的Arduino Nano(ATmega328P CPU)上运行它时,我发现它在转向“Serial.println(F(”ESP8266_PHP_CONNECTED“))时崩溃了;”(第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=='\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;
  };
}

1 个答案:

答案 0 :(得分:0)

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

你确定要读取的字符串的长度是唯一的一个字节吗?否则,strcpy_P()会导致内存损坏,当相应的内存出现时,可能会导致另一次崩溃稍后提到。另一点是......每当调用malloc()new时,您应该先使用它来检查返回指针的有效性。

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

你最好使用strtol(),这对于有效的数字字符检查更安全。此外,你没有考虑额外的一个字节为'\ 0'null字符at字符串的结尾可以防止来自atoi()的任何问题。

int SignListLength=atoi(Temp_Buffer);

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