M5StackToioとわたくし
https://gyazo.com/0a7435d23d027fc40503634244232371
はじめに
この時使っているM5StackToioと言うライブラリに関してご紹介したいと思います。
M5StackToioとは?
kenichi884版では、マットに関する情報が取得できたり、マットの特定位置の移動が可能になっています。
Bluetoothライブラリに依存しているだけなので、その他のESP32ボードでも動作します。手元のESP32-WROOM-32で動作を確認しました。
githubには詳細な説明が用意されているので、使い方に困ることはないと思います。 以下に、簡単な説明を付けておきます。
以下のバージョンはfutomi版由来のもので、M5Stack Core(Basic)とGREYでのみ動きます。
_testが付いているいるものは、kenichi884版の新機能のテストも含まれています。M5Unifiedを使っているため、多くのM5Stackファミリーで動作します。 ちょっとしたデモコード(simple_example.ino)を書いてみました。
このデモは、以下のように動きます。
初期化(setup())
toioと接続する。
接続時にtoioの効果音を鳴らす。
繰り返し(loop())
toioの位置と向きを表示
バッテリーの状態を表示
以下を交互に実行
LEDの明滅
指定位置への移動
code:simple_example.ino
static bool mode = false; // デモの状態
Toio toio; // Toio オブジェクト
ToioCore* toiocore = nullptr; // ToioCore オブジェクトポインタ
void setup() {
Serial.begin(115200);
std::vector<ToioCore*> toiocore_list = toio.scan(3); // 3 秒間 Toio Core Cube をスキャン
// 見つからなければ終了
size_t n = toiocore_list.size();
if (n == 0) {
exit(-1);
}
toiocore = toiocore_list.at(0); // 最初に見つかった Toio Core Cube の ToioCore オブジェクトを取得
toiocore->connect(); // toioに接続する
// toioの効果音を鳴らす
for (int i = 0; i < 10; i++) {
toiocore->playSoundEffect(i);
delay(500);
}
}
void loop() {
toio.loop(); // 必要
// toioのマット上での位置と角度を表示
ToioCoreIDData data = toiocore->getIDReaderData();
if (data.type == ToioCoreIDTypePosition) {
Serial.printf("posX: %u posY: %u angle: %u\n",
data.position.cubePosX, data.position.cubePosY, data.position.cubeAngleDegree);
} else if (data.type == ToioCoreIDTypeStandard) {
Serial.printf("Standard ID: %u\n", data.standard.standardID);
}
// Batteryの状態を表示
uint8_t batt_level = toiocore->getBatteryLevel();
Serial.println(String(batt_level) + "%");
// LEDの点滅と目標位置への移動
if (mode) {
toiocore->turnOffLed(); // 点灯中なら消灯
toiocore->controlMotorWithTarget(1, 5, 0, 50, 0, 200, 200, 0, 0); // 位置(x,y)=(200,200), 角度0度に速度50で移動
} else {
toiocore->turnOnLed(255, 255, 255); // 消灯中なら白で点灯
toiocore->controlMotorWithTarget(1, 5, 0, 50, 0, 300, 300, 180, 0); // 位置(x,y)=(300,300), 角度180度に速度50で移動
}
delay(2000);
mode = !mode;
}
シリアルの表示は以下のようになります。
code:serial.txt
15:55:16.816 -> posX: 195 posY: 199 angle: 359
15:55:16.915 -> 100%
15:55:19.125 -> posX: 304 posY: 300 angle: 179
15:55:19.220 -> 100%
M5StackToio joystick_drive.inoの対応Joystickの追加
https://www.youtube.com/watch?v=-lgxvZjHF7A
むとうの手元には、以下のJoystickがありました。
折角あるので、これらを使えるように改造してみました。
おまけ:AtomS3の加速度センサーでtoioを動かす(2024/12/08追記)
加速度センサーでtoioを動かせると面白そうだったので、作ってみました。手元ではAtomS3で試しましたが、M5Unifiedの機能を使っているので、他の加速度センサーが付いた機種でも使えると思います。
動作には、専用マットが必要です。手元ではtoio™開発用A3プレイマットで試しました。他の専用マットの場合、ひょっとするとMAT_CENTER_*やax,ayへ掛ける値の微調整が必要かもしれません。 code:toio_accel_control.ino
// toio コア キューブ(単体)付属の簡易プレイマット
const int MAT_CENTER_X = 98 + (402 - 98) / 2;
const int MAT_CENTER_Y = 142 + (358 - 142) / 2;
static bool mode = false; // デモの状態
Toio toio; // Toio オブジェクト
ToioCore* toiocore = nullptr; // ToioCore オブジェクトポインタ
void setup() {
Serial.begin(115200);
std::vector<ToioCore*> toiocore_list = toio.scan(3); // 3 秒間 Toio Core Cube をスキャン
// 見つからなければ終了
size_t n = toiocore_list.size();
if (n == 0) {
exit(-1);
}
toiocore = toiocore_list.at(0); // 最初に見つかった Toio Core Cube の ToioCore オブジェクトを取得
toiocore->connect(); // toioに接続する
// for M5Stack
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.init();
}
void loop() {
float ax, ay, az;
M5.update();
toio.loop();
// toioのマット上での位置と角度を表示
ToioCoreIDData data = toiocore->getIDReaderData();
if (data.type == ToioCoreIDTypePosition) {
Serial.printf("posX: %u posY: %u angle: %u\n",
data.position.cubePosX, data.position.cubePosY, data.position.cubeAngleDegree);
} else if (data.type == ToioCoreIDTypeStandard) {
Serial.printf("Standard ID: %u\n", data.standard.standardID);
}
// Batteryの状態を表示
uint8_t batt_level = toiocore->getBatteryLevel();
Serial.println(String(batt_level) + "%");
// 加速度の取得
M5.Imu.getAccel(&ax, &ay, &az); // get accel
Serial.printf("ax: %f ay: %f az: %f\n", ax, ay, az);
// toioの移動
toiocore->controlMotorWithTarget(0, 5, 0, 50, 0, MAT_CENTER_X + 100 * -ax, MAT_CENTER_Y + 100 * ay, 0);
// LEDの点滅
if (mode) {
toiocore->turnOffLed(); // 点灯中なら消灯
} else {
toiocore->turnOnLed(255, 255, 255); // 消灯中なら白で点灯
}
mode = !mode;
}
おまけ:専用マットなしで、AtomS3の加速度センサーでtoioを動かす(2024/12/09追記)
専用マットを使った加速度センサーでのtoioの操縦に関しては既にご紹介しました。
「良く考えたら、専用マット無くてもいけるんじゃね?」と思ったので、実際に作ってみました。
code:toio_accel_control_nomat.ino
static bool mode = false; // デモの状態
Toio toio; // Toio オブジェクト
ToioCore* toiocore = nullptr; // ToioCore オブジェクトポインタ
void setup() {
Serial.begin(115200);
std::vector<ToioCore*> toiocore_list = toio.scan(3); // 3 秒間 Toio Core Cube をスキャン
// 見つからなければ終了
size_t n = toiocore_list.size();
if (n == 0) {
exit(-1);
}
toiocore = toiocore_list.at(0); // 最初に見つかった Toio Core Cube の ToioCore オブジェクトを取得
toiocore->connect(); // toioに接続する
// for M5Stack
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.init();
}
void loop() {
float ax, ay, az, speed;
uint8_t lspeed, rspeed;
M5.update();
toio.loop();
// toioのマット上での位置と角度を表示
ToioCoreIDData data = toiocore->getIDReaderData();
if (data.type == ToioCoreIDTypePosition) {
Serial.printf("posX: %u posY: %u angle: %u\n",
data.position.cubePosX, data.position.cubePosY, data.position.cubeAngleDegree);
} else if (data.type == ToioCoreIDTypeStandard) {
Serial.printf("Standard ID: %u\n", data.standard.standardID);
}
// Batteryの状態を表示
uint8_t batt_level = toiocore->getBatteryLevel();
Serial.println(String(batt_level) + "%");
// 加速度の取得
M5.Imu.getAccel(&ax, &ay, &az); // get accel
Serial.printf("ax: %f ay: %f az: %f\n", ax, ay, az);
speed = -100.0 * ay;
if (speed < 0.0) {
speed = 0.0;
lspeed = rspeed = 0;
} else {
lspeed = (uint8_t)map(speed * -ax, -200, 200, 0, 115);
rspeed = (uint8_t)map(speed * ax, -200, 200, 0, 115);
}
Serial.printf("speed: %f lspeed: %d rspeed: %d\n", speed, lspeed, rspeed);
// toioの移動
toiocore->controlMotor(true, lspeed, true, rspeed, 2000);
// LEDの点滅
if (mode) {
toiocore->turnOffLed(); // 点灯中なら消灯
} else {
toiocore->turnOnLed(255, 255, 255); // 消灯中なら白で点灯
}
mode = !mode;
}
余談としてのおまけ:UIFlow1.0で動かす
(2024/12/15追記)
M5StackToioを使うわけではありませんが、UIFlow 1.0のtoio拡張を使って同じようなことをすることができます。 toio拡張は、Atomシリーズのみで利用可能です。
具体的なことは、説明しませんが、以下のコードを参考にしてみてください。
https://gyazo.com/91b20c1a64aa37ee66617aebf21af851
おわりに
M5StackToioを使うと、M5Stackから簡単にtoioを利用することができます。
Joystickでtoioを動かすプログラムはラジコンみたいで楽しいです。
もちろん、専用マットを使った動きを行うための関数も用意されているため、色々な作品に利用できると思います。
みなさんも使ってみませんか?
About 610t
https://gyazo.com/61121416c6cd984ca2b902f6af12288b
むとうたけし(武藤武士(wǔ téng wǔ shì)) aka 610t
奈良在住
専業主婦
54歳(1970/06/19生まれ)