ESP8266 data logging with real time graphs

In this tutorial we are going to make really really cool thing with NodeMCU ESP8266. That is data logger web server with real time graphs and tables, mostly seen on thingspeak. But this time we are putting complete graphs and tables all inside NodeMCU without using thingspeak. For this we need graphs library that we are using from chartsjs.org an open source Chart drawing library and Knowledge of alax, html and javascipt.Node MCU data logger

Things we need

  1. NodeMCU ESP8266
  2. USB Cable
  3. Laptop
  4. Internet and wifi router

Programming NodeMCU

To draw graphs we use chart.js from CDN. you can use char.js file directly inside the NodeMCU for this see : AJAX Web Server

To get knowledge of real time data update without refresh read this.

Program consists of two parts one is HTML, Javascipts and Arduino Code

Arduino IDE Code For Graphs ESP8266 and Data Logging

Before directly uploading make changes in WiFi SSID and Password as per yours WiFi. most of the things are explained inside code comments. also make index.h header file and save it near to your ino file.

In this example we are creating web server inside ESP8266 for data logging. It has two parts one part that displays HTML web GUI and second is that takes AJAX request and reads ADC data.

ESPGraph.ino File

/*
 * ESP8266 NodeMCU Real Time Graphs Demo
 * Updates and Gets data from webpage without page refresh
 * https://circuits4you.com
 */
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

#include "index.h" //Our HTML webpage contents with javascripts

#define LED 2  //On board LED

//SSID and Password of your WiFi router
const char* ssid = "your-wifi";
const char* password = "your-password";

ESP8266WebServer server(80); //Server on port 80

//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}

void handleADC() {
 int a = analogRead(A0);
 String adcValue = String(a);
 digitalWrite(LED,!digitalRead(LED)); //Toggle LED on data request ajax
 server.send(200, "text/plane", adcValue); //Send ADC value only to client ajax request
}
//==============================================================
//                  SETUP
//==============================================================
void setup(void){
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);     //Connect to your WiFi router
  Serial.println("");

  //Onboard LED port Direction output
  pinMode(LED,OUTPUT); 
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //If connection successful show IP address in serial monitor
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //IP address assigned to your ESP
 
  server.on("/", handleRoot);      //Which routine to handle at root location. This is display page
  server.on("/readADC", handleADC); //This page is called by java Script AJAX

  server.begin();                  //Start server
  Serial.println("HTTP server started");
}
//==============================================================
//                     LOOP
//==============================================================
void loop(void){
  server.handleClient();          //Handle client requests
}

index.h HTML Code File for data logger

const char MAIN_page[] PROGMEM = R"=====(
<!doctype html>
<html>

<head>
	<title>Line Chart | Circuits4you.com</title>
	<!--For offline ESP graphs see this tutorial https://circuits4you.com/2018/03/10/esp8266-jquery-and-ajax-web-server/ -->
	<script src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>	
	<style>
	canvas{
		-moz-user-select: none;
		-webkit-user-select: none;
		-ms-user-select: none;
	}

	/* Data Table Styling */
	#dataTable {
	  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
	  border-collapse: collapse;
	  width: 100%;
	}

	#dataTable td, #dataTable th {
	  border: 1px solid #ddd;
	  padding: 8px;
	}

	#dataTable tr:nth-child(even){background-color: #f2f2f2;}

	#dataTable tr:hover {background-color: #ddd;}

	#dataTable th {
	  padding-top: 12px;
	  padding-bottom: 12px;
	  text-align: left;
	  background-color: #4CAF50;
	  color: white;
	}
	</style>
</head>

<body>
    <div style="text-align:center;"><b>Circuits4you.com</b><br>Real Time Data Logging with Graphs on ESP8266</div>
    <div class="chart-container" position: relative; height:350px; width:100%">
        <canvas id="Chart" width="400" height="400"></canvas>
    </div>
<div>
	<table id="dataTable">
	  <tr><th>Time</th><th>ADC Value</th></tr>
	</table>
</div>
<br>
<br>	

<script>
//Graphs visit: https://www.chartjs.org
var values = [];
var timeStamp = [];
function showGraph()
{
    for (i = 0; i < arguments.length; i++) {
    	values.push(arguments[i]);    
    }

    var ctx = document.getElementById("Chart").getContext('2d');
    var Chart2 = new Chart(ctx, {
        type: 'line',
        data: {
            labels: timeStamp,	//Bottom Labeling
            datasets: [{
                label: "Voltage 1",
                fill: false,	//Try with true
                backgroundColor: 'rgba( 243, 156, 18 , 1)', //Dot marker color
                borderColor: 'rgba( 243, 156, 18 , 1)',	//Graph Line Color
                data: values,
            }],
        },
        options: {
            title: {
                    display: true,
                    text: "ADC Voltage"
                },
            maintainAspectRatio: false,
            elements: {
            line: {
                    tension: 0.5 //Smoothening (Curved) of data lines
                }
            },
            scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero:true
                        }
                    }]
            }
        }
    });

}

//On Page load show graphs
window.onload = function() {
	console.log(new Date().toLocaleTimeString());
	showGraph(5,10,4,58);
};

//Ajax script to get ADC voltage at every 5 Seconds 
//Read This tutorial https://circuits4you.com/2018/02/04/esp8266-ajax-update-part-of-web-page-without-refreshing/

setInterval(function() {
  // Call a function repetatively with 5 Second interval
  getData();
}, 5000); //5000mSeconds update rate
 
function getData() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
     //Push the data in array
	var time = new Date().toLocaleTimeString();
	var ADCValue = this.responseText; 
      values.push(ADCValue);
      timeStamp.push(time);
      showGraph();	//Update Graphs
	//Update Data Table
	  var table = document.getElementById("dataTable");
	  var row = table.insertRow(1);	//Add after headings
	  var cell1 = row.insertCell(0);
	  var cell2 = row.insertCell(1);
	  cell1.innerHTML = time;
	  cell2.innerHTML = ADCValue;
    }
  };
  xhttp.open("GET", "readADC", true);	//Handle readADC server on ESP8266
  xhttp.send();
}
		
</script>
</body>

</html>

)=====";

Results

Upload code and get IP Address from serial monitor. and enter it in web browser. wait for few seconds and see the updating of graphs.

NodeMCU Data Logging web server

References

  1. AJAX Tutorial
  2. SPIFFS for directly loading java script file.

 

10 thoughts on “ESP8266 data logging with real time graphs

  1. I’m trying to modify this code for my project, I create a click counter per 6 secs program and I want to plot it on the web server but it only appears on the data table not on the plot. Any tips?

  2. Hello,
    Thanks very much for the tutorial and code sample it worked the first time and looks suitable for my application. We are working on an archery IOT device a bit like a golf swing analyser.
    Some modification that I would like to make are the following:

    1. Plot multiple data points on one graph for X,Y,Z acc + heading. Should this be done as a JSON something like this? https://stackoverflow.com/questions/54963564/esp8266-request-multiple-http-get-simultaneously.

    2. Capture about 5 seconds worth of data starting when the bow is drawn, then plot all the data on the graph probably 5 samples per second so a total of 125 data points for 5 sensors.

    3. Be able to do all of this without an active internet connection? Just using the ESP as an AP. Is this going to cause an issue with chart.js? or other scripts loaded from online content.

    Thanks in anticipation.
    Joel

  3. Im a complete beginner. Can you please please please guide me? Just tell me the steps i need to take so i get a direction to move and think. I want to send the ACS712 5A sensor readings from esp8266 to a webserver and visualize the current and power in graphical form. Do i need to learn JQuery/JS/AJAX in detail? I already know html, css, C and some javascript. Thankyou

    1. As you are sending data to web server, You have to learn basics of Javascript, AJAX is just 4 line code (its not language),
      HTML and CSS basics required, And use any Simple Javascript graph library to plot the graphs (Here you need to learn more how to use it to fit for your application?). You can make it, It’s logic not language.

  4. It will be better to use send_P() function to avoid resets, because the PROGMEM is used for large files.
    String s = MAIN_page; //Read HTML contents
    server.send_P(200, “text/html”, s); //Send web page

      1. Sometimes I even can’t see available esp’s WiFi and also Serial monitor returns nothing. Can you provide me correct firmware for this tutorial?

Leave a Reply