cb77
Published © GPL3+

Temp & Humidity Chart using websockets and HighCharts

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

IntermediateFull instructions provided2 hours3,627
Temp & Humidity Chart using websockets and HighCharts

Things used in this project

Hardware components

Arduino MKR1000
Arduino MKR1000
×1
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Solderless Breadboard Half Size
Solderless Breadboard Half Size
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

DHT11 connection

Code

Arduino Websockets and DHT11 code

Arduino
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 code

HTML
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>

Credits

cb77
6 projects • 5 followers
Contact

Comments

Please log in or sign up to comment.