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

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

Atom Matrix(ESP32-PICO-D4)に搭載されている加速度センサの値を取得し、下を指す矢印を表示するコードをArduino IDEから書き込む 👇

Atom Matrixを購入したので、Arduino IDEからコードを書き込んできました。

ATOM Matrixwww.switch-science.com

完成したもの

本体を傾けると下方向を指す矢印を表示します。
ここに至るまでにやったことを順を追って説明していきます。

Atom Matrixの仕様を確認する

公式ドキュメントにざざっと目を通します。
加速度センサについての記述がなく、向きがわからなかったのですが、そこは、のちにシリアルプロットを見ながら勘で実装しました。

https://docs.m5stack.com/en/core/atom_matrix

VCPドライバをインストール

公式ドキュメントUSB Drive problemsのところに書いてありますが、Virtual COM port (VCP) driversをインストールしました。

https://docs.m5stack.com/en/core/atom_matrix
ftdichip.com

Arduino IDEからAtom Matrixにコードを書き込む準備をする

公式のクイックスタートに手順が詳しくまとめられているので、この通り準備すればOKです。

docs.m5stack.com

コードを書く

#include <M5Atom.h>

#define accListSize 10
#define arrowListSize 25

bool isInit = false;
float accX = 0;
float accY = 0;
float accZ = 0;
int accListIndex = 0;
float accXList[accListSize] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
float accYList[accListSize] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
float accZList[accListSize] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int arrowUp[arrowListSize] = {
  0, 0, 1, 0, 0,
  0, 1, 1, 1, 0,
  1, 0, 1, 0, 1,
  0, 0, 1, 0, 0,
  0, 0, 1, 0, 0
};
int arrowDown[arrowListSize] = {
  0, 0, 1, 0, 0,
  0, 0, 1, 0, 0,
  1, 0, 1, 0, 1,
  0, 1, 1, 1, 0,
  0, 0, 1, 0, 0
};
int arrowLeft[arrowListSize] = {
  0, 0, 1, 0, 0,
  0, 1, 0, 0, 0,
  1, 1, 1, 1, 1,
  0, 1, 0, 0, 0,
  0, 0, 1, 0, 0
};
int arrowRight[arrowListSize] = {
  0, 0, 1, 0, 0,
  0, 0, 0, 1, 0,
  1, 1, 1, 1, 1,
  0, 0, 0, 1, 0,
  0, 0, 1, 0, 0
};

void setup() {
  M5.begin(true, false, true);
  isInit = M5.IMU.Init() == 0;
  Serial.begin(19200);
}

void loop() {
  if (isInit) {
    M5.IMU.getAccelData(&accX, &accY, &accZ);
    M5.dis.clear();

    accXList[accListIndex] = accX;
    accYList[accListIndex] = accY;
    accZList[accListIndex] = accZ;

    accX = getAve(accXList, accListSize);
    accY = getAve(accYList, accListSize);
    accZ = getAve(accZList, accListSize);

    accListIndex = (accListIndex + 1) % accListSize;

      if (accX < 0) {
        if (abs(accY) < abs(accX)) {
          render(arrowLeft, arrowListSize, CRGB::Blue);
        } else {
          renderY(accY);
        }
      } else {
        if (abs(accY) < abs(accX)) {
          render(arrowRight, arrowListSize, CRGB::Blue);
        } else {
          renderY(accY);
        }
      }

    delay(10);
    M5.update();
  } else {
    M5.dis.clear();
    delay(10);
    M5.update();
  }
}

void renderY(float accY) {
  if (accY < 0) {
    render(arrowUp, arrowListSize, CRGB::Blue);
  } else {
    render(arrowDown, arrowListSize, CRGB::Blue);
  }
}

int getX(int i) {
  return i % (int)sqrt(arrowListSize);
}

int getY(int i) {
  return (int)(i / (int)sqrt(arrowListSize));
}

void render(int arr[], int size, int color) {
  for (int i = 0; i < size; ++i) {
    if (arr[i] == 1) {
      M5.dis.drawpix(getX(i), getY(i), color);
    }
  }
}

float getAve(float list[], int size) {
  float total = 0;

  for (int i = 0; i < size; ++i) {
    total += list[i];
  }

  return total / size;
}

書きました。
過去10回分の加速度の平均値を使うことで安定させています。

以上です。ぱぱっと実装できて非常に満足しています。