Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Gyusik Song
Published © GPL3+

Web-based Temperature and Humidity Monitoring

This project monitors temperature and humidity via web.

BeginnerShowcase (no instructions)1 hour1,247
Web-based Temperature and Humidity Monitoring

Things used in this project

Hardware components

PHPoC Black
PHPoC Black
×1
PHPoC Grove Expansion Board
PHPoC Grove Expansion Board
×1
HTX23C-ST-MR
×1

Story

Read more

Code

task0.php

PHP
<?php

if(_SERVER("REQUEST_METHOD"))
   exit; // avoid php execution via http request

include_once "/lib/sd_340.php";
include "/lib/sn_tcp_ws.php";

define("SLAVE_ID",        1);  // ID of HTX23C
define("FC_03",           3);  // read holding register
define("ADDR_HMID",      21);  // 21-Humidity, 22-Temperature
define("WORD_CNT",        2);  // 2 words (Humidity and Temperature)
define("MAX_NM_INDEX",  240);  // maximum nm index (for 60 seconds)


// frame: ID + function code + address + word count + CRC
function mbus_make_query()
{
   $str = "";
   $str .= int2bin(SLAVE_ID, 1);
   $str .= int2bin(FC_03, 1);
   $str .= int2bin(ADDR_HMID, 2, true);
   $str .= int2bin(WORD_CNT, 2, true);
   $crc_int = (int)system("crc 16 %1 ffff a001 lsb", $str);
   $str .= int2bin($crc_int, 2);
   return $str;
}

// check CRC
function mbus_chk_crc($str)
{
   $msg_len = strlen($str) - 2;
   $crc = bin2int($str, $msg_len, 2);
   $msg = substr($str, 0, $msg_len);
   $crc_chk = (int)system("crc 16 %1 ffff a001 lsb", $msg);
   if($crc_chk != $crc)
      return false;
   else
      return true;
}

echo "Monitoring Humidity and Temperature using HTX23C-ST-MR\r\n";

uart_setup(0, 9600, "N81N");
ws_setup(0, "htx23c", "text.phpoc");

$rwbuf = "";
$wpos = 0;  // next write position of nm
$spos = 0;  // next read position of nm
$slen = 4;  // send string size


// main loop
while(1)
{
   sleep(1);

   // send a query to serial
   $rwbuf = mbus_make_query();
   uart_write(0, $rwbuf);
   usleep(30000);

   // receive a response
   if(!uart_read(0, $rwbuf))
      continue;

   if(mbus_chk_crc($rwbuf) === false)
      continue;

   $hmid = bin2int($rwbuf, 3, 2, true);  // humidity (%)
   $temp = bin2int($rwbuf, 5, 2, true);  // temperature ('C)

   printf("Humidity: %.01f[%%] | Temperature: %.01f['C]\r\n", $hmid / 10.0, $temp / 10.0);

   if($wpos >= MAX_NM_INDEX)
      $wpos = 0;
   if($spos >= MAX_NM_INDEX)
      $wpos = 0;

   // store data into nm0
   nm_write(0, $wpos, $hmid);
   $wpos += 2;
   nm_write(0, $wpos, $temp);
   $wpos += 2;

   if($slen > MAX_NM_INDEX)
   {
      $slen = MAX_NM_INDEX;
      $spos += 4;
   }

   // send data to websocket
   if(ws_state(0) == TCP_CONNECTED)
   {
      $rhmid = 0;
      $rtemp = 0;

      $scnt = $slen / 4;

      // read data from nm0 and send it to websocket
      for($i = 0; $i < $scnt; $i++)
      {
         if($spos >= MAX_NM_INDEX)
            $spos = 0;
         nm_read(0, $spos, $rhmid, 2);
         $spos += 2;
         nm_read(0, $spos, $rtemp, 2);
         $spos += 2;

         $data = sprintf("%.01f,%.01f", $rhmid / 10.0, $rtemp / 10.0);
         ws_write(0, $data);
      }
      $slen = 0;
   }
   $slen += 4;
}

?>

index.php

PHP
Webpage
<?php
$ws_host = _SERVER("HTTP_HOST");
 
set_time_limit(30);
 
?>
<!DOCTYPE html>
<html>
<head>
<title>PHPoC / <?echo system("uname -i")?></title>
<meta content="initial-scale=0.5, maximum-scale=1.0, minimum-scale=0.5, width=device-width" name="viewport">
<style type="text/css">
body {font-family : "calibri"}
</style>
<script type="text/javascript">
var ws;
var canvas;
var ctx;
var WIDTH = 655;
var HEIGHT = 460;
var graphWIDTH = 590;
var graphHEIGHT = 400;
var padding = 30;
var hmids =  Array.apply(null, new Array(60)).map(Number.prototype.valueOf,0);  //init array hmids to 0 
var temps =  Array.apply(null, new Array(60)).map(Number.prototype.valueOf,0);  //init array temps to 0 
 
function addlabels(){
ctx.font = "18px calibri";

/* y axis labels for temp */
ctx.fillStyle = "#DF4D55";
ctx.fillText("T ('C)", 15, 15);
ctx.fillText(" 50", 0, 35);
ctx.fillText(" 40", 0, 115);
ctx.fillText(" 30", 0, 195);
ctx.fillText(" 20", 0, 275);
ctx.fillText(" 10", 0, 355);
ctx.fillText(" 0",  10, 435);

/* y axis labels for hmid */
ctx.fillStyle = "#20B2AA";
ctx.fillText("H (%)", graphWIDTH+15, 15);
ctx.fillText(" 100", graphWIDTH+28, 35);
ctx.fillText(" 80", graphWIDTH+33, 115);
ctx.fillText(" 60", graphWIDTH+33, 195);
ctx.fillText(" 40", graphWIDTH+33, 275);
ctx.fillText(" 20", graphWIDTH+33, 355);
ctx.fillText(" 0",  graphWIDTH+33, 435);

/* x axis labels */
ctx.fillStyle = "#383838";
ctx.fillText("Time (Sec.)", 570, 450);
}
 
function drawguide()
{
    ctx.lineWidth = 0.5;      
    ctx.strokeStyle = "#C3C3C3";
    ctx.beginPath();
    
    //10'c
    ctx.moveTo(padding, 350);
    ctx.lineTo(graphWIDTH + padding, 350);
    ctx.stroke();  
    //20'c
    ctx.moveTo(padding, 270);
    ctx.lineTo(graphWIDTH + padding, 270);
    ctx.stroke();  
    //30'c
    ctx.moveTo(padding, 190);
    ctx.lineTo(graphWIDTH + padding, 190);
    ctx.stroke();  
    //40'c
    ctx.moveTo(padding, 110);
    ctx.lineTo(graphWIDTH + padding, 110);
    ctx.stroke();  
    
}
 
function drawXY()
{
    ctx.lineWidth =  4;      
    ctx.strokeStyle = "#828282";
    ctx.beginPath();
    /* y axis for temp along the left edge of the canvas*/  
    ctx.moveTo(padding,padding);
    ctx.lineTo(padding,graphHEIGHT + padding+2);
    ctx.stroke();  
    /* x axis along the bottom edge of the canvas*/  
    ctx.moveTo(padding, graphHEIGHT + padding);
    ctx.lineTo(graphWIDTH + padding,graphHEIGHT + padding);
    ctx.stroke();  
    /* y axis for hmid along the bottom edge of the canvas*/  
    ctx.moveTo(graphWIDTH + padding,graphHEIGHT + padding + 2);
    ctx.lineTo(graphWIDTH + padding,padding);
    ctx.stroke();  
    
}
  
function plotdata_hmid()
{
    ctx.lineWidth = 3;  
    ctx.strokeStyle = "#20B2AA";
    ctx.shadowBlur = 2;
    ctx.shadowColor = 'rgb(255, 255, 255)';    
    ctx.beginPath();  
    
    for (var j in hmids)
    {
        val = HEIGHT-(hmids[j] * 4); 
        ctx.lineTo((j*10) + padding, (graphHEIGHT + padding) - (hmids[j]) * 4);
        ctx.stroke(); 
    } 
}
function plotdata_temp()
{
    ctx.lineWidth = 3;  
    ctx.strokeStyle = "#DF4D55";
    ctx.shadowBlur = 2;
    ctx.shadowColor = 'rgb(255, 255, 255)';    
    ctx.beginPath();  
    
    for (var j in temps)
    {
        val = HEIGHT-(temps[j] * 8); 
        ctx.lineTo((j*10) + padding, (graphHEIGHT + padding) - (temps[j]) * 8);
        ctx.stroke(); 
    } 
}
 
function clear() {
    ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
 
function draw() {
    clear();
    drawguide();
    plotdata_hmid();  
    plotdata_temp();  
    drawXY();
    addlabels();
}
 
function ws_init()
{
    ws = new WebSocket("ws://<?echo _SERVER("HTTP_HOST")?>/htx23c", "text.phpoc");
    document.getElementById("ws_state").innerHTML = "CONNECTING";
 
    ws.onopen  = function(){ document.getElementById("ws_state").innerHTML = "OPEN" };
    ws.onclose = function(){ document.getElementById("ws_state").innerHTML = "CLOSED"};
    ws.onerror = function(){ alert("websocket error " + this.url) };
 
    ws.onmessage = ws_onmessage;
}
 
function hmid_array(hmid)
{
    var last_pos;
    last_pos = 59;
    
    for (var i =  0; i < last_pos; i ++ )
        hmids[i] = hmids[i+1];
        
    hmids[last_pos] = hmid;      
}
  
function temp_array(temp)
{
    var last_pos;
    last_pos = 59;
    
    for (var i =  0; i < last_pos; i ++ )
        temps[i] = temps[i+1];
        
    temps[last_pos] = temp;      
}

function ws_onmessage(e_msg)
{
    e_msg = e_msg || window.event;
      var rdata = e_msg.data;
      var array_rdata = rdata.split(",");

      hmid_array(array_rdata[0]);
      temp_array(array_rdata[1]);
 
    canvas = document.getElementById("canvas_graph");
    ctx = canvas.getContext("2d");
    draw();
    
    document.getElementById("ws_reply_hmid").innerHTML = array_rdata[0];    
    document.getElementById("ws_reply_temp").innerHTML = array_rdata[1];    
}
window.onload = ws_init;
</script>
</head>
<body bgcolor="#EEF0FF">
<center>
      <H1>Temperature and Humidity Graph</H1>
      <canvas id="canvas_graph" width="650" height="460"></canvas><br />
      <table cellpadding="2" cellspacing="2">
         <tr bgcolor="#CCCCCC">
         <td><font size="5">Web Socket : </font></td>
         <td><font size="5"><span id="ws_state"></span></font></td>
         </tr>
         <tr bgcolor="#DDDDDD">
         <td><font size="5">Current Humidity: </font></td>
         <td><font size="5" color="#20B2AA"><span id="ws_reply_hmid"></span> %</font></td>
         </tr>
         <tr bgcolor="#EEEEEE">
         <td><font size="5">Current temperature : </font></td>
         <td><font size="5" color="#DF4D55"><span id="ws_reply_temp"></span> 'C</font></td>
         </tr>
      </table>
</center>    
</body>
</html>

Credits

Gyusik Song

Gyusik Song

5 projects • 9 followers

Comments