Raspberry Pi Pico W を Arduino IDE で味見2 ー姿勢制御モジュール製作ー
前回は Raspberry Pi Pico W をArduino IDEで味見し、WiFi通信やI2C通信を楽しみました。
ここでは更に深掘りし姿勢制御モジュールも製作しましたので報告いたします。
目次
ブラシレスモータ回転
以下のモータをRaspberry Pi Pico W を用いてArduino IDEコーディングで回してみます。
このモータはPWMのデューティで回転速度を指定し、回転方向やブレーキをロジック信号で指定します。それぞれ1周100パルスのA相, B相エンコーダ出力も兼ね備えています。
まずはdigitalWriteで雑にPWM出力してみました。
Raspberry Pi Pico W を Arduino IDE で味見
ブラシレスモータ回転テスト
digitalWriteで雑にPWM
周波数不明でなんか音なってる。。しっかりとしたPWM出力の勉強が必要 pic.twitter.com/ShffcxBT4v
— HomeMadeGarbage (@H0meMadeGarbage) April 2, 2023
周波数不明でなんか音なってる。。
以下のドキュメントを参考にdigitalWriteの周波数を20kHz [analogWriteFreq(20000)]としてデューティ比を10bit分解能 [analogWriteRange(1024)]で指定できるようにしました。
勉強のおかげでdigitalWriteの周波数(20kHz)と10bit分解能でパルス幅を指定してブラシレスモータを回せるエレガントな人間になれた。https://t.co/CPkr1QaYmc pic.twitter.com/l5jmsmFcWt
— HomeMadeGarbage (@H0meMadeGarbage) April 2, 2023
異音もなくなり回転方向転換もスムーズに行えています。
Arduino IDEにおけるRaspberry Pi Pico W でのPWM出力は digitalWrite で問題なさそうです。
パルスカウンタ
先ほどのモータのエンコーダ出力からモータの回転速度の算出します。
以下の記事でPIOでパルス幅を測定する方法が紹介されていました。
さらにパルス幅から周波数を導出するArduino IDE用ライブラリも公開されておりましたので、ありがたく使用させていただきました。
上記ライブラリを使用してモータエンコーダのA相 (1周 100パルス)の周波数を測定し回転速度を計ってみました。
PIOで周波数をはかるライブラリを使用させていただき
エンコーダのパルスで回転速度をエレガントに導出https://t.co/WwyoVbGntL pic.twitter.com/h3CQGKRL9c— HomeMadeGarbage (@H0meMadeGarbage) April 2, 2023
非常にええ感じにモータ回転速度が計れております。
B相も用いて回転方向検出や逓倍しての検出精度向上もおいおいやっていきたいですが、現状はこれで十分です。
姿勢制御モジュール製作
モータを制御して回転速度をはかれるようになったのでRaspberry Pi Pico W で1軸の姿勢制御モジュールを製作してみました。
Raspberry Pi Pico W で姿勢制御
作りがひどいけど お試しマルチコア core0でセンシング&モータ制御
core1でWiFi APモードでパラメータ調整どっかのタイミングでPico W用基板作りたいな
どっかから小型モジュール出るの待つかな? pic.twitter.com/n17fN6dtyw— HomeMadeGarbage (@H0meMadeGarbage) April 2, 2023
つくりはひどいですが。。無事に倒立動作が実現されました。
デュアルコアを用いて
core0で姿勢センシング&モータ制御
core1でWiFi APモードでパラメータ調整
を実施しています。
IMUにはMPU6050を使用しています。
OLED表示
I2C制御のOLEDディスプレイの表示がしばらくうまくいきませんでした。
単体では問題なく動いたのですが(Adafruit_SSD1306ライブラリ使用)、デュアルコアでMPU6050と同時に使用すると処理が遅くなってしまいました。
IMUとOLEDをそれぞれI2C0とI2C1で通信してなおかつデュアルコアで別けて制御したいのだけど
OLEDつなげると劇的におそくなる。。。これは週末の課題かな
しかしAruduino IDEでのpicoのデュアルコアの記述は奇抜だ pic.twitter.com/0rQlwKdBCy— HomeMadeGarbage (@H0meMadeGarbage) March 31, 2023
この時の構成は以下の通りです。
- core0:I2C0 (GP0, GP1) でMPU6050
- core1 :I2C1 (GP2, GP3) でOLEDディスプレイ
これを以下のように変更することで改善しました。
- core0:I2C0 (GP0, GP1) でMPU6050
- core1 :I2C1 (GP10, GP11) でOLEDディスプレイ
I2C1_SDA:GP2
I2C1_SCL:GP3
を
I2C1_SDA:GP10
I2C1_SCL:GP11
に変更で改善した。
(I2C0はGP0, GP1)GP0~GP7はSPI0群だから分けないと内部で悪さするのかな?
良く分からないけどとりあえず動いた pic.twitter.com/RWIPmQGvPA— HomeMadeGarbage (@H0meMadeGarbage) April 3, 2023
改善した理由はよくわかりません。。
変数フラッシュ保存
WiFi通信で指定したパラメータを電源オフ後も保持したく、保存方法を調べました。
以下の通りEEPROMライブラリでフラッシュ保存可能でした。
Raspberry Pi Pico W にはEEPROMは搭載されていませんがフラッシュメモリの空いているところに保存してくれます。
アドレス指定して1バイトずつの保存になるためfloat値やint値の保存がめんどくさいなぁと。。
そこで今流行りのChatGPTに聞いてみました。
プログラミング勉強しないで良かった pic.twitter.com/AlIozpZB7C
— HomeMadeGarbage (@H0meMadeGarbage) April 3, 2023
めっちゃありがたい。プログラミング苦手なので今後はChatGPTにたくさんお世話になりそうですww
変数書き込み
float変数 Kpをフラッシュ保存
1 2 3 4 5 6 |
byte byteKp[sizeof(float)]; memcpy(byteKp, &Kp, sizeof(float)); for (int i = 0; i < sizeof(float); i++) { EEPROM.write(i, byteKp[i]); } EEPROM.commit(); |
変数読み出し
フラッシュ保存されたfloat変数 Kpを読み出し
1 2 3 4 5 |
byte byteKp[sizeof(float)]; for (int i = 0; i < sizeof(float); i++) { byteKp[i] = EEPROM.read(i); } memcpy(&Kp, byteKp, sizeof(float)); |
姿勢制御モジュール再製作
OLED表示と変数保存ができるようになりました。
Raspberry Pi Pico W と私の距離が大変に縮まった
マルチコアでモータ制御とWiFi, ディスプレイ表示
WiFiでパラメータ調整しフラッシュ保存 pic.twitter.com/Xr8GVQ208v— HomeMadeGarbage (@H0meMadeGarbage) April 3, 2023
つくりがあまりに雑だったのでユニバーサル基板でESP32用ボードにマッチするように配線してきれいにRaspberry Pi Pico W が実装されるようにしました。
おわりに
ここでは Raspberry Pi Pico W の Arduino IDEでの開発を深掘りして、姿勢制御モジュールを実現しました。
これで私と Raspberry Pi Pico W との距離はずいぶんと近くなったように思います。
ほぼESP32と同様に取り扱えるようになったといってよいでしょう。
今後は以下の課題を念頭に置きつつ開発に取り組んでいきたいと思います。
- PIOでエンコーダA相, B相検知して回転方向判断
- エンコーダA相, B相のパルスを逓倍して高分解能化