【試したらできた】ChatGPT ではじめる IoT と電子工作
今回は、今話題の ChatGPT を使って、簡単な IoT システムを作れるか試してみました。
想定
今回は「IoT、電子工作、プログラミングが初めてな人が ChatGPT でどこまで作れるか?」という想定のもとで検証してみたいと思います。
作るもの
「Raspberry Pi で 温湿度センサーから温度と湿度を取得してクラウドに送信するシステム」を ChatGPT を使いながら作ります。
それではやっていきましょう。
用意するものを聞いてみる
今回は Raspberry Pi は既存のものを使いますが、「準備するものは何か?」という質問から始めました。
詳細な製品名までは回答にありませんでしたが、必要となる機材を全てリストアップしてくれました。さらに温湿度センサーとして「DHT11」や「DHT22」といった定番のものを教えてくれました。
尚、今回は Raspberry Pi 本体や周辺機器は既に手持ちのものを使うことにしたので、Raspberry Pi 関連機器については質問をしていません。
次に、温湿度センサーについて詳しく聞いてみます。
なんと 3 種類も教えてくれました。ここで得られた情報を元に「adafruit dht22センサー amazon」というキーワードで検索すると、Amazon の商品がヒットしました。これで実際に購入すべきセンサーまでたどり着けました。
この基板付きのセンサー(3ピンのもの)はプルアップ抵抗が内蔵されているので、ジャンパーワイヤーで直接 Raspberry Pi と接続することが可能です。
しかし、基板がない 4 ピンのものも販売されており、そちらを使う場合は別途抵抗が必要となります。そのあたりの事が回答に含まれていなかったのは注意が必要です。
Raspberry Pi とセンサーのつなぎ方を聞いてみる
材料は揃ったものとして、センサーを Raspberry Pi の GPIO ピンに繋げなければデータは取れません。ググればたくさん情報が出てきますが、つなぎ方も ChatGPT に質問してみます。
購入したセンサーの基板には「VCC」「DAT」「GND」と記載されているので、上記の回答で特に迷うことはないかと思います。(データ信号が「DOUT」と回答されていますが、許容できる範疇ではないでしょうか)
少々見づらいかもしれませんが、回答どおりに接続したものが以下の写真です。
Raspberry Pi を使ったことがある人ならピンへの接続は問題ないと思いますが、初めての場合だとどの GPIO ピンに接続すればいいか分かりません。慣れていても忘れている場合があるので、そんなときは pinout
コマンドが便利です。
Raspberry Pi 上でコマンドを実行するとグラフィカルにピン配置が確認できます。
とはいえ、やはり初めての場合だと pinout
コマンドなんて知らない人が多いはずなので、ピン配置も ChatGPT に聞いてみました。
図で教えてほしかったのですが、URL のリンクが正しくないので図が見れません。再び質問してみると markdown 形式ではなく 画像の URL を直接教えてくれました。
このリンクをコピペしてブラウザで開くと分かりますが、URL が変わっており新しい URL にリダイレクトされます。
リダイレクト先の正しい URL を ChatGPT に伝えて、改めてピン配置の図を提示してもらいました。
(リダイレクト先のページをスクロールしていけば、同じ図が見れますが…)
説明と図が合ってない部分がありますが、図を見ればセンサーをどこのピンに接続すればいいか分かりました。
データを取得する Python スクリプトを聞いてみる
実は先程の回答には続きがあり、Python を使ったデータ取得のスクリプトも提示してくれていました。
pip install
で sudo
が付いているのが気になりますが、Python のコードは見た感じだとそのままでも良さそうな内容です。下記は同じ内容のコードです。コピペ用に使ってください。
import Adafruit_DHT sensor = Adafruit_DHT.DHT22 pin = 4 humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) if humidity is not None and temperature is not None: print('Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity)) else: print('Failed to read sensor')
回答のあったコマンドを実行して Adafruit_DHT
のライブラリをインストールした後、提示されたコードを適当なファイル( dht22.py
)に保存して実行します。
$ python dht22.py Temp=24.8*C Humidity=33.6%
特にエラーもなく温度と湿度のデータが取れました。
ChatGPT との会話だけでデータ取得できました!
では次に進みましょう。どこまでできるのか楽しみです。
新しいライブラリを使うようにする
実は、当初提示された Adafruit_DHT
のライブラリは既に非推奨となっています。
そこで、新しいライブラリである CircuitPython-DHT
を使うように ChatGPT に聞いてみました。
(pip install
の sudo
が気になりますが)ライブラリが古い旨を指摘すると CircuitPython-DHT
の利用を勧められました。あわせて、Python のコードも新しいものを教えてくれています。
他の案として別のライブラリ DHT-sensor-library
というものを提案してくれているのですが、これは最初に紹介された非推奨のライブラリです。一旦これはスルーします。
CircuitPython-DHT
を使ったコードは下記になります。
import adafruit_dht dht_pin = 4 # DHT22のデータピンに接続したGPIOピン番号を指定 dht_sensor = adafruit_dht.DHT22(dht_pin) try: temperature = dht_sensor.temperature humidity = dht_sensor.humidity print(f"Temperature: {temperature:.1f} C Humidity: {humidity:.1f} %") except RuntimeError as e: print("Failed to read DHT22 sensor data:", e.args[0])
これを適当な名前(dht22_circuit.py
)で保存して、実行するとエラーになりました。
$ python dht22_circuit.py (中略) raise RuntimeError( RuntimeError: Timed out waiting for PulseIn message. Make sure libgpiod is installed.
このエラーについて、ChatGPT に質問してみます。
回答の通り、libgpiod2
をインストールして、コードも提示されたもの(dht22_circuit_v2.py
)に入れ替えます。
import board import adafruit_dht dht_pin = board.D4 # DHT22の信号ピンに接続されたGPIOピンの番号 dht_device = adafruit_dht.DHT22(dht_pin) # DHT22を使用する場合はDHT22クラスを使用 try: temperature_c = dht_device.temperature humidity = dht_device.humidity print("Temperature: {:.1f}C, Humidity: {}%".format(temperature_c, humidity)) except RuntimeError as e: print("Error: ", e.args[0])
これを実行すると温度と湿度の値が取れましたが、今度は Lost access to message queue
というメッセージも出るようになってしまいました。
$ python dht22_circuit_v2.py Temperature: 25.4C, Humidity: 31.9% Lost access to message queue
そこで、このメッセージの原因と解消方法も ChatGPT に質問してみます。
3つの原因と解決策を教えてくれました。しかし、1と2は既に設定済みなので該当しません。3つ目の解決策にある use_pulseio=False
を試してみることにします。
use_pulseio=False
パラメータの使い方も聞いてみます。
import board import adafruit_dht dht_pin = board.D4 # DHT22の信号ピンに接続されたGPIOピンの番号 dht_device = adafruit_dht.DHT22(dht_pin, use_pulseio=False) # use_pulseio=Falseを指定 try: temperature_c = dht_device.temperature humidity = dht_device.humidity print("Temperature: {:.1f}C, Humidity: {}%".format(temperature_c, humidity)) except RuntimeError as e: print("Error: ", e.args[0])
これをまた適当な名前(dht22_circuit_v3.py
)で保存して実行したところ、温湿度データだけ取得できるようになりました。
$ python dht22_circuit_v3.py Temperature: 26.8C, Humidity: 32.6%
MQTTブローカーに Publish する処理を追加してもらう
せっかくなので IoT らしく取得したデータを MQTT ブローカーに publish するところまでやってみましょう。
今回は、簡単にするために EMQ 社のパブリックブローカーを使うことにします。
提示されたコードは下記のとおりです。
import board import adafruit_dht import paho.mqtt.publish as publish dht_pin = board.D4 # DHT22の信号ピンに接続されたGPIOピンの番号 dht_device = adafruit_dht.DHT22(dht_pin, use_pulseio=False) # use_pulseio=Falseを指定 # EMQXのMQTTブローカーの情報を設定 mqtt_broker_host = "broker.emqx.io" mqtt_broker_port = 1883 mqtt_topic = "topic/temperature_humidity" while True: try: temperature_c = dht_device.temperature humidity = dht_device.humidity print("Temperature: {:.1f}C, Humidity: {}%".format(temperature_c, humidity)) # MQTTメッセージをpublishする message = f"Temperature: {temperature_c:.1f}C, Humidity: {humidity}%" publish.single(mqtt_topic, message, hostname=mqtt_broker_host, port=mqtt_broker_port) except RuntimeError as e: print("Error: ", e.args[0])
このコードでもいいのですが、このままだと連続的にデータを送ってしまい、ブローカーに負荷がかかる恐れがあるので 5秒間隔で送るように処理を追加しておきます。( 1 行目と 28 行目を追加)
これも ChatGPTに「5秒間隔でデータをpublishするように修正してください」と依頼したものです。
import time import board import adafruit_dht import paho.mqtt.publish as publish dht_pin = board.D4 # DHT22の信号ピンに接続されたGPIOピンの番号 dht_device = adafruit_dht.DHT22(dht_pin, use_pulseio=False) # use_pulseio=Falseを指定 # EMQXのMQTTブローカーの情報を設定 mqtt_broker_host = "broker.emqx.io" mqtt_broker_port = 1883 mqtt_topic = "topic/temperature_humidity" while True: try: temperature_c = dht_device.temperature humidity = dht_device.humidity print("Temperature: {:.1f}C, Humidity: {}%".format(temperature_c, humidity)) # MQTTメッセージをpublishする message = f"Temperature: {temperature_c:.1f}C, Humidity: {humidity}%" publish.single(mqtt_topic, message, hostname=mqtt_broker_host, port=mqtt_broker_port) except RuntimeError as e: print("Error: ", e.args[0]) time.sleep(5)
次に、動作確認のため適当な MQTT クライアントで上記スクリプトに記載されているトピックを Subscribe しておきます。
- ホスト:
broker.emqx.io
- ポート:
1883
- トピック:
topic/temperature_humidity
今回は「MQTT X」というクライアントアプリを使います。動作確認の準備ができたら先程のスクリプトを実行してみましょう。
(データを送りながらセンサーを手で握って温度と湿度が変わるようにしています。)
$ dht22_publish_to_emqx.py Temperature: 25.6C, Humidity: 35.9% Temperature: 25.6C, Humidity: 40.6% Temperature: 25.7C, Humidity: 51.5% Temperature: 26.3C, Humidity: 68.7%
下記は MQTTX による subscribe の様子ですが、ブローカー側にもデータが届いていることが確認できました。
最後に
ChatGPT の回答だけでデバイス側の設定からプログラムの作成までを試してみました。
簡単なケースだったのでネット上にもたくさん情報がある題材でしたが、特に困ること無くデータ送信まで実装することができたのは衝撃的です。
とはいえ、筆者は以前に DHT22 でデータ取得したことがあるので、無意識のうちに「正解にたどりつく質問」をしていた可能性があります。そのため全く初めての場合だとうまくできないことがあるかもしれないので、今回の内容は参考程度に見ていただければと思います。
また、電子工作の部分についてですが、回答を鵜呑みにして間違った接続をするとデバイスを壊してしまう可能性もあるので、「困ったときに調査するためのヒントをもらう」ような感覚で使っていくのがいいかなと思いました。
API も利用できるようになったので、他に面白そうなネタがあれば試してみたいと思います。
以上です。