M5:Bitでサンプルプログラムを動かす


M5:Bit converter Board for Micro:bit

M5:Bitを入手しましたがサンプルプログラムの動かし方がわかりづらかったため、記載します。

そもそもこれは何かといいますと、Micro:bitをM5Stackから制御するためのものです。
このM5:BitをMicro:bitに装着することでGrove接続のMicro:bitモジュールにできるようなイメージです。ただしMicro:bit側にもそれ用のプログラムが必要になります。

それぞれのプログラムは公式の下記リンクに記載されたとおりなのですが色々うまくいかなかった点がありました。

M5Stack側プログラム

公開されているサンプルプログラムのM5BIT.inoでは、

#include <M5StackUpdater.h>

でまずコンパイルエラーになりました。
検索して調べてみると、これは『M5Stack-SD-Updater』というものが使われているそうです。

↓M5Stack-SD-Updaterについては、こちらの説明がわかりやすかったです。
https://qiita.com/tomorrow56/items/c58f099595bc873e4c65

なるほどとても便利なライブラリのようです。
ということでこの情報に従ってライブラリをインストールして進めようとしたらまた新たな依存関係のエラーに。そしてその先にまた依存関係が‥で最終的によくわからないエラーに。

そもそも、M5Stack-SD-Updaterは便利そうだけど今回動かしてみたいM5:Bitには使わなくてもよさそうなのでM5Stack-SD-Updaterを使わないようにしました。

具体的には、includeの行と

  if(digitalRead(BUTTON_A_PIN) == 0){
    Serial.println("Will load menu binary");
    updateFromFS(SD);
    ESP.restart();
  }

をコメントアウトするだけで大丈夫でした。

また、このM5:BitはUART通信なので、GROVEポートはM5Stack FireなどのPortC(青色)につなぎます。
(最初M5Stack BasicのI2CのGROVEポートに繋いでしまって「動かない」ってじたばたしてしまってました。。)

m5bit.ino
/*
    Description: Use UART communication to control the LED matrix on microbit.
*/
#include <M5Stack.h>

#define WIDTH 320
#define HEIGHT 240
#define BLOCK_SIZE  40
#define UNIT_WIDTH  5
#define UNIT_HEIGHT 5
#define UNIT_SIZE 25
#define GETX(i) ((i) % (5))
#define GETY(i) ((i) / (5))
int world[UNIT_SIZE];
int i;

void setup() {
  M5.begin();
  M5.Power.begin();
  Wire.begin();
//  if(digitalRead(BUTTON_A_PIN) == 0){
//    Serial.println("Will load menu binary");
//    updateFromFS(SD);
//    ESP.restart();
//  }
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(35, 220);  
  M5.Lcd.println("  <       *       >");  
    for (i = 0; i < UNIT_SIZE; i++) {
    world[i] = 0;
  }
  i = UNIT_SIZE / 2;
}

void loop() {
      M5.update();
      int x = GETX(i) + 1;
      int y = GETY(i);
      if (world[i] > 0) M5.Lcd.fillRect(x * BLOCK_SIZE + 1, y * BLOCK_SIZE + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2, LIGHTGREY);
      else M5.Lcd.fillRect(x * BLOCK_SIZE + 1, y * BLOCK_SIZE + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2, BLUE);
      if (M5.BtnC.wasPressed()) {
         if (world[i] > 0) M5.Lcd.fillRect(x * BLOCK_SIZE + 1, y * BLOCK_SIZE + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2, WHITE);
         else M5.Lcd.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, BLACK);
         ++i;
         if (i >= UNIT_SIZE) i=0;
      }
      if (M5.BtnA.wasPressed()) {
         if (world[i] > 0) M5.Lcd.fillRect(x * BLOCK_SIZE + 1, y * BLOCK_SIZE + 1, BLOCK_SIZE - 2, BLOCK_SIZE - 2, WHITE);
         else M5.Lcd.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, BLACK);
         --i;
         if (i < 0 ) i=UNIT_SIZE -1;
      }
      if (M5.BtnB.wasPressed()) {
        if (world[i] > 0) world[i]=0;
        else world[i]=1;
        Serial2.print(world[i]);
        Serial2.print(GETX(i));
        Serial2.println(GETY(i));
      }
}

Micro:bit側プログラム

こちらはMakeCodeです。
サンプルは英語表記のイメージだったので日本語にするとこのようになります。

実行

M5Stack側プログラムとMicro:bit側プログラムを書き込んだら、接続して実行できます。