はじめに
ESP32とは、Wi-FiとBluetoothを内蔵する低コスト、低消費電力なマイコンです。
お値段は、だいたい1,000円~2,000円くらいでしょうか。
このESP32に自由にモジュールを配線しプログラミングすることで、お手軽にIoTを開発することが可能です。
ということで、今回はマイコンの定番である温度ロガーを作成してみました。
ESP32に温湿度センサーを取り付け、計測した温湿度をWi-Fi経由で定期的にクラウド上のDBに登録します。
準備するもの
ESP32-DevKitC WROOM-32E(Espressif Systems)
マイコン本体です。
ネットで簡単に買えます。
秋月電子通商さんのネット通販サイトから購入しました。
1,600円くらいでした。
DHT11(Aosong Guangzhou Electronics Co., Ltd.)
温湿度センサーモジュールです。
秋月電子通商さんのネット通販サイトから購入しました。
500円くらいでした。
ブレッドボード(サンハヤト SAD-101)
ESP32と各種モジュールを直接ハンダで配線することも可能だと思いますが、ブレッドボードであればピンを刺すだけで配線できるため、ブレッドボードがあると便利でしょう。
Amazonで500円くらいでした。
※!!注意!!※
よく知らずにEIC-801のブレッドボードを買ったら、ESP32-DevKitCが大きすぎて配線できませんでした。
SAD-101なら無事配線できたので、こちらをおすすめします。
ジャンパーワイヤ(オス-オス)セット 10cmセット
ブレッドボード上で電気回路間をつなぐ電線です。
秋月電子通商さんのネット通販サイトから購入しました。
180円くらいでした。
USBケーブル 2.0 A-microB
ESP32の電源用と、ESP32とPCを繋いで開発を行います。
充電専用のケーブルではデータ通信できないので、データ通信に対応したケーブルを購入しましょう。
Amazonで250円くらいでした。
開発環境
Arduino(Windows)
Arduino IDEを使用してESP32の開発を行います。
環境構築は下記サイトを参考に行いました。
https://interface.cqpub.co.jp/esp32-arduino-ide-2/
データベース
Azure SQL Databaseを使用。
下記のテーブル「temperatures」を用意し、そこに測定した温度湿度を記録していきます。
Column Name | Data Type | 備考 |
---|---|---|
id | bigint | ID |
chipid | nvarchar(50) | ESP32デバイス識別用 |
temperature | float | 気温 |
humidity | float | 湿度 |
create_at | datetime | 計測した日時 |
データベース操作用API
Azure Functionsを使用。
REST APIで作成し、Json形式の温度、湿度のデータをPUTメソッドでアップロード。
なぜPUTかというと、頻繁にデータをアップして10分間の平均値としてデータを更新する仕様にしたためです。
また、GETメソッドで温度、湿度のデータを取得するAPIです。
メインテーマじゃないため詳細は割愛。
温度グラフ表示用サイト
React react-chartjs-2を使用。
上記APIから取得した温度湿度のデータをグラフ表示させます。
メインテーマじゃないため詳細は割愛。
配線
- DHT11の1番ピンとESP32の3V3(電源)を接続。
- DHT11の2番ピンがデータI/O用のピンなので、ESP32の4番ピンと接続。
- DHT11の3番ピンはEmptyなので使用しない。
- DHT11の4番ピンとESP32のGNDを接続。
赤のワイヤーが電源。
黒のワイヤーがGND。
緑のワイヤーがデータI/O。
Arduino IDEで実装
ESP32をWi-Fiにつなぎ、DHT11から取得した温度湿度をHTTPでデータをPUTするプログラムです。
Arduino IDEにDHT11ライブラリをインストール
Auduino IDEのライブラリマネージャにて、「DHT」と検索して、「DHT-sensor-library」をインストールします。
このライブラリを利用して、DHT11から計測数値を取得します。
ソースコード
#include "DHT.h"
#include <WiFi.h>
#include <HTTPClient.h>
#include "ArduinoJson.h"
// APIのURL
#define API_URL "https://???.azurewebsites.net/api/tempratures"
#define DHTPIN 4 // DHT11の通信ピンを繋いだピン番号
#define DHTTYPE DHT11 // DHT 11
// DHTセンサーの初期化
DHT dht(DHTPIN, DHTTYPE);
// Wi-Fi接続情報を入力(IPアドレス自動取得)
const char* ssid = "****";
const char* password = "****";
uint64_t chipid; // ESP32固有のチップID保管用
void setup() {
// シリアル通信のデータレート設定
Serial.begin(9600);
Serial.println(F("DHTxx test!"));
// センサー初期化
dht.begin();
// チップID取得
chipid = ESP.getEfuseMac();
Serial.println(F("getEfuseMac"));
Serial.println(chipid);
// Wi-FiのモードをSTAに設定
WiFi.mode(WIFI_STA);
}
void loop() {
// 10秒待つ
delay(10000);
// 温度の読み込みに250ミリ秒 ~ 2秒かかるらしい
float h = dht.readHumidity(); // 湿度の取得
float t = dht.readTemperature(); // 温度の取得
// データチェック
if (isnan(h) || isnan(t)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
Serial.println(F("read from DHT sensor!!"));
// APIの仕様にあわせてJsonデータを作成
StaticJsonDocument<200> doc;
doc["chipid"] = chipid;
doc["temprature"] = t;
doc["humidity"] = h;
String json;
serializeJson(doc, json);
// APIをコールしてJsonデータをアップロード
HTTPClient http;
if( !http.begin(API_URL) ) {
Serial.println(F("Failed HTTPClient begin!"));
return;
}
http.addHeader("Content-Type", "text/plain");
// Wi-fiが切れやすいので、毎回接続を試みる
int retry_count = 0;
int httpResponseCode = -1;
while(httpResponseCode < 0 && retry_count++ < 50) {
wifi_connect(false);
// データをPUTする
httpResponseCode = http.PUT(json);
if( httpResponseCode < 0 ) {
Serial.println(F("PUT Failed"));
Serial.println(httpResponseCode);
wifi_connect(true);
}
delay(500);
}
Serial.println(httpResponseCode);
Serial.println(WiFi.status());
}
void wifi_connect(bool reconnect) {
if( !reconnect && WiFi.status() == WL_CONNECTED ) {
Serial.println(F("wifi already connected"));
return;
}
if( reconnect ) {
WiFi.disconnect();
delay(500);
Serial.println(F("wifi reconnect"));
WiFi.reconnect();
}
else {
Serial.println(F("wifi connect"));
WiFi.begin(ssid, password);
}
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// 取得したローカルIPアドレスをシリアルに出力
Serial.println(F(""));
Serial.println(F("WiFi connected."));
Serial.println(F("IP address: "));
Serial.println(WiFi.localIP());
}
Arduino IDEからESP32に書き込み
IDEの左上のボタンから書き込みを行います。
コンパイルに少し時間がかかります。
エラーなく書き込みが終わると、コードが実行されます。
Serial.printで出力した文字がシリアルモニタに表示されたら成功です。
Wi-FiにつながるとローカルIPが表示されます。
ということで、DBのデータをreact-chartjs-2でグラフ表示してみました。
※created_atがUTCのため、グラフは日本時間表記です。