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.

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.

0

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.