Project tutorial
Temp & Humidity Chart using websockets and HighCharts

Temp & Humidity Chart using websockets and HighCharts © GPL3+

Using websockets on one Arduino MKR1000 connected to wifi, I send temp & humidity data to a chart setup on HighCharts.

  • 1,817 views
  • 0 comments
  • 4 respects

Components and supplies

Apps and online services

About this project

I had a problem with my A/C and I wanted to control the temperature and the humidity. I found that the best way was using the arduino, websockets, a DHT11 sensor and a web browser.

The first problem I got was to find a websockets library that works in the MKR1000.

Finally somebody in arduino.stackexchange.com recommended me the NINA-Websocket library from Ocrdu that works perfect..

The arduino is connected to the DHT11 sensor using digital pin 2 to the DHT11 signal pin (view diagram). This pin may be changed in the code using the variable DHTPIN. DHT11 send every 2 seconds a sample of comma separated values of temperature & humidity.

Now the process is like this:

1. The MKR1000 connects to wifi and sends to serial monitor the connection info (IP and others). When the wifi is not connected the built in led is off and on when it is connected.

2. It wait for a client to connect.

3. To connect to the server from the client, you have to enter in the client the IP(from 1.) and the port selected (defaults is 80), again you may change in the code this value using variable webSocketPort, the value you have to enter in the web browser is like this:

http://IP:websocketport,

ie.

http://192.168.1.100:80.

Then click open and the chart start to receive data from the arduino and displayed it.

4. When the client is connected, it starts to send the sensor data to the client and the built in led blink.

5. The data the client receives every two second approx is displayed on the chart.

Code

Arduino Websockets and DHT11 codeArduino
Websockets manage the comunication between the arduino and the client(web browser)
#include <SPI.h>
#include <WiFi101.h>
#include <WebSocketServer.h>  //use NINA-Websocket-master
#include <Base64.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 2         // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11    // DHT 11

char ssid[] = "XXXX"; //  your network SSID (name)
char pass[] = "XXXX";    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;

int webSocketPort = 80;
WiFiServer server(webSocketPort);
WebSocketServer webSocketServer;
DHT dht(DHTPIN, DHTTYPE);

String sendSensorData(){
    // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return "";
  }
  String data = String(t) + "," + String(h);
  //Serial.println(data);
  return data;
}
  
void blink() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on 
  delay(100);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off 
  delay(100);                       // wait for a second
}
void WiFiConnect(){

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }
  
  // Attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    //Serial.print(" .");
    // wait 5 seconds to reconnect
    delay(5000);
  }

  // you're connected now, so print out the status:
  printWifiStatus();
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
 
  Serial.print("IP Address: ");
  Serial.println(ip);
  
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);
  Serial.print("WebsoketServer on: http://" ); Serial.print(ip); Serial.println( "/:" + String(webSocketPort) ); 
}

void setup() {
  
  //Initialize serial
  Serial.begin(9600);

  // Setup builtin led
  pinMode(LED_BUILTIN, OUTPUT);
  // turn the LED OFF (LOW on disconnect)
  digitalWrite(LED_BUILTIN, LOW);   
 
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  //Connect WiFI
  WiFiConnect();
  

  
 // turn the LED on (HIGH on connect)
  digitalWrite(LED_BUILTIN, HIGH);
  
  // start the server:
  server.begin();
  //start Temp/Hum sensor
  dht.begin();
}

void loop() {
  String data;
  //Is a client connected?
  WiFiClient client = server.available();
  
  if (client.connected() && webSocketServer.handshake(client)) { //If client connected and handshake with websocket is true continue

    while (client.connected()) { //if client is connected start to blink and send the data
      blink();

      // This is only to receive the open and close message from the client
      data = webSocketServer.getData();

      if (data.length() > 0) {
        //handleClientData(data);
        Serial.println("Received from Client: " + data);
      }

      //Get data from DHT11 and send to the client
      if ((data = sendSensorData()) != "") {
        webSocketServer.sendData(data);
        //Serial.println(data);
      }
    }
  }
  
  // wait to let the client disconnect
  delay(100);
}
HTML codeHTML
This is the HTML code that connect the arduino/websockets whith the chart using highcharts
<html>
<head>
  <title>Temperature & Humidity Chart</title>
	
  <!-- Compressed JavaScript Library  and Themes-->
	<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
  <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>  
 
  <!-- Charts Library -->
	<script src="https://code.highcharts.com/stock/highstock.js"></script>
	<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
	<script src="https://code.highcharts.com/stock/modules/export-data.js"></script>
    	
  <style>
    body {
      font-size: 16px;
      font-family: verdana,helvetica,arial,sans-serif;
    }
  </style>
</head>


<body>

	<div id="container" style="min-width: 310px; height: 600px; margin: 0 auto"></div>


	<script>
		var ws;
     
	  $(function() { 
			$("#close").click(function(evt){
				if( typeof ws != "undefined"){
					if(ws.readyState != 3 && ws.readyState != 4 ){
						ws.send("Close");
						ws.close();
					}
				}						
			});
	  	
	  	//Open websocket
		  $("#open").click(function(evt){
		  	var host = $("#host").val();
	      var port = $("#port").val();
	      var uri = $("#uri").val();
				//start highstock
	      var mainChart = new Highcharts.stockChart(chartOptions);
	              
	      // create websocket instance
	      ws = new WebSocket("ws://" + host + ":" + port + uri);
	       
	      // Close callback
	      ws.onclose = function(evt) {
	        //change color of labels to red
	        $("#host").css("background", "#ff0000"); 
	        $("#port").css("background", "#ff0000"); 
	        $("#uri").css("background",  "#ff0000");
	        $("div#message_details").hide();
	
	        };
	
	      // Open Websocket callback
	      ws.onopen = function(evt) { 
	        //change color of labels to green
	        $("#host").css("background", "#00ff00"); 
	        $("#port").css("background", "#00ff00"); 
	        $("#uri").css("background", "#00ff00");
					ws.send("Open");
	      };
	      //receive message callback
  			ws.onmessage = function(evt) {
    			var dataStr = [];
    			dataStr = evt.data.split(",");
    			// Series idx 0=Temp idx 1=Hum 
    			var seriesT = mainChart.series[0];
    			var seriesH = mainChart.series[1];
    			var temp = parseFloat(dataStr[0]);
    			var hum = parseFloat(dataStr[1]);
					var myEpoch = new Date().getTime(); //get current epoch time    			 				          
		        
					seriesT.addPoint([myEpoch, temp]);
					seriesH.addPoint([myEpoch, hum]);
 	      };
    	});
  });
	  
  
	</script>
	
	<script>
		Highcharts.setOptions({
  		global: 
  		{
      	useUTC: false
  		}
		});
    
    var tempdata;
    var humData;
		var chartOptions = {  
		chart: {
		  renderTo: 'container',
		  type: 'spline',
		  animation: false,
	  },
 		
 		title: {
        text: 'Temperature & Humidity vs Time'
    },
		xAxis: 	{
		  type: 'datetime',
		  tickPixelInterval:150,
		  labels: {
				format: '{value:%H:%M:%S}',
				rotation: 45,
				align: 'left'
			}
		},
    yAxis: [{
      title: {
        text: 'Temperature(°C)',
				style: {
        	color: Highcharts.getOptions().colors[1]
        }        
      },
		  tickInterval:1,
			labels: {
    		format: '{value}°',
    		style: {
        	color: Highcharts.getOptions().colors[1]
        }
      },
      opposite:false,
    },{
      title: {
	    text: 'Humidity',
			style: {
      	color: Highcharts.getOptions().colors[0]
        }
		  },
		  tickInterval:5,
			max:100,
			labels: {
    		format: '{value}\%',
    		style: {
        	color: Highcharts.getOptions().colors[0]
        }
      },
    	opposite:true
    }],

    rangeSelector: {
    	enabled: true,
    	inputEnabled: false,
      buttons: [{
          count: 6,
          type: 'hour',
          text: '6h'
      }, {
          count: 12,
          type: 'hour',
          text: '12h'
      }, {
          type: 'all',
          text: 'All'
      }],
    },
		legend: {
		    enabled: false
		},
		exporting:{
		        enabled: false
		},
		plotOptions: {
	  	series: {
        animation: false
    	}
  	},
  	
		series: [{
			name: 'Temp',
		  data: tempdata,
			color: Highcharts.getOptions().colors[1],
		},
	  {
			name: 'Hum',
		  data: humData,
			color: Highcharts.getOptions().colors[0],
		  yAxis:1 
	  }				  			
	]		
	}
		
		
	</script>
	


	<div id="connection_details">
	    <label for="host">host:</label>
	    <input type="text" id="host" value="192.168.1.110" style="background:#ff0000;"/>
	    <label for="port">port:</label>
	    <input type="text" id="port" value="80" style="background:#ff0000;"/>
	    <label for="uri">uri:  </label>
	    <input type="text" id="uri" value="/ws" style="background:#ff0000;"/>
	    <input type="submit" id="open" value="Open" />
	    <input type="button" id="close" value="Close" />
	</div>
    
	</body>
</html>

Schematics

DHT11 connection
Dht11 ftqzirjhmn

Comments

Similar projects you might like

MKR1000 Temp and Humidity Sensor

Project tutorial by Don Coleman

  • 27,876 views
  • 11 comments
  • 41 respects

Temperature and Humidity Data Logger

Project tutorial by Wimpie van den Berg

  • 43,743 views
  • 4 comments
  • 37 respects

How to read temperature and humidity on Blynk with DHT11

Project tutorial by PrinceMatthew

  • 28,949 views
  • 6 comments
  • 23 respects

Project KOOL: Temperature and Humidity Remote Monitoring

Project tutorial by vincent wong

  • 8,908 views
  • 1 comment
  • 22 respects

Arduino Temperature - Humidity - Rain Sensor

Project showcase by Mako

  • 24,427 views
  • 7 comments
  • 25 respects
Add projectSign up / Login