次に、SPI通信でADC MCP3208のデータをラズピコで読んでみる。
Raspberry Pi Picoでプログラミング ⑬ spi APIとA-DコンバータMCP3008
このサイトを頼りに配線。
プログラムを移植するが、うまくいかない。SPIDEVが無いと怒られる。その他はC言語の解説サイトばかり。。今回自分が使っているのはMicroPython。
Raspberry Pi Picoを使ってADC(LTC2462)からカウント値を取得する
ここが参考になるかも。しかし、この通り書いても動かない。
SPIオブジェクトにそんなメンバはないと怒られる。。ではクラスのメンバは何があるのか?ということで
クラス SPI -- シリアルペリフェラルインタフェース バスプロトコル(マスタ側)
ここも参考にしながら格闘中。
今回はかなりドハマりしたが、以下結果。
- ケーブル配線ミス。MCP3208のDoutを分圧してpicoに取り込んでいるが、電圧のより低い方に配線していた。
- SPIの関数をどれにすればよいかわからなかった。総当たりで試した結果、結果的にはwrite_readintoがよかった。なぜこれが良くて他はだめなのか、技術的な観点は追いかけていない。
- 配線設計ミス。CSピンをつないでいなかった。
- CSピンをずっとグラウンドにつないでいる参考サイトがあって、そこを参考にしたのが一番の失敗→参考サイトの情報は信じてしまうので、こうなるとつらい。
- CSピンはラズピコにつないで、きちんと1→0にしてやらないとデータを読んでくれない
- ラズパイの時と違って、CSピンの制御はSPIの関数群に含まれていない。よって、自前での制御が必要
- ラズピコにはSPIのID0と1がある。それはいいのだが、ID0の中でもピンが2セットある。どれを使えばいいのか、どれを使ってもいいのか、不明。これは実験してみてもよいかも。→後で試してみたら、4番ピン(SPI0 SCK)だとうまくいくが、9番ピン(SPI0 SCK)だとうまくいかなかった。これも技術的な理由は不明。
上記をうけて、回路図を書き直し。
うまくできた!
print文なしのシンプルなプログラムでADC読み込みをループした。
1秒当たり2564回実行していた。すると、1実行0.39msということになる。
毎ループ実行する必要がなさそうなものをfor文の外出しにしても0.3msくらい。
うーん、ラズパイ+ADCのときと変わらないか遅いくらい。。。。マイコンは余計な処理がない分、速いイメージがあったが、ラズピコにしてももそんなに早くならないんだな。プロセッサの違いだろうか。ボーレートを3倍にしても変わらず。
MCP3208のCH0~CH7を走査してみると、10000回実行に25秒かかった。すると、1実行2.5ms。
将来作りたい分電盤センサの要件と併せて考えてみる。
商用周波数50Hzをラズピコで計測するなら1波長8回サンプリング。ということは、サンプリング周期はπ/4。
交流電流のリアルな波形を捉えたいと思えば、ベストは電流の正弦波のピーク値をサンプリングできることだが、現状のラズピコだとワースト値はそこからπ/8ずれることになる。
正弦波であれば、そのずれは、cos(π/8)=0.999976 ん?意外と精度よいではないか。というか、この程度なら自宅使用で許容できる。