-->
Page 1 of 14

ESP8266 AJAX [SOLVED]

PostPosted: Fri Jul 31, 2015 5:06 am
by katz
Hi all,

I am trying to get a dynamic website from my ESP8266 server. It should update the runtime of the ESP every second. I have prepared some code that doesn't work ... yet. It hangs in the javascript part where it tests for 'readyState==4' and 'status==200'. This test fails and it triggers an alert.

The ESP does serve xml-data. The ulr 'http://192.168.xxx.yyy/xml' returns a proper xml-formatted page.

How do I get the ESP8266 to deliver the proper readyState and status?

Thanks, Peter.

Code: Select all#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);
const char* ssid="SSID";
const char* password="PASSWORD";
String webSite,javaScript,XML;

void buildWebsite(){
  buildJavascript();
  webSite="<!DOCTYPE HTML>\n";
  webSite+=javaScript;
  webSite+="<BODY onload='process()'>\n";
  webSite+="<BR>This is the ESP website ...<BR>\n";
  webSite+="Runtime = <A id='runtime'>00:00:00</A>\n";
  webSite+="</BODY></HTML>\n";
}

void buildJavascript(){
  javaScript="<SCRIPT>\n";
  javaScript+="var xmlHttp=null;\n";
  javaScript+="if(window.XMLHttpRequest){\n";
  javaScript+="  xmlHttp=new XMLHttpRequest();\n";
  javaScript+="}else{\n";
  javaScript+="  xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');\n";
  javaScript+="}\n";

  javaScript+="function process(){\n";
  javaScript+=" if(xmlHttp.readyState==0 || xmlHttp.readyState==4){\n";
  javaScript+="   xmlHttp.open('GET','/xml',true);\n";
  javaScript+="   xmlHttp.onreadystatechange=handleServerResponse();\n";
  javaScript+="   xmlHttp.send(null);\n";
  javaScript+=" }else{\n";
  javaScript+="   setTimeout('process()',1000);\n";
  javaScript+=" }\n";
  javaScript+="}\n";
 
  javaScript+="function handleServerResponse(){\n";
  javaScript+=" if(xmlHttp.readyState==4 && xmlHttp.status==200){\n";
  javaScript+="   xmlResponse=xmlHttp.responseXML;\n";
  javaScript+="   xmlDocumentElement=xmlResponse.DocumentElement;\n";
  javaScript+="   message=xmlDocumentElement.firstChild.data;\n";
  javaScript+="   document.getElementById('runtime').innerHTML=message;\n";
  javaScript+="   setTimeout('process()',1000);\n";
  javaScript+=" }else{\n";
  javaScript+="   alert('There is a problem ...');\n";
  javaScript+=" }\n";
  javaScript+="}\n";
  javaScript+="</SCRIPT>\n";
}

String millis2time(){
  String Time="";
  unsigned long ss;
  byte mm,hh;
  ss=millis()/1000;
  hh=ss/3600;
  mm=(ss-hh*3600)/60;
  ss=(ss-hh*3600)-mm*60;
  if(hh<10)Time+="0";
  Time+=(String)hh+":";
  if(mm<10)Time+="0";
  Time+=(String)mm+":";
  if(ss<10)Time+="0";
  Time+=(String)ss;
  return Time;
}

void buildXML(){
  XML="<?xml version='1.0'?>";
  XML+="<response>";
  XML+=millis2time();
  XML+="</response>";
}

void handleWebsite(){
  buildWebsite();
  server.send(200,"text/html",webSite);
}

void handleXML(){
  buildXML();
  server.send(200,"text/xml",XML);
}

void setup() {
  Serial.begin(115200); 
  WiFi.begin(ssid,password);
  while(WiFi.status()!=WL_CONNECTED)delay(500);
  WiFi.mode(WIFI_STA);
  Serial.println("\n\nBOOTING ESP8266 ...");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("Station IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/",handleWebsite);
  server.on("/xml",handleXML);
  server.begin(); 
}

void loop() {
  server.handleClient();
}

Re: ESP8266 AJAX

PostPosted: Sun Aug 02, 2015 2:57 am
by katz
Hi all,

I got it to work!! I had a Eureka-moment when I replaced the 'GET' method by the 'PUT' method. Now the website remains static and only the desired parts are updated. I think this is awesome. It gives me a wireless alternative to the serial monitor. Now I can watch variables (switches, temperatures, IR-sensors etc.) in realtime and in a browser without having to refresh it all the time.

Below is the code I wrote. It is complete and should work in your ESP, so check it out. It seems pretty stable and it works in Chrome, Firefox, IE and on my phone (Android). It only crashes when there are multiple browsers accessing the ESP at the same time.

If you have any ideas to make my code better or to solve the multiple-access-crashing problem, please leave a message here.

Thanks, Peter.

Code: Select all#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);
const char* ssid="SSID";
const char* password="PASSWORD";
String webSite,javaScript,XML;

void buildWebsite(){
  buildJavascript();
  webSite="<!DOCTYPE HTML>\n";
  webSite+=javaScript;
  webSite+="<BODY onload='process()'>\n";
  webSite+="<BR>This is the ESP website ...<BR>\n";
  webSite+="Runtime = <A id='runtime'></A>\n";
  webSite+="</BODY>\n";
  webSite+="</HTML>\n";
}

void buildJavascript(){
  javaScript="<SCRIPT>\n";
  javaScript+="var xmlHttp=createXmlHttpObject();\n";

  javaScript+="function createXmlHttpObject(){\n";
  javaScript+=" if(window.XMLHttpRequest){\n";
  javaScript+="    xmlHttp=new XMLHttpRequest();\n";
  javaScript+=" }else{\n";
  javaScript+="    xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');\n";
  javaScript+=" }\n";
  javaScript+=" return xmlHttp;\n";
  javaScript+="}\n";

  javaScript+="function process(){\n";
  javaScript+=" if(xmlHttp.readyState==0 || xmlHttp.readyState==4){\n";
  javaScript+="   xmlHttp.open('PUT','xml',true);\n";
  javaScript+="   xmlHttp.onreadystatechange=handleServerResponse;\n"; // no brackets?????
  javaScript+="   xmlHttp.send(null);\n";
  javaScript+=" }\n";
  javaScript+=" setTimeout('process()',1000);\n";
  javaScript+="}\n";
 
  javaScript+="function handleServerResponse(){\n";
  javaScript+=" if(xmlHttp.readyState==4 && xmlHttp.status==200){\n";
  javaScript+="   xmlResponse=xmlHttp.responseXML;\n";
  javaScript+="   xmldoc = xmlResponse.getElementsByTagName('response');\n";
  javaScript+="   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript+="   document.getElementById('runtime').innerHTML=message;\n";
  javaScript+=" }\n";
  javaScript+="}\n";
  javaScript+="</SCRIPT>\n";
}

void buildXML(){
  XML="<?xml version='1.0'?>";
  XML+="<response>";
  XML+=millis2time();
  XML+="</response>";
}
String millis2time(){
  String Time="";
  unsigned long ss;
  byte mm,hh;
  ss=millis()/1000;
  hh=ss/3600;
  mm=(ss-hh*3600)/60;
  ss=(ss-hh*3600)-mm*60;
  if(hh<10)Time+="0";
  Time+=(String)hh+":";
  if(mm<10)Time+="0";
  Time+=(String)mm+":";
  if(ss<10)Time+="0";
  Time+=(String)ss;
  return Time;
}

void handleWebsite(){
  buildWebsite();
  server.send(200,"text/html",webSite);
}

void handleXML(){
  buildXML();
  server.send(200,"text/xml",XML);
}

void setup() {
  Serial.begin(115200); 
  WiFi.begin(ssid,password);
  while(WiFi.status()!=WL_CONNECTED)delay(500);
  WiFi.mode(WIFI_STA);
  Serial.println("\n\nBOOTING ESP8266 ...");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("Station IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/",handleWebsite);
  server.on("/xml",handleXML);
  server.begin(); 
}

void loop() {
  server.handleClient();
}

Re: ESP8266 AJAX [SOLVED]

PostPosted: Sun Aug 02, 2015 11:22 am
by ragoth
Hi,
Your ESP8266 AJAX web server is very impressive. Please give me the link for correct type of library files ESP8266WiFi.h ,
ESP8266WebServer.h. I tried using the one in (esp8266-Arduino-master) and it does not recognize and says No such file or directory.
Please Help.
Best Regards,
Ragothamann R.

Re: ESP8266 AJAX [SOLVED]

PostPosted: Sun Aug 02, 2015 1:33 pm
by Stoney
Dude !
You are a fricking legend .. I have so many uses for this as I want to use them for simple debugging at times...
now .. just need to make it into a rs232 bridge and I will be in heaven..

(1 hour later)

...and after nearly an hour I am still lost :)

need to learn xml and javascript I think..
back after some studying !