体験的マイコン学習(Raspberry Pi編)


目次



第5回 事務所の温度をブラウザにグラフ表示してみる


今回はRaspberyPIに接続した温度センサーの結果をグラフ表示してみます。

マイコン学習の最終形はたぶんIOTなので、センサーの結果をサーバー側で処理する技術を検証します。

なお、PHP及びグラフ表示部分については、「センサーでできるおもしろまじめ電子工作」を参考にさせていただきました。

センサーサーバー連携図

今回作成したシステムの概念図が以下のとおりです。PHPやChart.jsは初めてだったので、試行錯誤でした。

データの付け込みやデータからの取り出しもPHPでやればよかったのかもしれませんが、よくわからなかった

ので、完成させることを優先して、慣れ親しんだRAILSの力を借りました

GrovePi+の準備

温度センサーは今回、GrovePi+という拡張ボードを使用しました。ブレッドボードで線をつなぐのと違って

がっちりはまっているので、安心感があります。RaspberyPIにGrovePi+を上からかぶせて、GrovePi+の端子

に温度センサーをつなぎました(写真の右上の線でつながれているのが温度センサー)

ページトップ

RaspberyPI側の準備

(1)RaspberyPI側のプログラムをpythonで作成します。取得した温度をRailsで作成したデータ保存APIを呼びます。

 sensor.py

import urllib import requests import sys from grovepi import * dht_sensor_port = 2 dht_sensor_type = 1 # データの取得 [ temp, hum] = dht(dht_sensor_port, dht_sensor_type) API_URL="(サーバのURL)" args = sys.argv kbn = "0" if len(args) == 2: kbn = args[1] # データの送信 response = requests.get(API_URL,params="data=" + kbn + "," + str(temp), verify=False)

(2)cronの設定を行い、時間起動でpythonプログラムを実行します。(今回は1時間置きに実行)

 cronの設定内容

00 00 * * * python /home/pi/Desktop/sensor.py 0 00 01 * * * python /home/pi/Desktop/sensor.py 1 00 02 * * * python /home/pi/Desktop/sensor.py 2 00 03 * * * python /home/pi/Desktop/sensor.py 3 00 04 * * * python /home/pi/Desktop/sensor.py 4 00 05 * * * python /home/pi/Desktop/sensor.py 5 00 06 * * * python /home/pi/Desktop/sensor.py 6 00 07 * * * python /home/pi/Desktop/sensor.py 7 00 08 * * * python /home/pi/Desktop/sensor.py 8 00 09 * * * python /home/pi/Desktop/sensor.py 9 00 10 * * * python /home/pi/Desktop/sensor.py 10 00 11 * * * python /home/pi/Desktop/sensor.py 11 00 12 * * * python /home/pi/Desktop/sensor.py 12

Rails側の準備

(1)Rails側のプログラムを作成します。Rails5ではAPIを作成する処理が標準で提供されたので、もっとスマートに

作成できるかもしれませんが、今回はとりあえずセンサーの結果をブラウザにグラフ表示するのが目的なので、

細かいことは目をつぶることにします。

 data_controller.rb

class DataController < ApplicationController # 呼び出し方 http://xxxxx/data/set?data="1,25.0" # パラメタ 1,25.0 時刻区分,温度 # テストでの呼び出し方 curl xxxxx/data/set?data="1,25.0" def set begin data = params["data"].split(',') sensor = Sensor.where(measure_date: Date.today, div: data[0]).first if sensor.blank? sensor = Sensor.new sensor.measure_date = Date.today sensor.div = data[0] end sensor.temperature = data[1].to_f sensor.save! render text: "OK" rescue => e logger.error e logger.error e.backtrace.join("\n") render text: "NG" end end end

(2)データの取り出しはRails標準の機能を使います。
※.json.jbuilderファイルを用意することで、(サーバURL)/sensors.jsonでjsonデータを取得できます。

 sensors_controller

class SensorsController < ApplicationController def index @sensors = Sensor.where(measure_date: Date.today) end end

 index.json.jpbuilder

json.array! @sensors, partial: 'sensors/sensor', as: :sensor

 _sensor.json.jbuilder

json.extract! sensor, :measure_date, :div, :temperature

PHPの準備

PHPを作成します。PHPの機能としては以下のとおりです。
①RAILS APIの呼び出し(curlを使用)
②取得したjsonを分解して、csvデータを作成(カンマ区切りで、1データの終わり毎に改行)

 sensorGet.php

<?php $base_url = '(サーバURL)/sensors.json'; $tag = 'PHP'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $base_url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); $response = curl_exec($curl); $result = json_decode($response, true); if (curl_errno($curl) != 0) { print('curl error:[' . curl_errno($curl) .'] '. curl_error($curl)); } curl_close($curl); $return = ""; for($i = 0; $i < count($result); ++$i) { $return = $return . $result[$i]["div"] . "," . $result[$i]["temperature"] . "\n"; } $filename = 'sensorLog.txt'; file_put_contents($filename, $return); echo file_get_contents("sensorLog.txt"); ?>

HTML/JSの準備

(1)グラフ表示用のHTMLを作成します。

 index.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="robots" content="noindex"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>事務所現在温度</title> <link rel="stylesheet" href="css/normalize.css" /> <link rel="stylesheet" href="css/index.css" /> <script src="js/jquery-1.11.3.min.js"></script> <script src="js/Chart.min.js"></script> <script defer src="js/index.js"></script> </head> <body> <!-- グラフ表示領域 --> <canvas id="chart"></canvas> </body> </html>

(2)グラフ表示用のJavaScript

 index.js

// PHPのURL var PHP_URL = "sensorGet.php"; // センサーの値 var sensorValue = 0; // センサーの時間 var sensorTime = 99; // サーバーにアクセス中かどうか var isAjax = false; // canvas要素の設定 var canvas = document.getElementById("chart"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; var context = canvas.getContext("2d"); // 線の情報 var data = { // ラベル labels: [], datasets: [ { data : [], // 塗りの色 fillColor: "rgba(0,0,220,0)", // 線の色 strokeColor: "rgba(0,0,220,1)" } ] }; // グラフの描画設定 var options = { // アニメーションの速さ animationSteps: 1, // 線をベジェ曲線で滑らかにするかどうか bezierCurve: false, // 目盛を自分で設定する scaleOverride: true, // Y軸の目盛の数 scaleSteps: 7, // Y軸の1目盛の大きさ scaleStepWidth: 5, // Y軸の最小値 scaleStartValue: -5, // 目盛の色 scaleLineColor: "#fff", // 目盛の線の幅 scaleLineWidth: 1, // グリッドを表示するかどうか scaleShowGridLines: true, // グリッドラインの色 scaleGridLineColor: "#222", // グリッドラインの幅 scaleGridLineWidth: 1, // Y軸方向のグリッドを表示するかどうか scaleShowVerticalLines: false }; var labels = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24"]; // 折れ線グラフをインスタンス化 var chart = new Chart(context).Line(data, options); // サーバーへアクセス中でなければ if(!isAjax) getSensorValue(chart); /** * PHPからセンサーの値を取得し、描画します */ function getSensorValue() { // フラグをtrue isAjax = true; $.ajax({ url: PHP_URL + "?p=" + new Date().getTime(), type: "post", dataType: "text", success: function(value) { var tempArray = value.split("\n"); for(var i = 0; i < tempArray.length; i++){ if (tempArray[i] != ""){ var dataArray = new Array(); dataArray = tempArray[i].split(","); sensorTime = dataArray[0]; sensorValue = dataArray[1]; chart.addData([sensorValue], labels[i]); } } // フラグをfalse isAjax = false; }, error: function(){ console.log("センサーの値を取得できませんでした。"); isAjax = false; } }) }

動作確認

ブラウザで確認します



13時で温度が下がったのでは、部屋が暑くなってきたので、窓を開けたせいですね。今回このシステム?

を作って感じたのは、自分の基礎知識のなさですね。JQUERYやPHPやWEB API呼び出しなどなど、、

IOTのできる人って、センサーからサーバーの知識からサーバ系言語まで、多種多様な知識をお持ち

なのでしょうか、、、


ページトップ