しばらく前の話になりますが、あまりに暑い日が続くので、はたして我が家の1日の温度がどのようになっているのか、グラフにして見てみたいと思い立ちました。
Arduinoエントリーキットを買った時に入っていた温度センサーが未使用で残っていたので、これを使って温度を測定することにしました。
測定した温度は、ESPr DeveloperでWebサーバに送信し、Webブラウザでグラフ表示できるようにしたいと思います。
作成したのは以下の4つです。
- ハードウエア
- ESPr Developer用のスケッチ
- 温度情報を受信するPHPプログラム
- グラフを表示するPHPプログラム
ここでは、これらの作成内容を説明します。
ハードウエア
ハードウエアは非常に簡単で、温度センサ(LM35DZ)とESPr Developerの以下の端子同士を接続するだけです。
LM35DZ | ESPr Developer |
---|---|
5V | VOUT |
OUT | TOUT |
GND | GND |
ESPr Developer用のスケッチ
ESPr Developerでは1分毎に温度を測定し、サーバに送信します。
スケッチは以下のとおりです。そこそこ長いですが、「Arduino」>「ファイル」>「スケッチ例」>「ESP8266WiFi」>「WiFiClient」のサンプルスケッチを、ほんの数行編集しただけです。
#include <ESP8266WiFi.h>
const char* ssid = "xxxxxxxx";
const char* password = "xxxxxxxx";
char host[40] = "xxxxxxxx";
char event[40] = "/temp_receive.php";
extern "C" {
#include "user_interface.h" // ESPr Developerでアナログデータを入力する際に記述
}
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
int sensorValue = system_adc_read(); // アナログ値を採取(TOUT端子)
Serial.println(sensorValue);
Serial.print("connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
// We now create a URI for the request
String url = String(event) + "?val0=" + String(sensorValue); // 採取したアナログ値を「val0」という変数名で送信
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
delay(60000); // 60秒待つ
}
温度情報を受信するPHPプログラム
サーバ側で温度情報を受信するPHPプログラム(temp_receive.php)は以下のとおりです。
SQLite3データベースに時間と温度を格納していきます。
<?php
// 各種初期設定
date_default_timezone_set('Asia/Tokyo');
$dbname = 'db_temp';
$db = new SQLite3($dbname);
// tableを作成
$sql = "CREATE TABLE IF NOT EXISTS temp ( id INTEGER PRIMARY KEY, event_time INTEGER, val0 INTEGER )";
$db->exec($sql);
// 現在時刻を取得
$event_time = time();
// デバイス採取値を取得
$val0 = $_GET['val0'];
// 値を書き込み
$sql = "INSERT INTO temp (id, event_time, val0) VALUES(null, $event_time, $val0)";
$db->exec($sql);
$db->close();
?>
グラフを表示するPHPプログラム
貯めたデータをグラフ表示するPHPプログラム(temp_graph.php)は以下のとおりです。とりあえず、グラフを閲覧したその日、一日分の観測データを取り出して、一日分のデータをグラフにしようと思います。
グラフ表示するために、「Chart.js」というものを使います。
<?php
// 各種初期設定
date_default_timezone_set('Asia/Tokyo');
$dbname = 'db_temp';
$db = new SQLite3($dbname);
$res = "";
$now = time();
$btime = strtotime( date("Y/m/d 00:00:00", $now) );
$etime = strtotime( date("Y/m/d 00:00:00", strtotime('+1 day', $now)) );
$date = date("n/j", $now);
// tempテーブルから今日の情報を抽出
$sql = "SELECT * FROM temp WHERE event_time BETWEEN $btime AND $etime";
$result2 = $db->query($sql);
while($info2 = $result2->fetchArray(SQLITE3_ASSOC)){
$event_time = ($info2['event_time']-$btime)/3600;
$val0 = $info2['val0']*100/1024;
$res .= "{ x: " .$event_time .", y: " .$val0 ." },";
}
$db->close();
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>温度計</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
</head>
<body>
<h1><?php echo $date;?></h1>
<canvas id="temp" width="300" height="50"></canvas>
<script>
var ctx = document.getElementById('temp').getContext('2d');
var temp = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'temperature',
fill: false,
borderColor: 'limegreen',
pointRadius: 0,
data: [ <?php echo $res;?> ]
}]
},
options: {
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks: { min: 0, max: 24, stepSize: 3 }
}],
yAxes: [{
ticks: { min: 0, max: 50, stepsize: 10 }
}]
},
legend: { display: false, }
}
});
</script>
</body>
</html>
動作確認
ふたつのPHPプログラムを、Webサーバにアップロードします。
Webブラウザで、Webサーバ上の「temp_graph.php」にアクセスすると、温度のグラフが表示されます。
ハードウエアを当社(兵庫県)の南西向きベランダの床面近くに置いた時の結果です。温度の確からしさは未確認ですが、実際の温度も、大体こんなものだと思います。
エアコンの室外機などもあるので過酷な環境ですが、それにしてもシャレにならない気温です。
ハードウエアを冷蔵庫の中に入れても温度を確認できました。冷蔵庫の中でもWiFiが繋がることに少々驚きました。