M5Stackを動かす


R2.3.4 

 考えてみると、全てのGPIOピンがM5Stack本体の横側に出ているわけではないのでした。中には、私の用途では使わないだろうピンもあるので、入れ替えてしまえばいいということで。それに、左右で同じGPIOピンがヘッダピンとソケットのかたちで出ているので、どちらかをつぶしても問題はないですね。全部出してくれればよかったのにね。

 ということで調べてみると、GPIO12とGPIO13が使えそうなことが分かりました。そこで、下のようにGPIO3とGPIO1をつぶすことにしました。ソケットの固定しているピンの半田を取って宙に浮かし、ケーブルを付けてBOTTOMの四隅にある穴の使っていないところから表に出してBUSコネクタの12・13ピンのところに半田付けで完了。

 BOTTOM裏のネジ近くの部分を若干一部削り取って、M5Stack本体の他の部分とスタックしたところ、干渉せずに組み込むことができました。

 すっきりとした姿になり、LCD表示にも動きにも問題がなくなりました(^^)/

 


R2.2.29 

 注意 !
 マイクロビットのプログラムで、BLEサービスがいろいろあるからといって、加速度や温度、ボタンなど全部「最初に」に入れておいたら、いろいろ実験に使えるじゃないか! なあんて思って、入れておくとM5Stackにはつながりません。2つまでは大丈夫でした。3つもいけるかもしれないけれど、全部! なんてことは止めておきましょう。


R2.2.28 

 昨日できた動きが、どういうわけか実現しなかった。どうも、GPIOピンの問題が大きい、と思う。選んだGPIOピンが適切でなかったということね(^^;)

 モーターAの制御に使ったピン21〜23が昨日は機能したが、今日になると駄目だったので、18・19・23に変更した。これらのピンはLDCと共用になっているらしく、動くことは動いたがLCDへの書き込みが実現していない。PWMに使うピンがポイントかな。アナログ出力が使えるピンでないといけないのではないかと思うが、34〜36は入力のみだし、アナログ出力が使えそうな0・2・12・13・15・25・26のうち25・26はDACで、可変抵抗でつないだのでガーガーやかましい。GPIO2以外はM5Stackの側に出ていない(^^;)

 時間があればあれこれ試してみよう。

 TB6612FNG搭載 デュアルモータードライバはピンを6本必要とするが、4本で済むデュアルモータードライバがある。これを使ってみようか。その他こまごました問題もあるが、追究しない(^^;)

 今回は、マイクロビットでコントロールしています。ここで見ることができます。

 マイクロビットのBLEでコントロールするのですが、すぐに忘れそうなのでここに記録しておくことにします。

 BLEコントロールの覚書

◆ マイクロビット

  1. 拡張機能でBluetoothを呼び出しておく。
  2. 「最初だけ」に、必要となるサービスを配置する。今回はボタンサービス。
  3. 右上にある歯車アイコンから、プロジェクトの設定でペアリングしないに設定。
  4. あとは適当な表示をさせる。
◆ M5Stack

  1. #include "BLEDevice.h"
  2. #define MYSERVER_ADDRESS "**:**:**:**:**:**" マイクロビットのアドレス指定
  3. static BLEUUID BtnSvcUUID("E95D9882-251D-470A-A062-FA1922DFA9A8"); ボタンサービスを指定
  4. static BLEUUID AchUUID("E95DDA90-251D-470A-A062-FA1922DFA9A8"); キャラクタリスティックスの指定 Aボタン
  5. static BLEUUID BchUUID("E95DDA91-251D-470A-A062-FA1922DFA9A8"); キャラクタリスティックスの指定 Bボタン
  6. static BLEAddress *pServerAddress;
  7. static BLERemoteCharacteristic* pRemoteCharacteristic1;
  8. static BLERemoteCharacteristic* pRemoteCharacteristic2;
  9. static BLEClient* pClient;
◆ setup で

  1. M5.Power.begin();
  2. BLEDevice::init("");
  3. pServerAddress = new BLEAddress(MYSERVER_ADDRESS);
  4. BLEClient* pClient = BLEDevice::createClient();
  5. pClient->connect(*pServerAddress, BLE_ADDR_TYPE_RANDOM);
  6. if( pClient->isConnected() == false ){
  7. M5.Lcd.println("failed to connect the server...");
  8. delay(2000);
  9. return;
  10. BLERemoteService* pRemoteService = pClient->getService(BtnSvcUUID);
  11. if( pRemoteService == nullptr ){
  12. M5.Lcd.println(F("failed to get service UUID..."));
  13. delay(2000);
  14. pClient->disconnect();
  15. return;
  16. pRemoteCharacteristic1 = pRemoteService->getCharacteristic(AchUUID);
  17. pRemoteCharacteristic2 = pRemoteService->getCharacteristic(BchUUID);
  18. if( pRemoteCharacteristic1 == nullptr ){
  19. M5.Lcd.println(F("failed to get characteristic UUID..."));
  20. pClient->disconnect();
  21. delay(2000);
  22. return;
◆ loop で

  1. if( pRemoteCharacteristic1->canRead()) {
  2. value1 = pRemoteCharacteristic1->readUInt8();
  3. value2 = pRemoteCharacteristic2->readUInt8();
 ここbleach31さんのページで、マイクロビットのサービスUUID、キャラクタリスティックUUIDが分かりました。ありがとうございました。

 kyle さんの「serverあれこれ」での内容をほとんど真似ています。このページでは温度サービスを扱っていますが、私にはボタンサービス、2つあるキャラクタリスティックをどう扱うかが問題でした。試行錯誤して、ようやく使うことができました。ただ、ボタンは2つしかなく、左ボタンで左折、右ボタンで右折、両押しで直進しかできませんでした。

 できれば加速度サービスを使ってマイクロビットの傾きで進行方向を変えられる処理を考えたいのですが.....マイクロビットからくるデータをxyz軸ごとにどうやって取りだすかが未だ課題のままです(^^;)


R2.2.27 

 スイッチサイエンスさんから、TB6612FNG搭載 デュアルモータードライバを新たに購入して、基板を刷新しました。前作は、片方の車輪がどうも動かなかったので。こういう場合、モーター・ドライバ・半田付け・プログラムなどが複雑に絡んでいるので、どこが悪いのかがすぐには分かりません。前作の基板は半田付けがやわだったので、スルーホールのしっかりしたものにし、しっかりと半田を回して固定しました。しかし、後に不完全半田付けが判明!(^^;)

 見栄えが良いためにと、M5Stackの裏側で見てGPIOピン3・1・16にPWMA・AIN1・AIN2を配線し、17・2・5にBIN1・BIN2・PWMBを配線したところ、A側のモーターが反応しなかったのでした。いろいろ調べてみると、というかデータシートを読んでみると、「どれでもいいから使ってしまえ!」はダメなわけで(^^;) そのピンに与えられている仕事をわきまえなくてはいけないのでした(当たり前ね)。プログラムで使っていないI2CとSPIの端子は大丈夫だろうということで、電源を取っている上の方の端子に目星を付けてやってみると、21〜23の端子が良好でした。

 早速、配線をぐるっと回して取り付けて

動かしてみると、ここで見られるように動きました(^^)/

 ボタンで前進・後退・停止です。しかし! 右に湾曲して動きます(^^;) 両方のモーターは同一のものであり、PWM周波数5000Hz、PWM解像度を10として、半分ほどの500の速さを指定 ledcWrite(1,500); したものです。それでも違ってしまうんですね。原因を探しても遠回りになるので、左右で速さ指定を変えてまっすぐ走れるようにするつもり。

 PWM制御の覚書

  1. ピン配置を決める:ドライバのPWM端子をM5のPIN1に接続すると仮定
  2. PWMの設定
    • PWMHz:周波数 5000Hzくらいですね
    • PWMlevel:解像度(8なら最大255,10なら最大1023)
  3. pinModeの設定:今回は全てOUTPUT
  4. ledcSetup(CH1, PWMHz, PWMlevel);でモータのPWMチャンネル等の設定
  5. ledcAttachPin(PIN1, CH1);でモータのPWMピンとチャンネルの設定
  6. ledcWrite(CH1, PWMlevel);で決めたチャンネルを通してモータに指示
 ArduinoIDEにある analogWrite()   PWM制御に関してはあれこれネットで情報を集めながら、最終的にはとても分かり易い、yana_labさんのM5StackのページでのPWM出力を参考にさせていただきました。上の覚書も同様です。多少表現変更しているので、間違えあったら私の責任です。ありがとうございました。


R2.2.21 

 「macsbug」さんのページはどの記事もとても魅力的なのですが、今回はその中のM5 Wheel(moio)を真似てみます(^^;) 私は3Dプリンターを持っていませんが、幸いに以前マイクロビットで作ったDCモーターカーがあるので、これに使った小型モーターとモータードライバボードを再利用してコンパクトカーを捏ねていきます。

 小型モーターや車輪の取り付けに苦労しましたが(小さすぎて手に余る)、どうにか車体ができたところ(相変わらず歪んでいる)。

 可能かどうかわからないけれど、M5StackのBUSとモータードライバをつないだところ。電源はM5Stackから取ることにしました。大丈夫かな? 

 ぐるりと側面の図。

 うまく動いたら側面を覆うパネルを作成して完成とするけれど、macsbugさんのmoioの2倍以上の背丈になりそう…配線も側に出てしまうしね。

 折角だから、マイクロビットでも使えるような構造にしています。


R2.1.28 

 M5Stackを乾電池ケースの上に固定するには、簡単な方法がありました。M5Stackには強力な磁石付いているので、薄い鉄板(白い上下2枚)を両面テープで貼り付けてから載せることです。簡単に外れて便利。しかも、動いたくらいでははがれない(^^)/ 

 ようやくそれなりに動けるようになったので、動画をアップしました。上から見た様子と、前から見た様子

 試運転をしていたら、女房殿が号令をかけてくれたのをヒントに、AquesTalkで喋らせてみました。ついでに、Avatarで顔をだしても見ました。ただ、Avatarが原因か、モーター制御が原因なのか、音(声)が悪化してしまいました。最後の「やれやれ、疲れたよ」と言うはずが、雑音でしかない(^^;)

 歩くときの姿勢ですが、あちこちにアップされている2本足歩行ロボットを見ると、下のように体を傾けて、宙に浮いた脚を前方に出すという方法が効果的かなと思って採用しました。

 この方法は、全体の重心の位置や傾ける角度、モーター間の間隔、足裏の面積や間隔などを試行錯誤で試してみた結果に得たものです。でもまあ、偶然にうまくいったというのが本当の話。

 もっとも、スタート前のきちんととした直立姿勢を作るところから始まります。サーボモーターは個体差があるし、ロボットを製作して組みつけたときにも寸法誤差がつきものです。製品でないので。そこで、4つのサーボを90度指定しても姿勢が崩れているので調整が必要です。その調整値を補正値としてプログラムの中で使うことになります。

 最初の1歩の脚回転になる上のサーボは静止位置から脚を前に振り出すことになるので、2歩目以降の角度と比べ半分になります。ここがポイント。止まるときにはどんな姿勢になっていてもOKです。最初の静止姿勢の4つのサーボの扱いを関数として組み込んでおけば、それを実行すればいいだけです。

 一番悩んだのは歩き方。しかし、やってみれば当然のことでした。両方のつま先を揃えることにしているので、ビデオのように1〜8で歩行は1回りします。それよりも問題になりそうだったのは、一つ一つのサーボに角度指定するときの方法。90度を基準に0度の方へ動く指定と180度の方向に指定するやり方です。(私の場合は、足首は25度、脚回しは15度にしてみました)右脚と左脚で逆方向に指定するかと思ったら、組みつけたときに両脚のサーボ群は逆に対照的に取り付けてあるので、同じ方向への指定で問題がないのでした。これはラッキー!

 まず静止状態。起立です。説明が面倒なので、どれも90度の位置に指定してきちっと正立しているとします。

 @を65度に指定。重心がうまく右足に乗ってくれればロボットからすると右に傾きます。次にAを75度指定。ロボットからすると右に上体が回旋します。このまま元の正立状態に戻ると内股になってしまうので、Cを75度指定して、両足を並行にします。そして、@を元の90度に指定すると、左足が一歩先に出た状態で成立します。

 次に、Bを115度に指定。ロボットは左に傾きます。次にCは75度になっているので、それから105度を指定します。ロボットからすると左に上体が大きく(30度)回旋します。Aも75度になっているので、105度を指定して指定して大きく旋回し、両足を並行にします。そして、Bを元の90度に指定すると、右足が一歩先に出た状態で成立します。あとはこれの繰り返しです。

 ということで、これは子供たちにトライさせるのに最高のアイテムと言えるのではないかなと思いました。ついでに、私のような高齢者が頭の体操として取り組むのも認知症予防となるかもしれません。


R2.1.26 

 ようやく電池ケースをゲットできたので本体工作を完成しました。県立図書館に予約した書籍『「M5Stack」ではじめる電子工作』が借りられるようになったので(1カ月以上待ちました...人気ですね(^^;)出かけたら、二足歩行ロボットの本があったので、これも借りてきました。歩きのアルゴリズムが理解しやすかったです。

 単4電池3本でスイッチ付きのケースだったので使い勝手が良かったです。本体にサンドイッチするようにしました。この上にM5Stack本体を輪ゴムで止めました。

 歩いた様子は、ここで見られます。滑らかな動きにしてはいないので、スリップしてるな〜 (^^;) プログラムはまだまだこれからですね。


R2.1.22 

 今のところは、M5Stackのボタン押しで動くのだけれど、やっぱり無線で動かしたい。

 狙いどころはWiFi、あるいはブルートース。WiFiはつながりました。でもアクセスポイントとなるルーターが自宅以外では利用が難しい。そうなると、ブルートース。

 マイクロビットにはブルートースを簡単に利用できるので、コントローラをマイクロビットにする。kyle さんの記事がわかりやすく、スケッチもあったので利用させていただき、つながりました。マイクロビットのアドレスは、nRF Connect for Mobileというアプリを使って調べました。マイクロビットで遊んでいたときにインストールしていたものです。

 マイクロビットのボタンサービスで、押せばM5Stackに表示できるので、これでコントロールできそうです。ただ、できれば加速度サービスを使って、前後左右の傾きでコントロールできればと考えています。しかし、ここに私にとって大きな壁が出現! 「XYZの順に各sint16、リトルエンディアンで格納 1000で割ると単位Gになる」「1000で割ると単位Gになる」になるのは知っています。どこかで、読んだことがあるから。その前の語が意味不明! どう処理すればXYZに分割できるのかが 分からない。これから勉強ですね(^^;)


R2.1.22 まずはサーボで2足歩行を計画

 マイクロビットで2足歩行を目指したけれど、ぎくしゃくしてうまくは動きませんでした。そこで、PCA9685を使った16チャンネルのサーボモータードライバボードを購入しました。けれど、マイクロビットでは使わずにそのままになっていました。

 M5Stackでも2足歩行のロボットを見たので、やってみようと計画。まずは本体作り。Google HomerさんGyutanさんの記事を参考にして作ってみました。結束バンドには目から鱗ですね! さらに、片脚で2つのサーボを直付けとは! みなさん頭が柔らかいなあ。さらに、Gyutanさんはマイクロビットで実現しています。マイクロビットの拡張機能にPCA9685もあるので簡単そう(???)。

 で、本体はほぼ完成。いまのところM5Stack本体から3VでPCA9685を動かし、5Vでサーボを動かしたらどうにか動きました。サーボは外部電源にしなければならないと思うので、単4電池の電池ボックスを購入予定なのだけれど、近場には売っていない! (^^;) で、今のところ休止状態。もっとも、4つのサーボをどう動かして2足歩行させるかが難しいところなのです。これを考え中。

 結束バンドを百均で買ってくる前に、不要になった反射望遠鏡の斜鏡金具のφ2mmスポークを使って左足だけ作ってみた。結構良かったけど3本だけだったので右足分が作れなかった。

 これでうまくいったら、マイクロビットでもやってみるかな。