先日ESP32というArduinoにWi-FiとBluetooth接続モジュールが搭載されたバージョンの(ような)マイコンを手に入れましたので、久々に電子工作をしてみました。今回は特にChatGPTに設計を手伝ってもらったので、スムーズに実装を進めることが出来ました。
この記事ではESP32を使った電子工作の方法を書きつつ、ソフト開発をする際にどのようなドキュメントを用意すればよいのか、そしてChatGPTを使うとどれだけ実装が楽になるかについて書いていきたいと思います。
-
-
ChatGPTを使いこなせば、人生が変わる。僕が実感した生成AIの本当の力
みなさんはChatGPTなどの生成AIを使っていますでしょうか? 2024年頃から話題になり始めた生成AIですが、僕もこれが出始めた当初とりあえずChatGPTを触ってみたものの、イマイチ使い勝手が ...
続きを見る
何を作るのか
『天気予報表示ガジェット』を作ります!!
ESP32を使用してWi-Fi経由で天気予報サイトからAPIを使って情報を取得し、それをSSD1306の小型液晶ディスプレイに表示させます。
なぜ作ろうと思ったか
- ESP32でWi-Fi経由でデータを取得してみたかった
- RTOS(タスク制御)を動作させてみたかった
- ChatGPTを活用しながらソフト開発をやってみたかった
僕はこの3月から現場が変わって電車通勤がそこそこ長くなったのですが「これはいい機会だ」と通勤時間にマイコン制御について本を読んだりネット記事を検索したりと、イチから勉強をし始めたのです。その中でマイコン制御について色々知っていくと「ちょっとこれ自分でも試したいな」という思いが強くなりました。
中でもESP32というWi-Fi/Bluetooth接続ができるマイコンの存在を知り、電子工作への意欲が駆り立てられました。ネット接続が出来ないArduinoで自宅で手軽に電子工作をやろうと思うとせいぜいモーターと液晶ディスプレイを制御するぐらいで、電子工作のバリエーションってそんなにないんですよね。ただネット接続可能となるとできることは無限のように増えます。
また以前自分がArduinoで電子工作を行ったときはRTOSを使ったタスク制御が出来ない(と思い込んでいた)ので、タイマ割り込みを使って苦労しながら擬似的にタスク制御を行っていたのです。ところが最近になりArduinoでもライブラリを読み込めば、あのAmazonが無償で提供している『FreeRTOS』というRTOSを使用できるということが分かったのです。
そして何よりもChatGPTの存在が大きい。いくらESP32でネット接続できようともRTOSが使用できようとも、どのように実装してよいか分からなければ動き出すことが出来ないのですが、ChatGPTに「ESP32を使ってFreeRTOSを制御するプログラムを出力して」と言えばサンプルコードが出てきてしまうのです。これをみて僕は「行けるぞ!!」と思いました。
まずは構想を練る
これは電車の中でコピー用紙にやりたいことを次々と書いていきました。
歩いている時などに「こういうことを実現したいな」というアイデアが湧いてきたりするので、そこでスマホにメモをしつつ、電車の中でコピー用紙に構想をまとめていきます。
これが実際に僕が書いていた構想メモですが、設計をしているときはものすごくワクワクしましたね。大まかな構想についてはだいたい3日ほどで完成したかと思います。
やるべきこと
マストで表示すべきは
- 日付
- 気温
- お天気アイコン
です。
そしてこれらを表示するために、天気予報ガジェットでは2種類のモードを設定します。
確認モード(構想メモでは「選択モード」)
ボタンの押下で「今日」→「明日」→「明後日」の一日ごと天気情報を表示していきます。
スライドモード
ボタン押下なければ3時間ごと向こう3日間の天気情報をスライドショー形式で表示していきます。
スライドモード時にボタンが押下されれば確認モードに遷移します。
確認モードでボタン押下がない状態が一定時間続けばスライドモードに遷移します。
必要なモジュール
構想メモを作成していく中で、必要なモジュールも見えてきました。
とりあえずは大きく分けて4つのモジュールがあれば機能は満たすことが出来そうです。
スイッチ入力(swin:SWitch INput)
スイッチ入力を制御します。チャタリング対策を施したうえで本モジュールからは「現在のスイッチ押下状態」「前回のスイッチ押下状態」を公開します。
モード管理(modem:MODE Manager)
スイッチの状態を受けて、スライドモードか確認モードのどちらに入るかを制御します。
またスライドモードでも確認モードでも、どの情報(今日なのか明日なのか、何時の時間を表示するのか)を決めます。
天気情報取得(weather:WEATHER information get)
Wi-Fi経由でネットから天気情報を取得します。
ディスプレイ表示(disp:DISPlay)
- 現在のモード
- 天気情報
- いつの情報を表示するか
から実際に液晶ディスプレイを制御して天気情報を表示します。
各種設計書を準備
大まかな構想も完成したところでドキュメントを準備していきます。
とはいえどのように要件定義書から基本設計書、詳細設計書を作成してよいか分からなかったのでChatGPTにお願いして質疑応答形式でドキュメントを作成してもらうことにしました。
すごすぎるだろ、ChatGPT。
質疑応答していくだけで要件定義書が完成したぞ。
作成した要件定義書
要件定義書が完成したところで基本設計書の作成に移ります。
こちらもChatGPTの質疑応答だけで完成します。
作成した基本設計書
当初は基本設計書まででよかと思っていましたが、せっかくなので「詳細設計書」と「モジュール設計書」も作成しました。
詳細設計書
モジュール設計書
usertask
swin
modem
weather
disp
これでドキュメントは一通り完成!!
実装までやってくれるChatGPT
一通りドキュメントが完成したところで、あとは自分でコードを書いて実装を行うつもりだったのですが、なんとChatGPTが実装までやると提案してくれるじゃないですか!
「さすがに精度高い実装は無理だろ~」と思っていたのですが、ほぼそのままマイコンにソフトを書き込めてしまうようなコードが出てきて腰を抜かしました。
もちろんこちら側が設計の段階からかなり精度高く情報を渡していたからコードも精度高く出力されたのですが、もうこれならエンジニアが不要になってしまうレベルです。
あとは細部のコードを手直しして実際にマイコンに書き込みます。
出力されたソース
★ESP32_WeatherSystem_Source.zip
※そのままESP32に書き込んでも正常に動作しません。(手直しが必要です)
トラブルシューティング
ChatGPTが出力したコードをもとにマイコンを動かしていたのですが、さまざまなトラブルが発生したため、その経緯をご紹介します。
ArduinoIDEとシリアルモニタ
スイッチ入力を行うswin.cppを単体で検査する際、当初は実際にスイッチを取り付けるのが面倒だったので、スイッチのON/OFF情報はArduinoIDEのシリアルモニタから送ることにしました。
0か1をシリアルモニタから送るのですが、これが思うように値が送れない。
原因を調べたところ
- ArduinoIDEにおいてシリアルモニタから数値を送ると、それは数字として認識されてしまう
- 「改行なし」を選ばないと、ひとつ数値を送っても改行コードがその次に自動的に送られてしまう
とのことでした。
volatile const とポインタ
volatile constで設定したテーブルをポインタで受け取ろうとすると、受け取る側もvolatile const設定していないとエラーになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
volatile const char suuji_tbl[5] = {0, 4, 2, 8, 5}; //----中略----- void disp(void){ char* t_ptbl; t_ptbl = suuji_tbl; //t_ptblがconstではないのでエラーになる //エラー解決のためにはconst char* t_ptblと宣言する //----中略----- } |
IOピンがダメな時がある
ESP32の2番ピンからON/OFFを取得しようとしていたのですが、いくらやってもONのまま変化しませんでした。
痺れを切らして隣の4番ピンで情報を取得したら即座にON/OFFが取れました。ESP32、結構ピンがダメになってることが多いそうです。
スタックオーバーフロー
WI-Fiから天気情報を取得するあたりでマイコンのリセットがかかってしまう模様。
結果として原因はスタックの確保サイズがコピペミスで819byteになっていたので8192byteに直したら問題なく動くようになりました。
いや~これは原因を探るのが大変でしたね。
一つ一つSerial.print("通過")というコードを追加して、どこまでプログラムが走ってるかを確認してみて、weather.cppで止まるので「ここで何か処理の重いことをやっているか?」と考えたところ、スタックサイズに行き当たりました。
漢字/お天気アイコンとビットマップC配列
今回の電子工作一番の難所が「漢字」と「お天気アイコン」を表示するところでした。
U8g2というライブラリを使えば漢字もお天気も表示できるのですが、あまりにもROM容量を取ってしまうので、断念。代わりにビットマップC配列という、漢字やアイコンを(ドットの)画像データとして配列データに置き換えて表示することにしました。
その際画像データをビットマップC配列に変換してくれる『image2cpp』というサイトを使ったのですが、こちらの操作方法がよく分からず延々と悩んでおりました。
ここでDraw modeをHorizontalにする必要があるのですが、他のサイトで「SD1306を使うときはVerticalにしないとダメ。Horizontalにしがちだけど気を付けて」とあったので、延々と誤りであるVerticalでデータを作っていたのでまともに表示がされませんでした。
イギリスの標準時間
今回天気情報を取得するのにイギリスのサイトであるOpenWeatherMapのAPIを使用したのですが、データ自体は僕の住所である名古屋のお天気情報を取得していたものの、時間がイギリス時間のままになっていました。
名古屋(日本)とイギリスでは8時間違うので、そこを考慮に入れなくてはいけませんでした。
完成品
天気情報取得ガジェットを作ってみて良かったこと
天気情報取得ガジェットの構想は2025年4月の頭に思いついて、そこから取り組んでだいたい40時間ぐらいで完成したように思えます。
そこそこ時間はかかったもののやってよかったなと感じることが多かったので、その点について書いていきたいと思います。
スキルが身についていることを実感した
まずは圧倒的にこの感覚がありました。
ESP32というWi-Fi付きのマイコンの存在を知り、そしてChatGPTにサンプルコードを出してもらったことで「これなら自分でもRTOSを使いつつ天気情報を取得するガジェットを作れるのでは?」と思いつき、実際にそれを作れたことは大きな自信になりました。
こうやって「Wi-Fiから情報を取得して、それをディスプレイに表示して―」なんて事務職をやっていた数年前からは考えられないスキルです。今回RTOSを使いつつ電子工作も出来たということで、こちらをポートフォリオに加え、いつかの転職のための武器の一つにしようと思います。
また電子工作をやっている間は、純粋に楽しかったです。特に通勤の行き帰りの電車の中でコピー用紙に構想を書いているときは「こうすれば出来るだろう」とか「モジュールの構成はこうして」など考えている間が一番エキサイティングでしたね。
RTOS(タスク制御)の仕組みについて理解できた
普段の現場ではタスクの追加(など滅多にありませんが…)をするときはツールでやってしまいますし、何よりもそれっぽいマニュアルもあるので腹落ちしていなくてもソフト自体は作れてしまうのですが、やっぱりRTOSを自分自身で制御してみたいなと思いました。
ESP32を使って小規模にタスク制御をやってみると、次々と「あぁ、RTOSってこういう仕組みになってるから現場ではああいうルールになってるんだ」と今まで疑問に思っていたことが次々と氷解していきました。
ChatGPTの使い方がわかった
ほんとChatGPTは今後の世の中のゲームチェンジャーになりますよ。
それにドキュメントの整備に関してもChatGPTと一問一答の応答で自動的に完成するし、コードもタスク制御のところのサンプルプログラムから、天気情報取得のコードについても全部ChatGPTが出してくれるので大枠で詰まる所がありませんでした。
今後生成AIが世の中にとってなくてはならないものに変わるのは間違いないので、早いうちにChatGPTの可能性に気づけてよかったです。
今回はお手軽に天気情報取得ガジェットを作りましたが、Wi-Fiを使って他にもやりたいことがたくさんあるので、また近いうちに別の工作に取り掛かろうと思います。
自分が「こうすれば多分出来るだろう」と思えるものはChatGPTの助けを借りれば実装できそうなので、また楽しみながらやっていきます!!