ルンバのシリアルインタフェースにM5 Atom liteを接続してハックします
Atom liteを使用しますがUARTが使えるマイコンなら何でも大丈夫だと思います
色々な事ができるのですがまずルンバをラジコン化してみました
ルンバをPS3コントローラでラジコン化できました\(^o^)/
— もけ@ムギ㌠ (@coppercele) March 6, 2021
シリアルポートとGPIOを直結してUARTでコマンド送るだけで簡単に制御できました(゚∀゚)
これQiitaの記事にまとめた方がいいですかね?🤔#M5Stack #M5ATOM pic.twitter.com/3CVb3t1xRt
##使用するデバイス##
ATOM Lite - スイッチサイエンス
https://www.switch-science.com/catalog/6262/
M5Stackシリーズの中で最もコンパクトな開発モジュールで、サイズはわずか24 x 24 mmです。M5StickCに比べGPIOピンを多く持ち、小型の組み込みデバイス開発に適しています。メインコントローラとして、ESP32-PICO-D4チップを搭載しているので、Wi-FiとBluetooth、4 MBの内蔵SPIフラッシュメモリを利用できます。(スイッチサイエンスさんから引用)
M5シリーズの中で一番小さくて手軽なAtom liteを使用しました
Atom liteで出来るなら他のマイコンでも使えるだろうと思ったので
##ルンバとマイコンを接続する##
ルンバにはOpen Interface (OI)という規格があり仕様が公開されています
これは自分が所有してる600番系ルンバの仕様書です。バリエーションによっていくつかPDFがあるようです
iRobot Roomba 600 Open Interface Spec
https://www.irobotweb.com/~/media/MainSite/PDFs/About/STEM/Create/iRobot_Roomba_600_Open_Interface_Spec.pdf
下調べでこちらのサイトなどを参考にさせていただきました
ルンバの制御用USBシリアルケーブルを綺麗に作りたいときのメモ - cvl-robot's diary
https://cvl-robot.hateblo.jp/entry/2017/08/28/173943
ルンバにスピッツを演奏させてみた | curious4dev
http://curious4dev.mydns.jp/post-1463/
まずルンバの上ブタを外すとmini DIN7ピンのシリアルポートが出てきます
フタは爪で止まっているので壊さない程度に力づくで外しましょう
仕様書を見ると7がGND,4がTXD,3がRXDだと分かります
ジャンパケーブルを使ってマイコンと接続します
自分はAtom mateという基板を介して接続しましたがGPIOが上に向いてるマイコンだったら直接つないでもいいと思います
ATOM Mate - スイッチサイエンス
https://www.switch-science.com/catalog/6532/
注意:ルンバのRX,TXは5Vなので本来3.3VのAtom liteを接続するときはレベルシフタ、ロジックレベルコンバータを使いましょう!
ESP32は5Vトレラントじゃないはずなのになぜか壊れないのですがメーカー非推奨なので自己責任で
NTB0104 レベルシフタ ピッチ変換済みモジュール - スイッチサイエンス
https://www.switch-science.com/catalog/2351/
電源はルンバのVpwrの15vを降圧させるのが王道かと思いますが
USBかTailbat(Atom liteの下につながってる細長い奴)から供給しています
##ルンバと通信する##
仕様書に通信の仕様が載っているので設定を合わせればUARTで通信できます
基本的にはOPcodeに続いて必要ならDataByteを送信するだけという簡単なプロトコルになっています
ルンバを自由に操作するにはsefe modeに入れないといけないので
Start(128)の後にSafe(131)コマンドを送ります
void setup() {
M5.begin();
// UART通信設定
Serial1.begin(115200, SERIAL_8N1, 25, 21);
// start
Serial1.write(128);
delay(50);
// safe mode
Serial1.write(131);
delay(50);
Serial.println("inited");
}
Safe modeに入ったらあとはコマンドを送れば何でもできるのですが、
今回はラジコンとして操作して遊んでみるので吸引(144)と移動(146)のコマンドを使用します
Opcodeに続けてDataBytesを送ることで実行できます
参考にしたサイトではDataBytesの間にdelay入れてたけど自分の環境ではなぜか動作がおかしくなったので入れてませんが
上手く動かないようならdelayを入れてもいいかもしれません
void move(int16_t left, int16_t right) {
// 移動
Serial1.write(146);
// delay(20);
Serial1.write((right & 0xFF00) >> 8);
// delay(20);
Serial1.write(right & 0xFF);
// delay(20);
Serial1.write((left & 0xFF00) >> 8);
// delay(20);
Serial1.write(left & 0xFF);
}
void vacuum(bool on) {
Serial1.write(144);
// delay(20);
Serial1.write(on ? 100 : 0);
// delay(20);
Serial1.write(on ? 100 : 0);
// delay(20);
Serial1.write(on ? 100 : 0);
}
##コントローラで操作する##
コントローラとしての送信機についてはスマホのバーチャルパッドやジャイロで操作したりといろいろあると思いますが
いろいろ試した結果物理コントローラが最適だと思ってます(異論は認める)
小学生に操作させてみると動かす対象に目が行ってしまうので手元がおろそかになって思い通りに動かせないんですよね
皆さんはPS3コントローラにこだわる必要はないと思いますのでBlynkとかM5StickCのジャイロとか好きな方法で動かしてください
そして物理コントローラにもBLE HIDとかBT classicいろいろあるのですが入手性と安定性を重視してPS3コントローラを使用します
ライブラリマネージャからインストールできるので手軽です
詳しくはこちらの記事を参照してください
ESP32(M5StickC)をPS3コントローラで操作する - Qiita
https://qiita.com/coppercele/items/0724b0b951868044223b
十字ボタンで移動、スタートボタンで吸引開始、セレクトボタンで吸引停止という動作にするとこのような実装になります
#include <Arduino.h>
#include <M5Atom.h>
#include <Ps3Controller.h>
void move(int16_t left, int16_t right) {
Serial1.write(146);
// delay(50);
Serial1.write((right & 0xFF00) >> 8);
// delay(50);
Serial1.write(right & 0xFF);
// delay(50);
Serial1.write((left & 0xFF00) >> 8);
// delay(50);
Serial1.write(left & 0xFF);
}
void vacuum(bool on) {
Serial1.write(144);
// delay(50);
Serial1.write(on ? 100 : 0);
// delay(50);
Serial1.write(on ? 100 : 0);
// delay(50);
Serial1.write(on ? 100 : 0);
}
bool up;
bool down;
bool right;
bool left;
void notify() {
if (Ps3.event.button_up.select) {
Serial.println("Released the select button");
vacuum(false);
}
if (Ps3.event.button_up.start) {
Serial.println("Released the start button");
vacuum(true);
}
if (Ps3.event.button_down.up) {
Serial.println("Started pressing the up button");
up = true;
}
if (Ps3.event.button_up.up) {
Serial.println("Released the up button");
up = false;
}
if (Ps3.event.button_down.right) {
Serial.println("Started pressing the right button");
right = true;
}
if (Ps3.event.button_up.right) {
Serial.println("Released the right button");
right = false;
}
if (Ps3.event.button_down.down) {
Serial.println("Started pressing the down button");
down = true;
}
if (Ps3.event.button_up.down) {
Serial.println("Released the down button");
down = false;
}
if (Ps3.event.button_down.left) {
Serial.println("Started pressing the left button");
left = true;
}
if (Ps3.event.button_up.left) {
Serial.println("Released the left button");
left = false;
}
// ナナメ
if (up && right) {
move(100, 50);
return;
}
if (up && left) {
move(50, 100);
return;
}
if (down && right) {
move(-100, -50);
return;
}
if (down && left) {
move(-50, -100);
return;
}
if (up) {
move(100, 100);
return;
}
if (down) {
move(-100, -100);
return;
}
if (right) {
move(50, -50);
return;
}
if (left) {
move(-50, 50);
return;
}
// 何も押されてなければ停止
move(0, 0);
}
void onConnect() { Serial.println("Connected!."); }
void onDisconnect() { Serial.println("Disconnected!."); }
void setup() {
// Serial.begin(115200);
M5.begin();
Serial1.begin(115200, SERIAL_8N1, 25, 21);
// start
Serial1.write(128);
delay(50);
// safe mode
Serial1.write(131);
delay(50);
Serial.println("inited");
// PS3コントローラ設定
// notifyで動作
Ps3.attach(notify);
Ps3.attachOnConnect(onConnect);
Ps3.attachOnDisconnect(onDisconnect);
// 接続するESP32のBLEアドレスに変更する
Ps3.begin("00:01:02:03:04:05:06");
}
void loop() {
delay(1);
}
ルンバをPS3コントローラでラジコン化できました\(^o^)/
— もけ@ムギ㌠ (@coppercele) March 6, 2021
シリアルポートとGPIOを直結してUARTでコマンド送るだけで簡単に制御できました(゚∀゚)
これQiitaの記事にまとめた方がいいですかね?🤔#M5Stack #M5ATOM pic.twitter.com/3CVb3t1xRt
おそらく思ってるより簡単にルンバをハックできると思います
音楽を演奏したりAlexaで清掃モードに入れたりなんてこともできるのでいろいろ楽しみましょう!(゚∀゚)
M5StickC赤外線リモコンをAlexaに対応させよう - Qiita
https://qiita.com/coppercele/items/8c962dabadf33d52709b