-->
Page 1 of 1

UNO Webserver - ESP8266 Hangs

PostPosted: Sat Jan 03, 2015 2:06 pm
by johnamon
Hi All,

I've modified / borrowed / written code that throws an HTML page using only the arduino UNO & ESP8266 AT Commands. However i find that without hard resetting the ESP8266 module after every page refresh that I only get between 2 & 4 page refreshes before the ESP8266 module 'apparently' hangs.

Does anyone have any ideas if it's possible to keep the connection up without hard resetting the ESP?? It's a pain to have to wait for the hard reset to complete..

A big long bit of code coming up..... Thanks in advance for any help!!

Code: Select all
//Leonardo
//Serial_ & dbgTerminal = Serial;
//HardwareSerial & espSerial = Serial1;


#define NUMBER_OF_PLUGS 9
#define LEDBLINK_MS     1000  // Blink rate (in milliseconds)
#define ESPRESET_MS     120000  //

////UNO & M328P
#include <avr/wdt.h>


#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
#include <Flash.h>

int reporting;


FLASH_STRING(HTMLCode1, "<HTML><HEAD>");
FLASH_STRING(HTMLCode2,"<TITLE>Arduino Wifi Plug</TITLE></HEAD><BODY><H1>Aquarium WIFI Plug Bar</H1><form action=\"\" method=\"get\"><fieldset><legend>Status</legend> &nbsp &nbsp &nbsp<br><br>");
FLASH_STRING(HTMLCode3,"</fieldset></form><BR><BR><HR><H2>Server Stats</H2><BR><B> Up time:");
FLASH_STRING(HTMLCode4,"</B></BODY></HTML>");
FLASH_STRING(stylesheet,"<Style type=\"text/css\">body{background-color:#FF9900;}  button.on {background-color:#009900; width:400px; padding-left:25px;} button.off{background-color:#E62E00; width:400px; padding-left:25px;}</Style>");


  FLASH_STRING(on1,"<button type=\"submit\" class=\"on\" name=\"");
  FLASH_STRING(on2,"\" value=\"1");
  FLASH_STRING(on3,"\">");
  FLASH_STRING(on4,"</button>");
  FLASH_STRING(on5,"<br>");
 
  FLASH_STRING(off1,"<button type=\"submit\" class =\"off\" name=\"");
  FLASH_STRING(off2,"\" value=\"0");
  FLASH_STRING(off3,"\">");
  FLASH_STRING(off4,"</button>");
  FLASH_STRING(off5,"<br>");

 
   
  int plug_pins[9] = {4,5,6,7,8,9,10,11,12};



//SoftwareSerial dbgTerminal(10, 11); // RX, TX
HardwareSerial & espSerial = Serial;

//
////MEGA2560
//HardwareSerial & dbgTerminal = Serial;
//HardwareSerial & espSerial = Serial1;

// set pin numbers:
const int ledPin =  13;      // the number of the LED pin
const int ESP8266_CHPD = 2;

// Variables will change:
int ledState = HIGH;             // ledState used to set the LED

#define BUFFER_SIZE 128
char buffer[BUFFER_SIZE];

void setup() {
 
  espSerial.setTimeout(2000);
 
  wdt_enable(WDTO_8S);

  int j=0;
  for ( j=0; j<NUMBER_OF_PLUGS; j++){
  pinMode(plug_pins[j],OUTPUT);
  digitalWrite(plug_pins[j],HIGH);
}
 
  pinMode(ledPin, OUTPUT); 
  pinMode(ESP8266_CHPD, OUTPUT);
  digitalWrite(ESP8266_CHPD,HIGH);

  espSerial.begin(9600); // ESP8266 
 
  delay(1000);

  //connect to router
  clearSerialBuffer();
  connectWiFi("SSID", "PASSWORD");
  wdt_reset();
 
  //test if the module is ready
  espSerial.println("AT");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
  //Change to mode 1
  espSerial.println("AT+CWMODE=1");
  espSerial.find("OK");
  clearSerialBuffer();
  delay(10);
 
  //set the multiple connection mode
  espSerial.println("AT+CIPMUX=1");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
 
  //set the server of port 80 check "no change" or "OK"
  espSerial.println("AT+CIPSERVER=1,80");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
  //set time out
 
  espSerial.println("AT+CIPSTO=300");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
 
  //print the ip addr
  //reporting = freeRam();
  espSerial.println("AT+CIFSR");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();

  digitalWrite(ledPin,ledState); 
}

void loop() {
   ledBlink();
 
  wdt_reset();
 
 
  int ch_id, packet_len;
  int pin_address, pin_state;
  char *pb; 
  espSerial.readBytesUntil('\n', buffer, BUFFER_SIZE);

  if(strncmp(buffer, "+IPD,", 5)==0) {
    // request: +IPD,ch,len:data
    sscanf(buffer+5, "%d,%d", &ch_id, &packet_len);
    sscanf(buffer+17, "%d=%d", &pin_address, &pin_state);
   
    if (packet_len > 0) {
      // read serial until packet_len character received
      // start from :
      pb = buffer+5;
      while(*pb!=':') pb++;
      pb++;
      if (pin_address == 4) {

        delay(100);
        functionSwitch(4);
        clearBuffer();
        clearSerialBuffer();
        homepage(ch_id);

      }
     
      else if (pin_address == 12) {

        delay(100);
        functionSwitch(12);
        clearBuffer();
        clearSerialBuffer();
        homepage(ch_id);

      }
     
     
      else if (strncmp(pb, "GET / ", 6) == 0) {

        delay(100);
       
        clearBuffer();
        clearSerialBuffer();
        homepage(ch_id);
      }
    }
  }
 
  clearBuffer();
  clearSerialBuffer();
}

void homepage(int ch_id) {
 
  //reporting = freeRam();
 
  String Header;
 
  String time="";
  time = time + millis()/1000;
  time = time + " Seconds";

  Header =  "HTTP/1.1 200 OK\r\n";
  Header += "Content-Type: text/html\r\n";
  Header += "Connection: close\r\n"; 
  //Header += "Refresh: 5\r\n";
 
  int html_length = 0;
  html_length = html_length + (int)HTMLCode1.length();
  html_length = html_length + (int)HTMLCode2.length();
  html_length = html_length + (int)HTMLCode3.length();
  html_length = html_length + formSize();
  html_length = html_length + HTMLCode4.length();
  html_length = html_length + time.length();
  html_length = html_length + (int)stylesheet.length();
  //html_length = html_length + sizeof(reporting);
 
  Header += "Content-Length: ";
  Header += (int)html_length;
  Header += "\r\n\r\n";

  espSerial.print("AT+CIPSEND=");
  espSerial.print(ch_id);
  espSerial.print(",");
  espSerial.println(html_length+Header.length());
  while (!(UCSR0A & _BV(TXC0)));

  if (espSerial.find(">")) {
    espSerial.print(Header);
    while (!(UCSR0A & _BV(TXC0)));
   
    HTMLCode1.print(espSerial);
    while (!(UCSR0A & _BV(TXC0)));
   
    stylesheet.print(espSerial);
    while (!(UCSR0A & _BV(TXC0)));
   
    HTMLCode2.print(espSerial);
    while (!(UCSR0A & _BV(TXC0)));
     
    print_form();
     
    HTMLCode3.print(espSerial);
    while (!(UCSR0A & _BV(TXC0)));
   
    espSerial.print(time);
    while (!(UCSR0A & _BV(TXC0)));
   
    //print output from functions
    //espSerial.print(reporting);
    //while (!(UCSR0A & _BV(TXC0)));
   
    HTMLCode4.print(espSerial);
    while (!(UCSR0A & _BV(TXC0))); 
   
    //clearBuffer();
  }
 
  String closeString = "AT+CIPCLOSE=";
  closeString = closeString + ch_id;
   
  espSerial.println(closeString);
  while (!(UCSR0A & _BV(TXC0)));
  delay(100);
  hardReset();

 
  clearSerialBuffer();   
  //delay(10);
  //clearSerialBuffer();
 


}

// Get the data from the WiFi module and send it to the debug serial port
String GetResponse(String AT_Command, int wait){
  String tmpData;
 
  espSerial.println(AT_Command);
  delay(wait);
  while (espSerial.available() >0 )  {
    char c = espSerial.read();
    tmpData += c;
   
    if ( tmpData.indexOf(AT_Command) > -1 )         
      tmpData = "";
    else
      tmpData.trim();       
         
   }
   return tmpData;
}

boolean hardReset() {

  digitalWrite(ESP8266_CHPD,LOW);
  delay(100);
  digitalWrite(ESP8266_CHPD,HIGH);
  delay(1000);
 
  clearSerialBuffer();
  espSerial.println("AT+RST");
  while (!(UCSR0A & _BV(TXC0)));
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
  connectWiFi("SSID", "PASSWORD");
  wdt_reset();
 
  //test if the module is ready
  espSerial.println("AT");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
  //Change to mode 1
  espSerial.println("AT+CWMODE=1");
  espSerial.find("OK");
  clearSerialBuffer();
  delay(10);
 
  //set the multiple connection mode
  espSerial.println("AT+CIPMUX=1");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
 
  //set the server of port 80 check "no change" or "OK"
  espSerial.println("AT+CIPSERVER=1,80");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
 
  //set time out
 
  espSerial.println("AT+CIPSTO=15");
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
}


void clearSerialBuffer(void) {
  while ( espSerial.available() > 0 ) {
    espSerial.read();
  }
}

void clearBuffer(void) {
  for (int i =0;i<BUFFER_SIZE;i++ ) {
    buffer[i]=0;
  }
}

boolean connectWiFi(String NetworkSSID,String NetworkPASS) {
  String cmd = "AT+CWJAP=\"";
  cmd += NetworkSSID;
  cmd += "\",\"";
  cmd += NetworkPASS;
  cmd += "\"";

  espSerial.println(cmd);
  while (!(UCSR0A & _BV(TXC0)));
  espSerial.find("OK");
  delay(10);
  clearSerialBuffer();
}

int formSize(){
 
      FLASH_STRING_ARRAY(plug_names, PSTR("Lights"), PSTR("Return Pump"),
    PSTR("Heater #1"), PSTR("Heater #2"), PSTR("Auto-top Off"), PSTR("Vortech #1"),
    PSTR("Powerhead"), PSTR("Reactor"), PSTR("Sump Light"));
   
    int byteSize=0;
    int i ;
    for (i=0; i<NUMBER_OF_PLUGS;i++){
      if(digitalRead(plug_pins[i])){
        byteSize=byteSize+plug_names[i].length();
        byteSize=byteSize+on1.length();
        byteSize=byteSize+on2.length();
        byteSize=byteSize+on3.length();
        byteSize=byteSize+on4.length();
        byteSize=byteSize+on5.length();
        if(plug_pins[i]<10){
           byteSize=byteSize + 1; // 2 bytes per int and each is used twice to label the radio buttons
        }
        else{
          byteSize=byteSize + 2;
        }
}
      else{
         byteSize=byteSize+plug_names[i].length();
        byteSize=byteSize+off1.length();
        byteSize=byteSize+off2.length();
        byteSize=byteSize+off3.length();
        byteSize=byteSize+off4.length();
        byteSize=byteSize+off5.length();
        if(plug_pins[i]<10){
           byteSize=byteSize + 1;  // 2 bytes per int and each is used twice to label the radio buttons
        }
        else{
          byteSize=byteSize + 2;
        }
      }
    }
  return byteSize;
}

void print_form(){
 
    FLASH_STRING_ARRAY(plug_names, PSTR("Lights"), PSTR("Return Pump"),
    PSTR("Heater #1"), PSTR("Heater #2"), PSTR("Auto-top Off"), PSTR("Vortech #1"),
    PSTR("Powerhead"), PSTR("Reactor"), PSTR("Sump Light"));
 
   
  int i ;
    for (i=0; i<NUMBER_OF_PLUGS;i++){
     
      //Print the name of the Plug
     
       if(digitalRead(plug_pins[i])){
        on1.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        espSerial.print(plug_pins[i]);
        while (!(UCSR0A & _BV(TXC0)));
       
        on2.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        on3.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        plug_names[i].print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        //espSerial.print(plug_pins[i]);
        //while (!(UCSR0A & _BV(TXC0)));
       
        on4.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        on5.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
 
}
      else{
        off1.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        espSerial.print(plug_pins[i]);
        while (!(UCSR0A & _BV(TXC0)));
       
        off2.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        off3.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        plug_names[i].print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
        //espSerial.print(plug_pins[i]);
        //while (!(UCSR0A & _BV(TXC0)));
       
        off4.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       

        off5.print(espSerial);
        while (!(UCSR0A & _BV(TXC0)));
       
    }
}
}

void functionSwitch(int pin){
 
  boolean pinState = LOW;
  if (digitalRead(pin) == LOW){
          pinState = HIGH;
  }
        else{
          pinState = LOW;
        }
        digitalWrite(pin, pinState);
        delay(5);
}


void ledBlink()
{
  static unsigned int  ledStatus = LOW;  // Last set LED mode.
  static unsigned long ledBlinkTime = 0; // LED blink time.
  static unsigned long espTime = millis()+ESPRESET_MS; // LED blink time.
 

  // LED blinking heartbeat. Yes, we are alive.
  // For explanation, see:
  // http://playground.arduino.cc/Code/TimingRollover
  if ( (long)(millis()-ledBlinkTime) >= 0 )
  {
    // Toggle LED.
    ledStatus = (ledStatus==HIGH ? LOW : HIGH);

    // Set LED pin status.
    digitalWrite(ledPin, ledStatus);

    // Reset "next time to toggle" time.
    ledBlinkTime = millis()+LEDBLINK_MS;
  }
 
 
  if ( (long)(millis()-espTime) >= 0 )
  {

    hardReset();
   
    espTime = millis()+ESPRESET_MS;
  }
 
} // End of ledBlink()

/*
int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}



int find_text(String needle, String haystack) {
  int foundpos = -1;
  for (int i = 0; (i < haystack.length() - needle.length()); i++) {
    if (haystack.substring(i,needle.length()+i) == needle) {
      foundpos = i;
    }
  }
  return foundpos;
}
*/