みかづきブログ・カスタム

基本的にはちょちょいのほいです。

M5Stack Core2 v1.1の傾きを検知して、音源を再生しながらNeoPixelを輝かせる ✨

M5Stack Core2を使ってチャーハンを輝かせるべく、プログラムを書いてます。
今回はこれまで作ったプログラムを組み合わせて、

  • 加速度センサで傾きを検知
  • 傾いたら音源を再生
  • 傾いたらNeoPixelを輝かせる
  • ボタンを押して機能をOFFにしたら傾けても何も起こらない

を実現します。

前回までのあらすじ

加速度センサ編

blog.kimizuka.org

NeoPixel編

blog.kimizuka.org

音源再生編

blog.kimizuka.org

ボタン制御編

blog.kimizuka.org


加速度センサ値の読み取り、LED(NeoPixel)の制御、音源の再生ときたので、あとは組み合わせればほぼほぼOKなのですが、ゆくゆく必要になるであろう、ボタンの制御を今回は実装していこうと思います。

ソースコード

#include <M5Core2.h>
#include <driver/i2s.h>
#include <AudioFileSourceSD.h>
#include <AudioGeneratorMP3.h>
#include <AudioOutputI2S.h>
#include <Adafruit_NeoPixel.h>

AudioFileSourceSD *file;
AudioGeneratorMP3 *mp3;
AudioOutputI2S *out;

#define BCLK_PIN 12
#define LRCK_PIN 0
#define SADTA_PIN 2
#define EXTERNAL_I2S 0
#define OUTPUT_GAIN 100

bool isPlay = false;
bool isOn = false;

#define LEDPIN 32
#define NUMPIXELS 72
#define DELAY 10

Adafruit_NeoPixel pixels(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);

int ledIndex = 0;

float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;

ButtonColors offColor = {BLACK, WHITE, WHITE};
ButtonColors onColor  = {BLACK, RED, RED};

int buttonWidth = 160;
int buttonHeight = 90;

Button button(
  (320 - buttonWidth) / 2,
  (240 - buttonHeight) / 2,
  buttonWidth,
  buttonHeight,
  false,
  "ON",
  offColor,
  onColor
);

void setup() {
  pixels.begin();
  M5.begin();
  M5.IMU.Init();
  M5.Axp.SetSpkEnable(true); 
  button.addHandler(handleButtonRelease, E_RELEASE);
  M5.Buttons.draw();
  playMp3();
}

void playMp3() {
  if (!isPlay) {
    isPlay = true;
    file = new AudioFileSourceSD("/bgm.mp3");
    out = new AudioOutputI2S(I2S_NUM_0, EXTERNAL_I2S); 
    out -> SetPinout(BCLK_PIN, LRCK_PIN, SADTA_PIN);
    out -> SetOutputModeMono(true);
    out -> SetGain((float)OUTPUT_GAIN / 100.0);
    mp3 = new AudioGeneratorMP3();
    mp3 -> begin(file, out);
  }
}

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  pixels.clear();

  if (isOn) {
    if (mp3 -> isRunning()) {
      isPlay = true;

      if (!mp3 -> loop()) {
        mp3 -> stop();
        isPlay = false;
      }
    } else {
      isPlay = false;
      mp3 -> stop();
    }

    if (-0.8F < accZ) {
      if (!isPlay) {
        playMp3();
      }

      for (int i = 0; i < 16; i++) {
        pixels.setPixelColor((ledIndex + i * 2) % NUMPIXELS, pixels.Color(100, 100, 100));
      }

      pixels.show();
    } else {
      if (isPlay) {
        isPlay = false;
        mp3 -> stop();
      }

      for (int i = 0; i < NUMPIXELS; i++) { 
        pixels.clear();
        pixels.show();
      }
    }

    ledIndex = (ledIndex + 1) % NUMPIXELS;
  } else {
    isPlay = false;
    mp3 -> stop();

    for (int i = 0; i < NUMPIXELS; i++) { 
      pixels.clear();
      pixels.show();
    }

    delay(100);
  }
}

void handleButtonRelease(Event & e) {
  isOn = !isOn;
  button.setLabel(isOn ? "OFF" : "ON");
  M5.Buttons.draw();
}

基本的に組み合わせただけです。

DEMO

タッチパネル上のボタンでON・OFFできます。
GIFアニメだと分かりませんが、LEDが輝いている時は音源もループ再生されています。

裏返すと光も音もOFFになります。
GIFアニメだと分かりませんが、LEDが消灯している時は音源も停止しています。

リポジトリ

github.com

ソフトとしてはこれでOKなので、次回はクロッシュ(フタ)に取り付けるための治具を作成していきます。