把遇到錯誤的、學習到的前端筆記在這邊

總網頁瀏覽量

Copyright © Tzeng Ying-chi. 技術提供:Blogger.

2019/10/02

[2019鐵人賽] - 18.筆記IoT初練習- 用JS控制Arduino吧!視覺化溫度資料 Socket.io + Johnny Five + Highcharts - 溫度器 Thermometer


上篇 [[2019鐵人賽] - 17.筆記IoT初練習- 用JS控制Arduino吧!手心的溫度~Johnny Five 之 Thermometer](https://kingweblife.blogspot.com/2019/10/2019-17iot-jsarduinojohnny-five.html)

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

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

視覺化圖表 - Highcharts ~

> Highcharts
https://www.highcharts.com/

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



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


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

恩....我以前就用過是沒錯~
但選用的原因還有它是 based on SVG、支援Mobile、支援RWD

> 比較一下 Chart.js VS Highcharts.js
- Chart.js 在手機上的表現


 
- Highcharts.js 在手機上的表現



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

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

- 最知名的 JS 圖表庫 D3.js

- Open source 使用 HTML5 Canvas 的 Chart.js

就看人選用啦~擇你所愛愛你所選~

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

之前玩 LED 時是在 Client 端控制 透過 Socket.io 傳遞到 Server 端並在Server端中使用 Johnny-Five 來控制 Arduino,而這次是由 Sensor 偵測資訊並傳遞給 Arduino 輸入資料後處理完傳給 Server 顯示在網頁上,由 Client 端連上網頁後觀看相關資料資訊

> 嗚....好亂喔....( ˘・з・)
> 看圖吧~

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



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



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

後端部分

```
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;
    }
  });
});
```

前端部分

前端頁面要呈現圖表, 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: [
      // 資料集,若有複數資料集以物件方式來增加
      {
        name: 'My Hand Temperature',
        data: tempData, //溫度陣列資料
      },
    ],
  });
}
```

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

啟動 node~ Run Run看~
```
node temp-chart.js 
```



成功!(*´∀´)~♥

從Sensor偵測環境溫度後,在從後端傳到前端頁面上,讓我們更容易讀取資料~
只要設定好 Router 手機也可以看到偵測的資訊喔~


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

本文到這邊先下台一鞠躬了~
有錯敬請留言改正,感謝您的閱讀 <(_ _)>

0 留言:

張貼留言