iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
1
IoT

IoT沒那麼難!新手用JavaScript入門做自己的玩具~系列 第 19

[Day 18]-用JS控制Arduino吧!視覺化溫度資料 Highcharts + Socket.io + Johnny Five - 溫度器 Thermometer

IoT沒那麼難!新手用 JavaScript 入門做自己的玩具!(iT邦幫忙鐵人賽系列書)

★本系列文章已集結成冊,和系列文不同的是:

  • 本書使用大量的圖解來說明LED系列、多種感測器等原理。
  • 補足系列文程式碼的解說,增加逐行程式碼的詳細解說!
  • 全彩的書籍,用圖解的方式,讓讀者來理解Johnny-Five各種API的功能與效果,讓你不會只讀文字看到想睡覺而學不起來。

歡迎大家做出自己想要的玩具,為了樂趣而學習,讓學習變成你的樂趣!ヽ(・×・´)ゞ
讓Arduino也能用JavaScript創造出屬於自己的作品!

★購書連結-天瓏網路書局:
https://www.tenlong.com.tw/products/9789864345328

《IoT沒那麼難!新手用 JavaScript 入門做自己的玩具!(iT邦幫忙鐵人賽系列書)》
博客來、金石堂、momo、誠品、PChome、讀冊,均有販售喔!─=≡Σ((( つ•̀ω•́)つ
ISBN:9789864345328

上篇 -
[Day 17]-用JS控制Arduino吧!手心的溫度~Johnny Five 之 溫度感測 Thermometer

我們在本地端用 Johnny-Five 實驗了溫度感測器 - LM35
但只有 console.log 這樣吐訊息根本看不出資料的高低變化....( ˘・з・)

於是.....(登登楞登~登登~ (多拉A夢的音效)

視覺化圖表 Highcharts

Highcharts
https://www.highcharts.com/


先給大家看看我做的結果~٩(๑•̀ω•́๑)۶

Highcharts 介紹

Highcharts 是一個可以把資料視覺化的圖表 JS 框架(framework),可以簡單的用 JavaScript 的把資料統計、顯示圖表在網頁上!

謎之音:為什麼要使用 Highcharts 呢?
本魯宅:婀.....(思考了三秒...) 因為我以前有用過所以就用了...
謎之音:(欸...不是吧....

恩....我以前就用過是沒錯~
但選用的原因還有

  • based on SVG
  • 支援Mobile
  • 支援RWD

比較一下 Chart.js 和 Highcharts.js 在手機上的表現

  • Chart.js

本魯的 iPhone7 截圖

  • Highcharts.js


本魯的 iPhone7 截圖

結論:Highcharts.js 深得我心!完勝!(*´∀´)~♥

JavaScript 視覺化圖表庫

JavaScript 還有其他視覺化圖表庫
像是

最知名的 JS 圖表庫 D3.js
https://d3js.org/


Open source 使用 HTML5 Canvas 的 Chart.js
https://www.chartjs.org/


就看人選用啦~擇你所愛愛你所選囉~ξ( ✿>◡❛)

Socket.io + Johnny Five + Highcharts

接下來說明,
怎麼實現透過 Socket.io 來蒐集溫度資料後,在網頁上顯示圖表(ง๑ •̀_•́)ง

想法是這樣的~

之前玩 LED 時,是在 Client 端控制透過 Socket.io 傳遞到 Server 端並在Server端中使用 Johnny-Five 來控制 Arduino

而這次是由 Sensor 偵測資訊並傳遞給 Arduino 輸入資料, Arduino 處理完傳給 Server 顯示在網頁上,由 Client 端連上網頁後觀看相關資料資訊

心之音:嗚....好亂喔....( ˘・з・)
本魯:看圖吧~  (  ̄□ ̄)/    <( ̄ㄧ ̄ )

  • 以往是由 Client 端來控制,傳遞方向是 Client 往 Server 端 emit

  • 現在則是由 Sensor 偵測資訊輸入給 Arduino 後,Client 端透過 Socket 與 Server 連線後,即可查看資料、資訊!

恩~大概是這樣的概念.....(有錯請指正,感謝~
好!話不多說,實作吧!(๑•̀ㅂ•́)و✧

實作 - 溫度 Dashboard

後端部分

var io = require('socket.io');
var express = require('express');
var five = require('johnny-five');

var board = new five.Board();
var app = express();

app.use(express.static('www'));
var server = app.listen(3000, function() {
  console.log('connected!');
});

var sio = io(server);

var timeArray = [];
var tempArray = [];
// Highcharts資料集必須用陣列,故宣告溫度與時間陣列

board.on('ready', function() {
  var temperature = new five.Thermometer({
    controller: 'LM35', //設定感測器元件
    pin: 'A0', //設定輸入類比腳
    freq: 3000, //設定三秒取一次溫度值
  });

  sio.on('connection', function(socket) {
    temperature.on('data', function() {
      // console.log(this.celsius + '°C');
      temp = this.celsius; // 取得目前環境攝氏溫度
      tempArray.push(temp);
      tArr = getTime();
      console.log(tempArray, tArr);
      socket.emit('startTemp', {
        // 發送給 Client startTemp事件
        temp: tempArray,
        time: tArr,
      });
    });
	/* 這一大塊都是在取時間 */
    function getTime() {
      var time = new Date();
      var y = time.getFullYear();
      var m = time.getMonth() + 1;
      var d = time.getDate();
      var h = time.getHours();
      var min = time.getMinutes();
      var s = time.getSeconds();

      m = checkTime(m);
      d = checkTime(d);
      h = checkTime(h);
      min = checkTime(min);
      s = checkTime(s);

      dateTime = { year: y, mon: m, day: d, h: h, min: min, sec: s };
      timeStr = h + ':' + min + ':' + s;

      timeArray.push(timeStr);

      return timeArray;
    }
    function checkTime(i) {
      if (i < 10) {
        i = '0' + i;
      } // add zero in front of numbers < 10
      return i;
    }
	/* 這一大塊都是在取時間 end*/
  });
});

前端部分

前端頁面要使用到 Highcharts 呈現圖表!
X 軸為時間, Y 軸為攝氏溫度

為了求快速開發這邊也一樣,CSS 引用 Bootstrap 框架,JS 引用 jQuery 來撰寫~


前端的程式碼~

HTML 部分

<!DOCTYPE html>
<html lang="zh-tw">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="" />
    <meta name="author" content="Tzeng,Ying-Chi" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
      integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
      crossorigin="anonymous"
    />
    <title>Temperature Test</title>
  </head>
  <body>
    <div class="container pt-4">
      <h3>Temperature Test</h3>
      
      <!-- 在網頁中添加一個div,並給它一個id且設置寬度和高度,這將是圖表的寬度和高度。 -->
      <div id="chart" style="width:100%; height:400px;"></div>
      
    <nav class="navbar navbar-light bg-light fixed-bottom">
      IoT沒那麼難!新手用JavaScript入門做自己的玩具 系列文 Tzeng,Ying-Chi
    </nav>
    
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="index.js"></script>
  </body>
</html>

JavaScript 部分

var socket = io.connect();

socket.on('startTemp', function(data) {
  // 當socket開始連線時,接收資料
  console.log(data);
  tempData = data.temp; // 溫度陣列
  timeData = data.time; // 時間陣列
  renderChart(tempData, timeData); // 產生圖表
});

function renderChart(tempData, timeData) {
  Highcharts.chart('chart', {
    // 在 div id="chart" 中繪製Highcharts圖表
    chart: {
      type: 'line', // 圖表種類
      animation: false,
    },
    title: {
      text: 'Johnny-five with Temperature',
    },
    xAxis: {
      //  X軸
      type: 'datetime',
      categories: timeData, // X軸資料
    },
    yAxis: {
      title: {
        text: 'Temperature (°C)',
      },
    },
    plotOptions: {
      line: {
        dataLabels: {
          enabled: true,
        },
      },
    },
    series: [
      // 資料集,若有複數資料集以物件方式來增加
      // ex:{name: '軸的名稱',data:陣列資料,}
      {
        name: 'My Hand Temperature',
        data: tempData, //溫度陣列資料
      },
    ],
  });
}

測試看看吧!(ง๑ •̀_•́)ง

啟動 node!Run Run看~(; ・´д・´)

node temp-chart.js 

有新增節點表示成功啦!(*´∀´)~♥

從Sensor偵測環境溫度後,在從後端傳到前端頁面上,
讓我們更容易讀取資料!

只要設定好 Router,手機也可以看到偵測的資訊喔~

想玩玩的朋友可以試試看喔~完整的程式碼都在我的github囉~
d(d'∀')

文後

如果鐵人賽有得獎得到獎金,我要拿去買書桌...
現在坐在床上打文打到肩頸超痛的....Orz


本系列的程式碼皆會上傳到 GitHub 上開源

2019ironman-JS-IoT :
https://github.com/tinatyc/2019ironman-JS-IoT

喜歡按個星星吧~乾蝦乾蝦<(_ _)>


團隊系列文:

CSScoke - 金魚都能懂的這個網頁畫面怎麼切 - 金魚都能懂了你還怕學不會嗎
Hina Hina - 陣列大亂鬥
阿斬 - Python 程式交易 30 天新手入門
Clarence - LINE bot 好好玩 30 天玩轉 LINE API
塔塔默 - 用Python開發的網頁不能放到Github上?Lektor說可以!!
Vita Ora - 好 Js 不學嗎 !? JavaScript 入門中的入門。


同步連載於blogger-King 學習前端之人生


上一篇
[Day 17]-用JS控制Arduino吧!手心的溫度~Johnny Five 之 溫度感測 Thermometer
下一篇
[Day 19] -用JS控制Arduino吧!聖光啊!你看見那個鐵人了嗎?Johnny-Five 之 光敏電阻 Photoresistor
系列文
IoT沒那麼難!新手用JavaScript入門做自己的玩具~33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言