0

I am developing a system that reads data from an LM35 temperature sensor and forwards it to a web page using an Arduino Uno and a ESP8266 WiFi Module. The data flow is as follows:

LM35 --> Arduino Uno --> ESP8266 (Having a web server) --> Webpage

The Uno sends data to the ESP8266 every SAMPLE_RATE seconds (4 seconds in my example) but the ESP8266 keeps updating the web page as it is a dynamic web page running AJAX. The problem is that I can see the data updating only once in a while (I assume when the 4 second delay aligns with the instant when the ESP8266 updates the value on the web page).

How can I make it so that even if The Uno doesn't send new values (during the 4 second gap), the ESP8266 keeps updating the web page with the old values? I have tried numerous times but have failed. Here is my code so far:

ARDUINO SIDE:

#include <SoftwareSerial.h>
#include <String.h>
//a Header for the Filtering Algorithm
//*******************************************************************/
//#include "Filter.h"
//*******************************************************************/
//Set RESET PIN for ESP8266
//*******************************************************************/
#define RST_PIN_ESP8266 13
//*******************************************************************/
//Define Baud rate for Serial Communication and ESP8266 Software Serial
//*******************************************************************/
#define SERIAL_BAUD_RATE 9600
#define ESP8266_SOFT_SERIAL_BAUD_RATE 9600
//*******************************************************************/
//LM35 Temperature sensor used for this code
//*******************************************************************/
#define LM35 A0
//*******************************************************************/
//Define Sensor sampling rate
//*******************************************************************/
#define SAMPLE_RATE 4000
//*******************************************************************/
//Code Features . . Uncomment to enable
//*******************************************************************/
//#define LM35_RAW_DEBUG
//#define TEMP_READ
//#define PRINT_DEBUG
#define MEASURE_SALINE
//*******************************************************************/
//ESP8266 Software Serial Object
//*******************************************************************/
SoftwareSerial ESP8266_Serial(6,7);
//*******************************************************************/
//Global Variables
//*******************************************************************/
float tempC;
long rawValue = 0, initCount = 0;
int initRawValue = 0, i, START_VALUE = 0;
int SALINE_STARTED = 0, SALINE_IN_PROGRESS = 1, SALINE_EXHAUSTED = 2;
int saline_status_flag = 0;
String finalMSG;
//*******************************************************************/
//Needed objects for time counting and filtering
//*******************************************************************/
unsigned long StartTime = millis();
//ExponentialFilter<int> ADCFilter(5, 0);
//*******************************************************************/
void setup() {
 long rawValue = 0, initCount = 0;
 int initRawValue = 0, i;
 //Set up Serial Communication
 Serial.begin(SERIAL_BAUD_RATE);
 ESP8266_Serial.begin(ESP8266_SOFT_SERIAL_BAUD_RATE);
 pinMode(RST_PIN_ESP8266, OUTPUT);
 Reset_ESP8266();
 while(ESP8266_Serial.available()) {
 getIP(); // Obtain IP for ESP8266
 }
 delay(1000);
 //Increase accuracy
 analogReference(INTERNAL);
 //Start Sensor Calibration
 #ifdef MEASURE_SALINE
 Serial.print(". . . CALIBRATING SYSTEM . . .\n");
 #ifdef PRINT_DEBUG
 Serial.println("\n\nTime Elapsed :\n\n");
 #endif
 here:
 unsigned long currentTime = millis();
 unsigned long elapsedTime = currentTime - StartTime;
 #ifdef PRINT_DEBUG
 Serial.println(elapsedTime);
 #endif
 if(elapsedTime < 20000) {
 initCount++;
 rawValue += analogRead(LM35);
 #ifdef PRINT_DEBUG
 Serial.println(rawValue);
 #endif 
 goto here;
 }
 currentTime = 0;
 elapsedTime = 0;
 rawValue = rawValue / initCount;
 //Averaging from 5000 sensor samples
 initRawValue = rawValue;
 START_VALUE = initRawValue;
 Serial.println("\n. . . CALIBRATION COMPLETE . . .");
 Serial.print("\nInitial Raw LM35 Value : ");
 Serial.print(START_VALUE);
 Serial.print("\n\n");
 Reinitialize_Variables();
 delay(2000);
 #ifdef PRINT_DEBUG
 Serial.println("\nLM35 Sample Count:\n");
 Serial.println(initCount);
 #endif
 #endif
 initCount = 0;
 #ifdef LM35_RAW_DEBUG
 Serial.println("\n. . . STARTING LM35 DEBUG READING . . .\n\n");
 #endif
 #ifdef MEASURE_SALINE
 Serial.println("\n. . . STARTING SALINE MONITORING. . .\n\n");
 #endif
}
void loop() {
 #ifdef MEASURE_SALINE
 Measure_Saline();
 #endif
 #ifdef LM35_RAW_DEBUG
 rawValue = analogRead(LM35);
 Serial.println(rawValue);
 #endif
 #ifdef TEMP_READ
 Read_Temp();
 #endif
 Reinitialize_Variables();
}
void Measure_Saline() {
 int dont_print_flag = 0;
 unsigned long StartTime = millis();
 //Take readings (SAMPLE_RATE times) and average them
 here:
 unsigned long currentTime = millis();
 unsigned long elapsedTime = currentTime - StartTime;
 #ifdef PRINT_DEBUG
 Serial.println(elapsedTime);
 #endif
 if(elapsedTime < SAMPLE_RATE) {
 initCount++;
 rawValue += analogRead(LM35);
 #ifdef PRINT_DEBUG
 Serial.println(rawValue);
 #endif
 goto here;
 }
 currentTime = 0;
 elapsedTime = 0;
 rawValue = rawValue / initCount;
 #ifdef PRINT_DEBUG
 Serial.print("initCount : ");
 Serial.print(initCount);
 #endif
 if(saline_status_flag != SALINE_EXHAUSTED) {
 if(rawValue < START_VALUE) {
 saline_status_flag = SALINE_STARTED;
 } else if(rawValue == START_VALUE) {
 saline_status_flag = SALINE_IN_PROGRESS;
 } else if(rawValue > START_VALUE) {
 START_VALUE = rawValue;
 delay(1000);
 rawValue = analogRead(LM35);
 delay(10);
 if(rawValue > START_VALUE) {
 saline_status_flag = SALINE_EXHAUSTED;
 dont_print_flag = 1;
 Serial.print(rawValue);
 Serial.print(" Saline bottle EXHAUSTED\n");
 finalMSG = (String(rawValue) + " EXHAUSTED\n");
 ESP8266_Serial.println(finalMSG);
 }
 }
 //Saline Therapy Ongoing
 if((saline_status_flag == SALINE_STARTED || saline_status_flag == SALINE_IN_PROGRESS) && dont_print_flag == 0) {
 Serial.print(rawValue);
 Serial.print(" Saline Therapy IN PROGRESS\n");
 finalMSG = (String(rawValue) + " IN PROGRESS\n");
 ESP8266_Serial.println(finalMSG);
 } else if(saline_status_flag == SALINE_EXHAUSTED && dont_print_flag == 0) {
 //Saline Exhausted
 Serial.print(rawValue);
 Serial.print(" Saline bottle EXHAUSTED\n");
 finalMSG = (String(rawValue) + " EXHAUSTED\n");
 ESP8266_Serial.println(finalMSG);
 }
 START_VALUE = rawValue;
 } else {
 Serial.print(" Saline bottle EXHAUSTED\n");
 finalMSG = (String(rawValue) + " EXHAUSTED\n");
 ESP8266_Serial.println(finalMSG);
 }
 delay(200);
}
void Read_Temp() {
 rawValue = analogRead(LM35);
 tempC = rawValue * 0.48828125;
 tempC = rawValue / 9.31;
 Serial.println(tempC);
 delay(2000);
}
void Reinitialize_Variables() {
 initCount = 0;
 rawValue = 0;
 initRawValue = 0;
 i = 0;
}
void getIP() {
 Serial.println(ESP8266_Serial.readStringUntil('\n'));
}
void Reset_ESP8266() {
 pinMode(RST_PIN_ESP8266, OUTPUT);
 digitalWrite(RST_PIN_ESP8266, HIGH);
 // (RST_PIN_ESP8266 = 1 -> RESET = 0 so ESP8266 RESET FALSE) 
 delay(1000); 
 digitalWrite(RST_PIN_ESP8266, LOW);
 // (RST_PIN_ESP8266 = 0 -> RESET = 1 so ESP8266 RESET TRUE)
 delay(1000);
 digitalWrite(RST_PIN_ESP8266, HIGH);
 // (RST_PIN_ESP8266 = 1 -> RESET = 0 so ESP8266 RESET FALSE)
 delay(50);
}

ESP8266 side:

/*
 * This Code is for the ESP8266 WiFi Module. It builds a website running AJAX (Asynchronous JavaScript and XML)
 * which allows this webpage to update itself without having to refresh itself which may not be resource friendly
 */
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#define DEVICE_ID 1
ESP8266WebServer server(80);
const char* ssid="COLDSPOT"; // WiFi Access Point to connect to
const char* password="1234567890"; // Password for the Access Point
String webSite,javaScript,XML;
void buildWebsite() {
 buildJavascript();
 webSite = "<!DOCTYPE HTML>\n";
 webSite += javaScript;
 webSite += "<BODY onload='process()'>\n";
 webSite += "<h1 align='center'><BR>SALINE MONITORING:<BR><h1>\n";
 webSite += "STATUS = <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 += DataFromArduino(); //incoming data from Arduino. It means it is the value of mapping function.
 XML += "</response>";
}
String DataFromArduino() {
 String coming;
 if(Serial.available()) {
 while(Serial.available()) {
 coming = Serial.readStringUntil('\n');
 delay(1);
 } // it is getting via serial port.
 return coming;
 } else {
 return coming;
 }
}
void handleWebsite() {
 buildWebsite();
 server.send(200,"text/html",webSite);
}
void handleXML() {
 buildXML();
 server.send(200,"text/xml",XML);
}
void setup() {
 Serial.begin(9600); 
 WiFi.begin(ssid,password); //trying to connect the modem
 while(WiFi.status() != WL_CONNECTED) {
 delay(500);
 }
 WiFi.mode(WIFI_STA);
 Serial.println("\n\n. . . BOOTING ESP8266 . . .\n");
 Serial.print("DEVICE ID : ");
 Serial.print(DEVICE_ID);
 Serial.print("\n");
 Serial.print("CONNECTED TO ACCESS POINT : ");
 Serial.println(ssid);
 Serial.flush();
 Serial.println(WiFi.localIP());
 //it is sending the IP to Arduino's port. So I can see the IP on Serial Monitor
 Serial.flush();
 server.on("/", handleWebsite);
 //it is all about setting of server.
 server.on("/xml",handleXML);
 server.begin(); 
}
void loop() {
 server.handleClient();
}

Please note that I have already changed the baud rate of the ESP8266 to 9600. I am using THIS ESP8266 Module.

dda
1,5951 gold badge12 silver badges17 bronze badges
asked Oct 12, 2017 at 5:16

1 Answer 1

0

If you take the variable String coming out of the function DataFromArduino() and make it a global variable (by adding it to the line after String website1). That way it will store its value between calls to DataFromArduino() and return the same result if it has had nothing new.

answered Oct 12, 2017 at 7:40
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.