UNO Webserver - ESP8266 Hangs
Posted: Sat Jan 03, 2015 2:06 pm
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!!
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>      <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;
}
*/