ESP32-DevkitCとDHT11とCDSで、温度・湿度・明るさのデータをPostgreSQLに保存するデータロガーを作成するには、以下の手順を実行します。
構成としてはESP32-DevkitCに接続したDHT11で温度・湿度を取得し、CDSで明るさを取得します。ESP32-DevkitCからWiFi経由でPC側のFlaskのRESTサービスにアクセスしデータを受け渡し、PostgreSQLにデータを保存します。
〇ESP32-DevkitCとDHT11とCDSを接続した写真
データロガーの開発手順
1. PC側:PostgreSQLのデータベースにテーブルを作成する
以下のSQLコマンドを実行して、温度・湿度・明るさを保持するテーブルを作成します。
create table iot_sensor_data
(
device_name varchar(30) not null,
data_ts timestamp not null,
temperature integer,
humidity integer,
lightness integer,
constraint pk_iot_sensor_data primary key (device_name, data_ts)
);
※PostgreSQLをインストールしていない場合は、以下の記事を参照してください。
・Ubuntu20.04にインストールしたい場合は、以下の記事のPostgreSQLのインストール部分を参照してください。
Ubuntu 20.04にNextcloud20とPostgreSQL13をインストールする
・Raspberry Piにインストールしたい場合は、以下を参照してください。
Raspberry Pi(Raspbian Buster)にPostgreSQL11をインストールしてtestデータベースとtestユーザを作成する
2. PC側:ユーザの追加
Flaskを実行するユーザpyを作成するには、以下のコマンドを実行します。
sudo addgroup py
sudo adduser --quiet --gecos "" --ingroup py py
3. PC側:pipenvのインストール
sudo apt-get -y install python3-pip python3-distutils python3-dev python3-testresources
sudo pip3 install --upgrade setuptools
sudo pip3 install pipenv
echo "export PIPENV_VENV_IN_PROJECT=true" >> ~/.bashrc
source ~/.bashrc
4. PC側:flaskとpsycopg2のインストール
以下のコマンドで、flaskとpsycopg2をインストールした仮想環境を作成します。
sudo apt-get -y install libpq-dev
sudo mkdir -p /opt/iot_logger
sudo chown py:py /opt/iot_logger
※ここから作成したpyユーザで以下のコマンドを実行します。
cd /opt/iot_logger
pipenv --python 3
pipenv install flask psycopg2-binary
pipenv shell
5. PC側:REST APIでデータを受け取り、PostgreSQLに保存するFlaskアプリケーションの構築
以下のコードを/opt/iot_loggerのapp.pyに保存します。
app.py
from flask import Flask, jsonify, request
import time
import os
import psycopg2
import psycopg2.extras
def dbconnect():
conn = psycopg2.connect(host=os.environ['PG_HOST'], port=os.environ["PG_PORT"], database=os.environ['PG_DB'], user=os.environ['PG_USER'], password=os.environ['PG_PASS'])
return conn
sql = """insert into iot_sensor_data values ('ESP32-DevkitC', current_timestamp, %s, %s, %s)"""
@app.route('/iot_logger', methods=["POST"])
def iot_logger():
print(request.get_data())
temp = int(request.json['temp'])
humidity = int(request.json['humidity'])
lightness = int(request.json['lightness'])
conn = dbconnect()
#with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
with conn.cursor() as cur:
cur.execute(sql , (temp, humidity, lightness))
conn.commit()
return {"status":"ok"}
app = Flask(__name__)
app.run(debug=True, host='0.0.0.0', port=5001, threaded=True)
4. PC側:テスト実行
Flaskを実行するには、以下のコマンドを実行します。
export PG_HOST=(PostgreSQLのホスト名またはIPアドレス)
export PG_PORT=(PostgreSQLのポート:デフォルトは5432)
export PG_DB=(PostgreSQLのデータベース名)
export PG_USER=(ユーザ名)
export PG_PASS=(パスワード)
export FLASK_APP=app.py
flask run -h 0.0.0.0 -p 5001
※Ctrl+Cで停止します
5. PC側:サービス化
以下のコマンドでFlaskアプリケーションをサービス化して実行します。
cat << EOF | sudo tee /etc/systemd/system/iot_logger.service
[Unit]
Description=IoT logger
[Service]
Type=simple
Environment=export PG_HOST=(PostgreSQLのホスト名またはIPアドレス)
Environment=export PG_PORT=(PostgreSQLのポート:デフォルトは5432)
Environment=export PG_DB=(PostgreSQLのデータベース名)
Environment=export PG_USER=(ユーザ名)
Environment=export PG_PASS=(パスワード)
Environment=export FLASK_APP=app.py
ExecStart=/opt/iot_logger/.venv/bin/python3 app.py
User=py
Group=py
WorkingDirectory=/opt/iot_logger
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable iot_logger
sudo systemctl start iot_logger
6. ESP32-DevkitC側:ESP32-DevkitCとDHT11/CDSの配線
ESP32-DevkitCとDHT11センサーモジュール/CDSを配線します
DHT11のDigitalピンへ(付属ケーブルの緑) -> ESP32-DevKitCのIO27ピン
DHT11のGNDへ(付属ケーブルの黒) -> ESP32-DevKitCのGNDピン
DHT11のVへ(付属ケーブルの赤) -> ESP32-DevKitCの3V3ピン
※ESP32とDHT11の接続は以下の記事を参照してください。
ESP32-DevkitCとDHT11で計測した温度・湿度をWiFi経由のREST APIで通知する
CDS,10KΩ抵抗を以下の様に接続します。
※CDSの接続は以下の記事を参照してください。
ESP32-DevkitCとCDSで明るさを計測する
4つのエネループをセットした電池ボックスのプラスは5V端子、マイナスはGNDに接続します。
※電池と基板の接続は以下の部品を使用しました。
XHコネクタ ベース付ポスト トップ型 2P B2B-XH-A(LF)(SN)
https://akizukidenshi.com/catalog/g/gC-12247/
電池ボックス 単3×4本 スイッチ付 XHコネクタ付
https://akizukidenshi.com/catalog/g/gP-12242/
7. ESP32-DevkitC側:プログラミング
以下のプログラムをmain.pyとして、ESP32-DevkitCに保存します。dhtのライブラリ導入は、上記のDHT11の記事を参照してください。
import machine
import time
import dht
import urequests
import ujson
import network
# WiFiのssid
ssid = "WiFiのssid"
# WiFiのパスワード
password = "Wifiのパスワード"
# REST APIの接続先
url = "http://(ホスト名またはIP):(ポート番号)/iot_logger"
header = {'Content-Type':'application/json'}
def connect_wifi():
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print("connecting to network...")
sta_if.active(True)
sta_if.connect(ssid, password)
while not sta_if.isconnected():
pass
print("network config:", sta_if.ifconfig())
# ADC初期化
pin35 = machine.Pin(35, machine.Pin.IN)
cds = machine.ADC(pin35)
cds.atten(machine.ADC.ATTN_11DB) # 11dBの減衰率、約3.6v が最大入力電圧
# DHT11初期化
dht11 = dht.DHT11(machine.Pin(27))
time.sleep(1)
while True:
# WiFi接続
connect_wifi()
# 測定
dht11.measure()
temp = dht11.temperature()
humidity = dht11.humidity()
lightness = cds.read()
# REST APIに通知
data = ujson.dumps({"temp":str(temp), "humidity":str(humidity), "lightness":str(lightness)})
try:
resp = urequests.post(url, data=data.encode("utf-8"), headers = header)
print(resp.json())
resp.close()
except OSError as err:
print(err)
print("----")
# deepsleep
#time.sleep(2)
machine.deepsleep(60*60*1000) # 3600sec=1時間
8. ESP32-DevkitC側:データ確認
以下のSQLを実行して、センサーデータが保存されていることを確認します。
select * from iot_sensor_data