ESP32 BME680で測定したデータをMariaDBにとばす その2

先日BME680のデータをMariaDBに飛ばしましたが、スタンドアロンで自動測定できるようにプログラムを更新しました。また、Wi-Fiに接続している際にLEDを点灯させることとしました。ピン4番にプルアップ抵抗を介してLEDを接続します。

左上にLEDをつけていますWi-Fi接続で点灯します。

以下がプログラムです。ブートした際に自動的に走らせるために、プログラム名はmain.pyにしてあります。

この通りWi-Fiに接続するとLEDがともります。phpMyAdminで確認すると10秒おきにデータが蓄積していきます。

ESP32 複合センサBME680で測定したデータをMariaDBにとばす

先日仕入れたBME680を用いて温度、湿度、気圧、ガス濃度を測定してMariaDBに飛ばして記録したいと思います。今回のプログラムです。先にWi-Fiにつないでからrunさせます。

実行結果です。

C:\Users\>ampy -p com3 run c:\micropython\posttest8.py
Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead
Temperature: 17.36
Humidity: 54.01
Pressure: 1019.21
Gas: 56.24
"temp=17.36 , hum=54.01 , pres=1019.21, gas=56.24"New record created successfully
Temperature: 17.35
Humidity: 54.14
Pressure: 1019.22
Gas: 54.43
"temp=17.35 , hum=54.14 , pres=1019.22, gas=54.43"New record created successfully
Temperature: 17.41
Humidity: 54.15
Pressure: 1019.24
Gas: 53.23
"temp=17.41 , hum=54.15 , pres=1019.24, gas=53.23"New record created successfully
Temperature: 17.48
Humidity: 54.03
Pressure: 1019.2
Gas: 52.34
"temp=17.48 , hum=54.03 , pres=1019.2, gas=52.34"New record created successfully

Aborted!

しっかりと10秒おきにDBに記録されています。

次回はプログラムを見直し、単独で自動運転できるようにします。

ESP32 複合センサBME680

先日お知らせしたBME680による温湿度気圧、ガス濃度の分析です。

SCLは21ピン、SDAは23ピンにつなぎました。

今回は秋月電子のセンサを用いていますが、同じようにAdafruitでも同様のセンサキットを用意しており、GithubにてMicroPython用に用意されているAdafruithttps://github.com/robert-hh/BME680-Micropythonのモジュールを用います。

まずはモジュールです。

このモジュールを用いますと簡単に測定できます。Adafruitで用意しているテスト用プログラムを使用し、毎度のプルアップをソフト的に行います。

あっという間に出来上がりです。

C:\Users\>ampy -p com3 run c:\micropython\bmetest.py
Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead
15.30285 45.3333 1031.108 269211
15.31457 45.40735 1031.111 116460
15.33859 45.47064 1031.105 124723

次回はこれを用いて、DBにつなぎます。

ESP32からMariaDBにデータをとばす

センサからのデータもとれるようになり、Wi-Fiにつながり、NTPで時計の補正もできるようになりました。

IoTを進める中で必要なのはデータベースにひたすらデータを放り込み、その中で、異常のあるデータをいかに早く見つけ出すかが重要になります。このため、今回はデータベースにMariaDBを用い、ESP32からデータをPHPにPOSTしデータベースに取り込む一連の流れを紹介します。

まずはデータベースを作成します。MariaDBのインストールその他は省略しまして、既にesp_dataというデータベースを作成してあるところから始めます。phpMyAdminを使用してデータベース中にSensorDataというテーブルを作ります。次のSQL文をphpMyAdminのSQLクエリを実行し、テーブルを作ります。今回テストの都合でMACadd列は省略してあります。

CREATE TABLE SensorData (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
//    MACadd VARCHAR(30) NOT NULL,
    value1 VARCHAR(10),
    value2 VARCHAR(10),
    value3 VARCHAR(10),
    reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)

テーブルが出来上がったら、適当にデータを入れてみます。

INSERT INTO SensorData(value1, value2, value3) VALUES (12.3,23.4,35.3)

実行を押すとSQL文が実行され、行が挿入されます。ここまで確認したら、次はMicroPython上でjsonを用いたPOST文を作成します。

MicroPythonではpythonで使用するjsonとrequestsの頭にuをつける形になります。この形でpostできます。

次にデータを受けるphp側を作成します。

コマンドラインからampyを用いて上記MicroPythonのプログラムを走らせた結果が次です。

C:\Users\>ampy -p com4 run c:\micropython\posttest.py
New record created successfully

phpMyAdminで確認しても新しいレコードが挿入されています。

 編集 コピー削除 削除1712.323.435.32021-02-25 19:35:51

ESP32 時計まわり

ESP32をWi-Fiにてネットワークにつなぎましたので、次は時計まわりを整備します。

ESP32にはリアルタイムクロック(RTC)が実装されていますので、まずはどのような反応が出るか見ます。

>>> from machine import RTC
>>> rtc=RTC()
>>> rtc.datetime()
(2000, 1, 1, 5, 0, 2, 41, 237515)

2000年1月1日ですね。これでは時計として使えませんので、NTPサーバーに接続して現在時刻(UTC)に合わせます。

>>> import ntptime
>>> ntptime.settime()
>>> rtc.datetime()
(2021, 2, 22, 0, 22, 6, 52, 654317)

2021年2月22日22時6分52秒ですか、4個目の0は多分曜日を表しており月曜日、654317は・・・

>>> import utime
>>> utime.localtime()
(2021, 2, 22, 22, 16, 34, 0, 53)

utimeでローカルタイム表示で見てみましょう。

2021年2月22日22時16分34秒月曜日、年内の通算日数53日目(31+22=53)これはUTCですので、JSTに合わせます。

>>> utime.mktime(utime.localtime())
667355194
>>> utime.mktime(utime.localtime())+(9*3600)
667387595
>>> utime.localtime(utime.mktime(utime.localtime())+(9*3600))
(2021, 2, 23, 9, 26, 38, 1, 54)

9時間進めますutime.mktime()関数でローカルタイムを秒数の整数に戻します。この整数にJSTは9時間進んでいますので9時間×3600秒を足してあげます。この整数をutime.localtime()関数で時間に戻します。すると2021年2月23日9時26分38秒火曜日54日経過と日本時間に変更できました。

全体のプログラムです

実行経過です。

C:\Users\>ampy -p com4 run c:\micropython\timetest1.py
network config: ('192.168.11.25', '255.255.255.0', '192.168.11.1', '192.168.11.1')
2021/2/23 9:39:41

ESP32 ネットワーク接続

今回はESP32をWi-Fi接続してみました。

Wi-Fi接続は結構簡単で、MicroPython DocのESP32用クイックリファレンスhttps://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.htmlに詳しく書かれています。今回はこれをそっくり踏襲します。

まずはTera Term上でコマンドでの反応を見ます。

>>> wlan = network.WLAN(network.STA_IF)   #Wi-Fiをステーションモードにします
>>> wlan.active(True)             #アクティブ化確認します
True
>>> wlan.connect('essid','password')     #essidにはつなぐWi-Fiのessidを、passwordにはパスワードを入れます
>>> print('network config:',wlan.ifconfig()) #Wi-Fi接続のコンフィギュレーションをプリントします、ipアドレス、サブネット、ゲートウェイアドレス、DNSアドレス
network config: ('192.168.11.25', '255.255.255.0', '192.168.11.1', '192.168.11.1')
>>>
>>> wlan.scan()                 #Wi-Fiの電波のスキャンをします
[(b'Buffalo-G-****', b'4=\xc4\xc3\x17\x98', 11, -41, 3, False), (b'rs500m-e17ec9-1', b'\x10KF\xe1~\xcc', 6, -67, 3, False), (b'rs500m-e17ec9-2', b'\x12KF\xe1~\xcc', 6, -69, 3, False), (b'TOBU_Free_Wi-Fi', b'\x00\x14\x06(\x191', 1, -84, 0, False), (b'aterm-36fa28-g', b'\x10f\x82M\xd2\x08', 8, -85, 4, False), (b'SPWH_H33_129E8B', b'0\xa1\xfa\x12\x9e\x8b', 2, -86, 4, False)]
>>>

これで、Wi-Fiへの接続ができることを確認しました。実際のプログラムではクイックリファレンスにあるように、関数で定義して、つなげばオッケーです。

ampyを使用してプログラムを走らせると、以下のような結果になります。

C:\Users\>ampy -p com4 run c:\micropython\wifitest.py
connecting to network...
network config: ('192.168.11.25', '255.255.255.0', '192.168.11.1', '192.168.11.1')

温度センサADT7410を用いた温度測定

前回のDHT11から、時間がたちましたが、ブレッドボードに乗っていたADT7410を用いて、温度測定をしてみたいと思います。DHT11はワンワイヤーで、ESP32自体でライブラリをもっていたので楽でしたが、ADT7410ではしっかりとメーカーの仕様を読んでおかないといけません。

メーカーのアナログデバイシスのホームページから、資料をダウンロードします。https://www.analog.com/media/en/technical-documentation/data-sheets/ADT7410.pdfの12~13ページに書いてありますが、13ビットでの測定では0x00から2バイト拾って、くっつけて、うしろの3ビット分を切ると言う作業が必要になります。

今回はsclを18ピンにsdaを19ピンに設定しました。ADT7410もプルアップが必要なので、まずはプルアップします。

>>> from machine import SoftI2C, Pin
>>> p18 = Pin(18, Pin.IN, Pin.PULL_UP)
>>> p19 = Pin(19, Pin.IN, Pin.PULL_UP)

その後softi2cでデータを読み込みます。

>>> data = SoftI2C(scl = Pin(18), sda = Pin(19), freq = 10000).readfrom_mem(0x48, 0x00, 2)

ここで、2バイト分のデータを見てみます。

>>> print(data[0])
10
>>> print(data[1])
224

10進数でプリントされるので、2進数でプリントさせます。

>>> print(bin(data[0]))
0b1010
>>> print(bin(data[1]))
0b11100000

data[0]は00001010、data[1]は11100000となってます。data[0]を左に8ビットずらしてdata[1]をつなげます。

>>> print(bin(data[0]<<8 |data[1]))
0b101011100000

0000101011100000となりました。右側3ビットは不要ですから、右に3ビットずらします。

>>> print(bin((data[0]<<8 |data[1]) >>3))
0b101011100

0000101011100になりました。10進数に治すと、

>>> print(((data[0]<<8 |data[1]) >>3))  # temp=print(((data[0]<<8 |data[1]) >>3))
348

これを13ビットですから、資料にあるとおり16で割ります。

>>> print(((data[0]<<8 |data[1]) >>3)/16)
21.75

これで温度21.75度が出てきました。

このセンサではマイナスになるとファーストビットに1が立つので、13ビットで1000000000000は10進数で4096ですから、tempがこの数より大きい場合はマイナスの温度になるのでtemp=temp-8192とすればOKです。例フルビット1111111111111は10進数で8191ですから、8191-8192=-1これを16で割って-0.0625度となります。

温湿度計DHT11を用いた温湿度測定

今回はESP32を用い、一番簡単なセンサーによる温湿度の測定について紹介します。

ESP32はMicropythonにて簡単にプログラムを書くことができ、IoTには最適なデバイスです。今回はこれにDHT11という温湿度センサを接続し、温度と湿度を測定するプログラムを紹介します。

まずはブレッドボードを用いてESP32とDHT11を接続します(写真の青色のセンサです。左型のセンサは別途紹介します)。

写真のとおり左からVCC(3.3Vもしくは5Vに接続)、信号線(今回はピン4に接続)、一個飛ばして一番右のピンはアース(GND)に接続します。信号線は2ピンとワンワイヤーのセンサーとなります。参考資料はこちらです。https://akizukidenshi.com/download/ds/aosong/DHT11_20180119.pdf

ESP32ではDHT ドライバはソフトウェアで実装され、すべてのピンで動作するとのことで、Micropythonの公式ホームページhttps://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html#dht-driverに書いてある例を用いて、動かしてみます。

>>> import dht
>>> import machine
>>>
>>> d = dht.DHT11(machine.Pin(4))
>>> d.measure()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "dht.py", line 17, in measure
OSError: [Errno 110] ETIMEDOUT

いきなりエラーです。DHT11の上記リンクにのせたプロダクトサービスをよく読むとI/Oは電源とプルアップした回路にしなさいと書いてあります。

プルアップ用の抵抗は持っていますが、ESP32のGPIOにはプルアップもソフト的に使えますので、そちらで対応です。

>>> import dht
>>> import machine
>>> from machine import Pin   #class Pinをインポート
>>>
>>> p4 = Pin(4, Pin.IN, Pin.PULL_UP)  #4番ピンをプルアップ
>>> d = dht.DHT11(machine.Pin(4))
>>> d.measure()
>>> print(d.temperature(),'C')
20 C
>>> print(d.humidity(),'%rh')
44 %rh

これで、温度と湿度が測定できます。(温度は少数点以下ありませんが・・・)

後日、精度高い温度計での測定をします。

ESP32のファームウェアアップデート

新品のESP32を仕入れてあったので、microPython仕様にするためファームウェアのアップデートをしました。ファームウェアについてはhttp://micropython.org/download/esp32/に最新版がありますし、アップデートの仕方も説明がしてあります。

まずは元から入っているファームを消去します。ファームの入れ替えはesptool.pyを使用します。今日はUSBのポートはCOM4です。

C:\Users\>esptool.py --chip esp32 --port com4 erase_flash
esptool.py v2.2
Connecting....
Chip is ESP32D0WDQ5 (revision (unknown 0xa))
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 10.3s
Hard resetting...

次にあらかじめダウンロードしているファームウェアを書き込みます。

C:\Users\>esptool.py --chip esp32 --port com4 write_flash -z 0x1000 c:\micropython\esp32-idf3-20210202-v1.14.bin
esptool.py v2.2
Connecting.....
Chip is ESP32D0WDQ5 (revision (unknown 0xa))
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 1445632 bytes to 925476...
Wrote 1445632 bytes (925476 compressed) at 0x00001000 in 82.8 seconds (effective 139.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting...

ampyで確認しようとしましたが、上手くいかず、TeraTermでシリアル接続してファームを確認しました。

ちゃんとファームウェアアップデートされています。

ts Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5008
ho 0 tail 12 room 4
load:0x40078000,len:10600
ho 0 tail 12 room 4
load:0x40080400,len:5684
entry 0x400806bc
MicroPython v1.14 on 2021-02-02; ESP32 module with ESP32
Type "help()" for more information.
>>>

上にあるように、help()コマンドをたたくと、一寸した例文が出ます。

>>> help()
Welcome to MicroPython on the ESP32!

For generic online docs please visit http://docs.micropython.org/

For access to the hardware use the 'machine' module:

import machine
pin12 = machine.Pin(12, machine.Pin.OUT)
pin12.value(1)
pin13 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
print(pin13.value())
i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22))
i2c.scan()
i2c.writeto(addr, b'1234')
i2c.readfrom(addr, 4)

Basic WiFi configuration:

import network
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
sta_if.scan()                             # Scan for available access points
sta_if.connect("<AP_name>", "<password>") # Connect to an AP
sta_if.isconnected()                      # Check for successful connection

Control commands:
  CTRL-A        -- on a blank line, enter raw REPL mode
  CTRL-B        -- on a blank line, enter normal REPL mode
  CTRL-C        -- interrupt a running program
  CTRL-D        -- on a blank line, do a soft reset of the board
  CTRL-E        -- on a blank line, enter paste mode

For further help on a specific object, type help(obj)
For a list of available modules, type help('modules')

OSのリリース情報とディレクトリ構造を表示したところ、boot.py出来ています。

>> import os
>>> os.uname()
(sysname='esp32', nodename='esp32', release='1.14.0', version='v1.14 on 2021-02-02', machine='ESP32 module with ESP32')
>>> os.listdir()
['boot.py']

再度コマンドプロンプトから、ampyを用いてリスト表示をしたら無事にboot.pyも表示されており、無事にmicroPython仕様になっていることを確認しました。

C:\Users\>ampy -p com4 ls
boot.py