
M5Stack で iPhone GarageBandの音を鳴らす ② 3軸加速度センサの接続・発音
M5Stack から無線で iPhone GarageBandの音を鳴らす実験をしているのですが、
前回はM5StackのボタンAを押すと音が出る所までできました。
目次
Grove Beginner Kit for Arduino
今回はセンサを繋げて音を出してみたいと思い、、、、
先日お父ちゃんに貰った、
Grove Beginner Kit for Arduino
を使って行きたいと思います。
お父ちゃんにもろた
繋げてみよ!#電子工作 pic.twitter.com/lIPyQlzpyh— ムプ- (@j6XX2IChZG99891) July 6, 2025
紹介記事はこちら⬇️
“3軸加速度センサ”が入っているようなので、
今回はそれを接続してみたいと思います!
公式Wiki:Grove Beginner Kit for Arduino | Seeed Studio Wiki
パーツを接続
まずは3軸加速度センサを探す…
公式図 Grove – 3-Axis Accelerator と記載がある
同じような形のパーツを探す
裏側を確認すると “Grove – 3-Axis Digital Accelerator” と記載があった。
M5Stack と つなげる。
この黄色、白、赤、黒の線は、GROVEケーブルと呼ぶようだ。
パーツを嵌める時は向きがあるので特に注意することはなかった。
ライブラリのインストール
3軸加速度センサについての公式Wiki:
Grove – 3-Axis Digital Accelerometer (LIS3DHTR) | Seeed Studio Wiki
“LIS3DHTR” というチップが搭載されているとのこと。
Arduino IDE の Library Manager で “LIS3DHTR”を検索して
“Grove-3-Axis-Digital-Accelerometer-2g-to-16g-LIS3DHTR”
をインストール

最初、ライブラリを間違えた
公式ページをちゃんと確認せずChatGPTに、
「Grove Beginner Kit for Arduino の3軸加速度センサをM5Stackに接続したい」と相談していたら、
ChatGPTが違うセンサ(Adafruit Sensor)で話を進めてしまい、
「センサが認識されない〜!」としばらくハマってしまいました。
反省 💦
I2Cスキャナコードで調べる(スキップ可)
ライブラリを間違えていたため認識されず、
I2Cスキャナコードでデバイスを探しました。
デバイスアドレス(0x19)は公式サイトに記載があるので、
この作業は本来不要だと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <M5Unified.h> #include <Wire.h> void setup() { M5.begin(); Wire.begin(21, 22); // M5StackのPORT A Serial.begin(115200); Serial.println("I2C scanner. Scanning..."); M5.Lcd.setTextSize(2); M5.Lcd.setCursor(0, 0); M5.Lcd.println("Booting..."); Serial.println("I2C scanner. Scanning..."); byte error, address; int devices = 0; for (address = 1; address < 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); Serial.println(address, HEX); devices++; } } if (devices == 0) Serial.println("No I2C devices found\n"); else Serial.println("Scan complete."); } void loop() {} |
上記コードを実行しても
M5Stackに何も表示されない…と困っていたら
お父ちゃんが助けてくれました。
これは「シリアルモニタ」で確認するのだと…!
・M5.Lcd.println:M5Stackの画面に出力
・Serial.println:シリアルモニタへの出力
シリアルモニタ確認方法
Arduino IDE上部の虫眼鏡アイコン(「シリアルモニタ」)をクリック

すると、Arduino IDE下部、
Output の別タブにSerial Monitor が表示されました。

しかし何も表示されない、、、、、、、
と困っていたら、、またもやお父ちゃんの助け舟。
M5Stackをリセットする(M5Stackの側面にある赤いボタンを1回押す)と表示されました!
こういうところが、全く何も知らない初心者にとっては時間のかかるハマりポイントになるんですよね💦
「なぜか表示されない…!接続に問題があるのか??」などと、何時間も費やしてしまう😭
そして文字は表示されたのだが文字化けしている…..

これは右上の 9600 baud を 115200 baud にする必要がありました。
この baud rate(ボーレート) はプログラムに記載のある値と揃える必要があるとのこと。
1 |
Serial.begin(115200); |
プログラム側に合わせると無事表示されました!

デバイスが2個検出されている…から、
3軸加速度センサ を外してリセットボタンを押す。
すると 0x75 だけになったので、
3軸加速度センサ は 0x19 と判明!
お父ちゃんに助けられました…🙏
公式サイトに記載がある!
そして、判明した0x19は、公式Wikiにちゃんと記載があった〜!!

ChatGPT頼りの前にまずはちゃんと調べないと💦
しかし今回の作業で理解が深まり良い勉強になりました📖
加速度センサの表示
ここまできたらあとはもうプログラムを書いてもらうだけ…
ChatGPTに書いてもらい….
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <M5Unified.h> #include "LIS3DHTR.h" #include <Wire.h> LIS3DHTR<TwoWire> LIS; void setup() { M5.begin(); Wire.begin(21, 22); Serial.begin(115200); M5.Lcd.setTextSize(3); // begin時にアドレスを指定 LIS.begin(Wire, 0x19); if (!LIS.available()) { Serial.println("LIS3DHTR not found!"); M5.Lcd.setCursor(0, 0); M5.Lcd.println("LIS3DHTR not found!"); while (1); } LIS.openTemp(); // 温度センサON(必要なら) delay(100); LIS.setFullScaleRange(LIS3DHTR_RANGE_2G); LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ); M5.Lcd.setCursor(0, 0); M5.Lcd.println("LIS3DHTR OK!"); } void loop() { float x = LIS.getAccelerationX(); float y = LIS.getAccelerationY(); float z = LIS.getAccelerationZ(); Serial.print("X: "); Serial.print(x); Serial.print(" Y: "); Serial.print(y); Serial.print(" Z: "); Serial.println(z); M5.Lcd.setCursor(0, 30); M5.Lcd.printf("X: %.2f\nY: %.2f\nZ: %.2f\n", x, y, z); delay(500); } |
表示されたー!!動いてるーー🙌
M5Stackに3軸加速度センサを接続🙌#電子工作 pic.twitter.com/nLFc77l3E9
— ムプ- (@j6XX2IChZG99891) July 8, 2025
加速度センサの傾きで音を鳴らす
下記条件で BLE-MIDI 送信する形でプログラムを書いてもらいました。
x軸:音の高さ(左へ傾けると低く、右へ傾けると高くなる)
y軸:ベロシティ(上へ傾けると強く、下へ傾けると弱くなる)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
#include <M5Unified.h> #include "LIS3DHTR.h" #include <Wire.h> #include <BLEMidi.h> LIS3DHTR<TwoWire> LIS; bool wasConnected = false; float lastX = 0.0; float lastY = 0.0; float lastZ = 0.0; bool notePlaying = false; int currentNote = 60; int currentVelocity = 64; const float threshold = 0.10; // X軸のノイズ除去用の移動平均 float smoothX() { float sum = 0; for (int i = 0; i < 5; i++) { sum += LIS.getAccelerationX(); delay(2); } return sum / 5.0; } void setup() { M5.begin(); Wire.begin(21, 22); Serial.begin(115200); BLEMidiServer.begin("Accel MIDI"); LIS.begin(Wire, 0x19); LIS.setFullScaleRange(LIS3DHTR_RANGE_2G); LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ); M5.Lcd.setTextSize(2); } void loop() { if (!BLEMidiServer.isConnected()) { wasConnected = false; delay(100); return; } float x = smoothX(); float y = LIS.getAccelerationY(); float z = LIS.getAccelerationZ(); // 傾き角度取得 float angleX = atan2(x, z) * 180.0 / PI; float angleY = atan2(y, z) * 180.0 / PI; // note: x軸の傾き(±45° → 54〜78) int note = constrain((int)(angleX * 0.2666) + 66, 0, 127); // velocity: y軸の傾き(±45° → 0〜127) int velocity = constrain((int)((angleY + 45.0) * (127.0 / 90.0)), 0, 127); M5.Lcd.setCursor(0, 0); M5.Lcd.printf("X: %+6.2f\nY: %+6.2f\nZ: %+6.2f\n\n", x, y, z); M5.Lcd.printf("AngX: %+5.1f° \nAngY: %+5.1f° \n\n", angleX, angleY); // 発音トリガー float dx = x - lastX; float dy = y - lastY; float dz = z - lastZ; lastX = x; lastY = y; lastZ = z; // 3軸の合成ベクトル長として変化量を出す float dAccel = sqrt(dx*dx + dy*dy + dz*dz); // トリガ判定 if (dAccel > threshold && !notePlaying) { BLEMidiServer.noteOn(0, note, velocity); currentNote = note; currentVelocity = velocity; notePlaying = true; Serial.printf("Note ON: %d Vel: %d\n", note, velocity); M5.Lcd.setCursor(0, 100); M5.Lcd.println("Note ON\n\n"); M5.Lcd.printf("Note: %3d\nVelocity: %3d\n\n", note, velocity); } if (notePlaying && abs(dz) < 0.05) { BLEMidiServer.noteOff(0, currentNote, currentVelocity); notePlaying = false; M5.Lcd.setCursor(0, 100); M5.Lcd.println("Note OFF"); } } |
3軸加速度センサの傾きでガレバンの音を鳴らす🎹
BLE-MIIDIで送信x軸:音の高さ(左へ傾けると低く、右へ傾けると高くなる)
y軸:ベロシティ(上へ傾けると強く、下へ傾けると弱くなる)#M5Stack #Grove #seeed #GarageBand #MIDI pic.twitter.com/8StaLDbkNO— ムプ- (@j6XX2IChZG99891) July 10, 2025
面白いかも!
音階設定:ジャズ風
ただ音を出すだけではなく音階的な音を出したいと思い、
こちらもChatGPTに調整してもらいました。
int scale[] = { 0, 3, 5, 6, 7, 10 };
ここでスケール設定が色々とできそうです。
今回はジャズ風にしてもらいました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
#include <M5Unified.h> #include "LIS3DHTR.h" #include <Wire.h> #include <BLEMidi.h> LIS3DHTR<TwoWire> LIS; bool wasConnected = false; float lastX = 0.0; float lastY = 0.0; float lastZ = 0.0; bool notePlaying = false; int currentNote = 60; int currentVelocity = 64; const float threshold = 0.10; int scale[] = { 0, 3, 5, 6, 7, 10 }; // X軸のノイズ除去用の移動平均 float smoothX() { float sum = 0; for (int i = 0; i < 5; i++) { sum += LIS.getAccelerationX(); delay(2); } return sum / 5.0; } void setup() { M5.begin(); Wire.begin(21, 22); Serial.begin(115200); BLEMidiServer.begin("Accel MIDI"); LIS.begin(Wire, 0x19); LIS.setFullScaleRange(LIS3DHTR_RANGE_2G); LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ); M5.Lcd.setTextSize(2); } void loop() { if (!BLEMidiServer.isConnected()) { wasConnected = false; delay(100); return; } float x = smoothX(); float y = LIS.getAccelerationY(); float z = LIS.getAccelerationZ(); // 傾き角度取得 float angleX = atan2(x, z) * 180.0 / PI; float angleY = atan2(y, z) * 180.0 / PI; // note: x軸の傾き(±45° → 54〜78) int note = constrain((int)(angleX * 0.2666) + 66, 0, 127); // velocity: y軸の傾き(±45° → 0〜127) int velocity = constrain((int)((angleY + 45.0) * (127.0 / 90.0)), 0, 127); M5.Lcd.setCursor(0, 0); M5.Lcd.printf("X: %+6.2f\nY: %+6.2f\nZ: %+6.2f\n\n", x, y, z); M5.Lcd.printf("AngX: %+5.1f° \nAngY: %+5.1f° \n\n", angleX, angleY); // 発音トリガー float dx = x - lastX; float dy = y - lastY; float dz = z - lastZ; lastX = x; lastY = y; lastZ = z; // 3軸の合成ベクトル長として変化量を出す float dAccel = sqrt(dx*dx + dy*dy + dz*dz); // トリガ判定 if (dAccel > threshold && !notePlaying) { // 音をスケールに合わせる処理 int baseNote = constrain(note, 0, 127); int octave = baseNote / 12; int degree = baseNote % 12; int closest = scale[0]; for (int i = 1; i < sizeof(scale)/sizeof(scale[0]); i++) { if (abs(scale[i] - degree) < abs(closest - degree)) { closest = scale[i]; } } note = constrain(octave * 12 + closest, 0, 127); BLEMidiServer.noteOn(0, note, velocity); currentNote = note; currentVelocity = velocity; notePlaying = true; Serial.printf("Note ON: %d Vel: %d\n", note, velocity); M5.Lcd.setCursor(0, 100); M5.Lcd.println("Note ON\n\n"); M5.Lcd.printf("Note: %3d\nVelocity: %3d\n\n", note, velocity); } if (notePlaying && abs(dz) < 0.05) { BLEMidiServer.noteOff(0, currentNote, currentVelocity); notePlaying = false; M5.Lcd.setCursor(0, 100); M5.Lcd.println("Note OFF"); } } |
3軸加速度センサの傾きでガレバンの音を鳴らす🎹 BLE-MIIDIで送信
ブルーノートバージョン pic.twitter.com/kOcialdKwo
— ムプ- (@j6XX2IChZG99891) July 10, 2025
面白い!スケールまで設定すると音楽的な響きになって良い感じ。