1行も自分で書かずにマイコンのプログラムが書けるか?
ChatGPTとの会話でどこまでマイコンのプログラムが書けるか?ちょこちょことやってきてかなり使えるところまで来たのでまとめてみようかと記事にしています。
はるか25年前にちょこっとC++とかで、プログラマー経験があったものの流石に25年も経っていると通用するものか?と思ってやってみています。
課題は簡単で、既存のマイコンがありそれを今の機材に置き換えると言うもの。
そこで、問題がひとつ。メインコントローラーが20年前のマイコンのアセンブラしかない![]()
そのマイコンのコードなんかとーぜん知ってるはずもないので、今流行りのChatGPTさんに聞いてみる。サクッとMPUの命令セットの概要からか?やっていることの概要をまとめてくれて。
あれ?これぐらいのことなら、専用のマイコンじゃなくて出来るかも⁉︎
専用マイコン→シリアル通信→モーター制御(専用マイコン)
この赤の部分だけなのでなんとかなるかと。
モーター制御側は、C言語のソースがあるのでデータを受け取って何をしているか?推定はできそう![]()
機器選定からメインコントローラーをラズパイよりディスプレイの基盤が大きい![]()
表示部をRaspberry Pi Zero 2 WH用7インチタッチディスプレイ
モーターにシリアル通信コマンド送信をSeeeduino Nano→結果的に、Seeed Studio XIAO ESP32S3になるのですが![]()
まず、稼働させるモーターのFWと実機から通信パケットを探り始める![]()
すると、うむむ!ハードウェアUARTを使ってない!汎用ポートで自力でBitBang通信していることが判明![]()
※ここが後に大きな落とし穴になるのは本人も分かっていない
BitBangしていたのはメインコントローラー側だったのですがそれは、メインコントローラー側にハードウェアUARTが足らなかったから?ではないかと推測
今時、安いロジックアナライザーで簡単に信号が測れるので助かるー!
しかし、ここからが意外と大変![]()
自分のキャリアブランクが長すぎてわからんことだらけ![]()
モーター駆動の24V 信号線の3.3Vと5Vラインを、テスターで短絡させて回路を壊したり![]()
回路のお勉強をちょっぴりしてみたり。
しかし、20年前とは雲泥の差で、安価で便利なものがあるのでなんとか乗り越えて、
ラズパイ(3.3V)とArfuino Nano Every5.0V(Seeeduino Nano)もBSS138を4つ使った4回路のモジュールAE-LCNV4-MOSFET(BSS138)で簡単に接続![]()
意外とブレッドボードの接触不良のコツを知ったり、自分が子供の頃のマイコン少年みたいに楽しんでおります。
シリアル通信とは言え、ハードウェア通信で元々がないので、ターゲットのマイコンとお話がまだ出来ておらず。
万全を整えるべく、もう一台のArduino Nano Everyをコントローラーのエミュレーターとして使って通信経路をある程度万全にしておかないと、実機の時にさっぱり分からなくなるので、実施。
やっとのこと、エミュレーターから答えが送信されてきたものの、ビットが間違っとる‼️![]()
ChatGPTさんとかなりの会話を進めて。
中継機能側がシングルタスクなのでどうしても返信信号を出せないのではないか?という会話が出てきて、低価格のマイコン Seeed Studio XIAO ESP32S3 が、2Coreで、マルチタスクが出来るので、これなら大丈夫
となって、早々に手配してて研究
【データ通信往路経路】
Arduino nano every (ターゲット装置のエミュレータとして5V) <-秋月(AE-LCNV4-MOSFET(BSS138))-> ESP32S3 (2core FreeRTOS) <-> ラズパイ(3.3V)
【データ通信復路経路】
ラズパイ(3.3V) <->ESP32S3 (2core FreeRTOS)<-秋月(AE-LCNV4-MOSFET(BSS138))->Arduino nano every
とマルチタスクならなんとかなると思ってたらそれが素人の甘いところでした。
そもそも、秋月(AE-LCNV4-MOSFET(BSS138)のレベルシフタが曲者でした。
Chat GPT 4o は、プロンプター側に寄り添う傾向が強いという噂を聞いていましたが確かにそうでした。問題点をまとめると。
データの往路で、 5.0V ->レベルシフタ(BSS138)->3.3V にするときの信号がとれずに苦戦そこから逆に応答送信でどうしても、Arduino nano every からの信号の読み取りが上手くゆきませんでした。
元々、ハードウエアに弱い自分だったので、遥か昔に先輩が言っていた言葉を手繰り寄せながら、ChatGPT 3oと対話を続けると凄く粘り強く回答に導くくれるように会話が続きました。
最終的に矩形波パルスのΔ(デルタ)をスキャンするプログラムを試してみると、Δがいつまでも決まらない。つまり波形が波になっていて、矩形波でないとESP32S側が思ってしまうということらしい![]()
レベルシフトをする時に信号の補正の為に、10KΩの抵抗でプルアップさせると学んでいたので大丈夫だろうと踏んでおりましたが。やはり、ただの抵抗であって、信号の波に影響があるんは自明の理だったようですが、また、ChatGPT 3oさんにクレーム![]()
すると![]()
TXB信号(分圧後)の波形は明確に“なまっている”
- TXB(= Arduino TX → 分圧 → ESP32 RX)に相当する信号ラインを見ると:
- 立ち上がり・立ち下がりが丸く、傾斜的
- 特にスタートビットにあたる部分がなだらかで、ESP32のUART回路が「誤検出」または「無視」するレベル
- これはESP32が受信できない最大の理由
この回路図を見るとマイコン初心者でない人はあーあーコイツやっちゃってるよー![]()
ってなるんでしょうね?![]()
DC-5V を DC-3.3Vの信号にトランジスタ+抵抗で電圧を信号を調整すると、本来は矩形波になるところが、波みたいになって、それが「なまっている」という事になるらしいです。
【参考波形図】
信号が「なまる」とは、こんなイメージらしいです。
確かに信号は出ているけど、下の青い信号では、ESP32S3では?この信号?違うなぁ?とスタートビットを検知してくれないそうです。
さらに、ChatGPT 3oさんと会話
じゃーどーすれば信号が鈍らないように出来るのさ?![]()
ChatGPT 3oはある程度の時間をかけて推論するので、きっちり答えを出してきました。
とあっさり本当の回答を出してきました![]()
最初から言ってよー
ですが。
ズボラな私は、そんなICをハンダ付け出来るはずもないので、そこからはGoogleさんで調べると。
やっぱり、頼れるのは秋月電子通商さん。
そこで、今後の為にさらに勉強の為に、ChatGPT 3oさんと会話
波形のイメージの「なまる」を電子工作素人にもわかるように解説して!
【波形イメージ】
良い波形 (バッファIC)
---| ̄ |___________| ̄ |--- ← 立下り ≈10ns → UARTが一発認識
悪い波形 (抵抗分圧)
__/ ̄ \______/  ̄\--- ← 立下り 5µs。しきい値付近でモタモタ
^ ^ ← ノイズで “ガサガサ” → 誤検出
UART 受信側がエッジに求めるもの
| パラメータ | 大ざっぱな目安 |
| 立ち上がり/立ち下がり時間 (tr / tf) | ビット幅の 5〜10 % 以内 |
| スタートビット検出の条件 | “ハイ→ロー”しきい値を一度だけ確実に跨ぐ |
| ESP32 内部オーバーサンプリング | 16×(115200 bps → 約 1.84 MHz) |
計算してみる
| ボーレート | 1ビット幅 | tr/tf が許される長さ |
| 115200 bps | 8.68 µs | ≦0.8 µs 程度なら余裕 |
| 9600 bps | 104 µs | ≦10 µs くらい |
| 300 bps | 3333 µs | 330 µs も許されるはず…だが実は危ない |
分圧 vs. バッファの具体的な立ち上がり
| 回路 | 典型 tr/tf | 形 |
| 2 kΩ:1 kΩ 分圧 + ワイヤ容量 (≈ 20 pF) | 約 τ=R×C = 2 µs/90 % 立上りで ≈ 4.6 µs | 台形・丸い / ̄\ |
| 74LVC8T245 出力 | 10–20 ns | カクッ_| ̄|_ |
115200 bps なら 0.01 µs vs 8.68 µs → 十分速い
分圧は 4–5 µs、9600 bps の 10 µs マージンには入るが、ノイズ窓が広いのでミスが起きやすい
300 bps だと「時間的」には余裕でも、ノイズ&ハミングのせいでスタートビット誤判定という別の問題になるという説明
「波形がなまる」ということがよくわからなかったので、ChatGPTさんに詳しく教えてもらう。本当に勉強になります。ChatGPT 3oさんに感謝です。
信号問題が終息するか?は以下のロジックで明確らしい![]()
1.BSS138 分圧 → LVC16T245 バッファ 波形が鋭く・揺れが小さくなる → Δスキャンで「失敗=false」が激減し、Δサーチアルゴリズムですぐ収束値が見つかる
2.エッジのジッタ低減 Δの許容窓が狭くても安定 今まで 200–1200 µs 探っていたのを、100–600 µs 程度まで絞れる可能性
3.立上がり/立下がり時間短縮 ビット中心が読みやすい waitValidStart() のデバウンス 300 µs ももっと短く設定可
実を言うと専門用語が分かりやすくて、ググりながらよーやく理解。
そもそも、ジッタって何やねん!からです...
♪じったばったするなよ~♪スミマセン![]()
それで、結局 2ch両方使える 16bit AE-LLCNV-LVCH16T245 に落ち着く
シルク印刷を見てもシンプル。
2chあり、1A, 2A, 1B, 2B, 1OE,1DIR, 2OE, 2DIRと要するに信号方向と信号を落とすことをコントロールする信号を入れれば、性格にレベルシフト出来るというバッファICだそうです。
落ち着いてつなげば秒で終わるはずが他の用事をしながらささっとつなげると
やっぱり、2chがちゃんとドライブできてない(ケーブルがちゃんと繋がっておっちょこちょいな自分
)
で、ケーブルをちゃんとつないで、プログラムを修正すると、ドライブ完了!
もともと、自力でBitBang通信をしようとしていたので、矩形波のΔの値が取れずに、スタートビットの検出に失敗していたのですが。安定はしてきました。がっ!やっぱり、自力で波形を処理するのは大変面倒なことがわかり、断念。
あっさりとハードウエアUARTに方向転換をChatGPT 3oが勧めてくる
それ、1番最初にハードウェアUARTだと、出来ないって言ってたじゃん‼︎嘘つきっ
きっと、このおじさんは勉強しないとダメだな。と、直感でAIが感じたのかもしれません![]()
ESP32S3が、元々3本ハードウェアUARTをもっていたのも幸いでした。Arduino IDEでも、モニター用を含めてしっかり、3本使えるのでよかったです。
でも早く言ってよーである![]()
早々にコードを通信信号のΔ最適値を大まか探せたので、SN74LVC16T245のIC バッファが、レベルシフタとして十分機能している確認にはなったので、コードを修正。
というか一から作った方が早いので、ChatGPT 3oさんにお願い。ものの数秒で完成するけど。忘れっぽいChatGPTさんは、ちゃんと言わないと大前提を忘れます![]()
AIさん!SN74LVC16T245をドライブする初期設定抜けてますよ!もう約束わすれました?修正して完全なコードにしてね
とプロンプトに入れると、しっかり覚えているので簡単に修正完了。
【ちゃんとパルス出てるじゃん
】
あっさりと、パケットの中継コードが完成。
現時点のChatGPTについてですが、深く推論する3oと自分のプロンプトと目的には合っていたようです。
ようやく、実装段階の細かいパケット内容がったり制御にまつわる部分に取り掛かれます。
しかし、ハードウェアの素人の自分に、まるで失敗を通して教えてくれるかの様に次々とヒントを出してきて、最終的な回答はそれかよ!ですが、知らなかったハードウェアに近いところを学ぶ事ができたのは、ChatGPTのおかげです。
何でもそうですが、すぐに答えが出て仕舞えば中身をよく理解せずに出来ちゃうと、もっと困った事が実際に運用した時にどうしようもなくなるので、ある程度細かいところは知っておくことも大切ですよね![]()












