M5StickC PLUSでArduinoをはじめよう!

M5StickC-PLUS
M5StickC-PLUS

この記事では、はじめてM5StickC PLUSを使ってArduino開発するまでの解説をしていきます。M5StickC PLUSは、Arduino互換機であるESP32をベースにLCD・バッテリー・ボタンなどを内蔵し、パッケージ化した小型のM5Stack製品です。

なお、今回の開発環境はMacBook Proで行いました。

M5StickC PLUSの仕様

項目内容
モデル名M5StickC Plus
SocESP32-PICO-D4
BPS1200-115200/250k/500k/750k/1.5M
項目スペックピン割り当て
ボタンAGPIO37
ボタンBGPIO39
ブザーGPIO2
IRGPIO9
LEDGPIO10
LCDST7789V2(135x240)GPIO15/13/23/18/5
MICSPM1423DATA:GPIO34
CLK:GPIO0
電源管理AXP192
内蔵電池リチウムイオンポリマー120mA
慣性計測装置(IMU)6-Axis(MPU6886)SCL:GPIO22
SDA:GPIO21
リアルタイムクロック(RTC)BM8563
SCLGPIO33
SDAGPIO32

M5StickC PLUSは、M5StickCのアップグレード版です。ESP32ベースなのでWiFi、Bluetoothは、もちろん使えます。また、ジャイロ・加速度センサーやリアルタイムクロックも内蔵されています。

詳しくは M5StickC PLUSドキュメント をご覧ください。

ドライバのインストール

まず、MacbookでM5と通信できるようにするため、 M5STACKのダウンロードページ からCP2104 Driverをインストールします。

インストール完了後、次のコマンドでSiLabsUSBDriverの有無を確認しましょう。

$ ls /Library/Extensions/
HighPointIOP.kext	SiLabsUSBDriver.kext
HighPointRR.kext	SoftRAID.kext

セキュリティ関係でインストールできない場合は「System Preference」の「Security & Privacy」で鍵を一旦外しましょう。

Arduino IDEの設定

M5Stack Core2を接続し、Arduino IDEを起動します。シリアルポートは「/dev/cu.usbserial-xxxxx」で始まるポートを選択します。

▼PreferenceのボードマネージャーURLsに以下のアドレスを追加します。

https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json

その後、Toolsのボードマネージャーを開き「m5」で検索しM5Stackのボードをインストールします。さらに、ライブラリマネージャで「M5StickC」で検索し「M5StickCPlus」をインストールします。

プログラムの書き込みテスト

ここまでで、M5StickC PLUSの開発の準備が整ったと言いたいのですが、スケッチをアップロードするときにいくつかエラーが出て書き込めませんでした。その時のエラーと対処法を記しておくので、同じ症状が起きた場合の参考にしてください。

書き込みエラー1

▼serialモジュールが見つからないエラーが発生しました。M5StickでPythonのserialを使っているのが関係しているようです。

Traceback (most recent call last):
  File "/Users/mopipico/Library/Arduino15/packages/m5stack/tools/esptool_py/3.0.0/esptool.py", line 39, in <module>
    import serial
ImportError: No module named serial
exit status 1
Error compiling for board M5Stick-C-Plus.

▼pip3からpython2側にパッケージを追加すれば良いようで、次のようにして解決できました。

$ sudo pip3 install --target /Library/Python/2.7/site-packages pyserial

参考

書き込みエラー2

その他の書き込みエラーの時は、USB-Cケーブルを抜き差ししたり、シリアルモニターを一旦閉じたりして根気よく何度か試せばうまくいきます。

千里の道もLチカから

千里の道もLチカから
千里の道もLチカから

それでは、M5StickC PLUSのプログラミングをしていきましょう。まずは定番のLEDを点灯させる「Lチカ」からやってみたいと思います。実はM5StickC PLUSにはLEDが内蔵されており、G10に割り当てられています。なので、次のようなプログラミングでLEDを点滅させることができます。ただし、G10がLOWを出力した時にLEDが点灯することに注意して下さい。

#include <M5StickCPlus.h>

#define LED_PIN 10 // G10

void setup() {
    M5.begin();
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    // M5.update();

    digitalWrite(LED_PIN, LOW); // LED点灯
    delay(500);
    digitalWrite(LED_PIN, HIGH); // LED消灯
    delay(500);

}

LCDに「Hello World!」を表示する

M5StickC-PLUS
M5StickC-PLUS

次に、LCD画面に「Hello World!」の文字を表示してみましょう。次のようにM5ライブラリを使うことで、かんたんに文字表示が可能です。ただし、デフォルトでは縦画面に設定されています。画面を回転させるにはM5.Lcd.setRotation(3)などで変更します。

#include <M5StickCPlus.h>

void setup() {
  // initialize the M5StickC object
  M5.begin();
  M5.Axp.ScreenBreath(10); // 画面の明るさ7〜12
  M5.Lcd.setRotation(3); // 画面を横向きにする
  M5.Lcd.fillScreen(WHITE);
  M5.Lcd.setCursor(5, 10);
  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setTextSize(2);
  M5.Lcd.printf("Hello World!");
}

void loop(){
}

LCDサンプルコード

GitHubに LCD表示のサンプルコード があるので試してみましょう。

Display.inoを実行すると、動画のように三角形がランダム表示されます。▼

M5StickC PLUSのLCDサンプル
M5StickC PLUSのLCDサンプル

ボタンのイベントを取得する

M5StickC PLUSでは、電源ボタン以外に二つのボタンがあり、プログラムで自由に扱えます。フロントのボタンがAボタン、右サイドのボタンがBボタンとして割り当てられています。

たとえば、ボタンが押されたかどうかはwasPressed()で判定が可能です。この関数は、ボタンが押される度に一度だけ1を返すので、loop内で状態を監視してあげれば良いです。また、ボタンを押している間だけ処理をさせたい場合は、isPressed()関数で判定できます。

#include <M5StickCPlus.h>

void setup() {
  Serial.begin(9600);
  // initialize the M5StickC object
  M5.begin();
}

void loop(){
  M5.update(); // Buttonの状態更新のため必要

  if(M5.BtnA.wasPressed()){
    Serial.println("Pressed A button.");
  }
  
  if(M5.BtnB.wasPressed()){
    Serial.println("Pressed B button.");  
  }
}

参考

ただしこの方法だと、delay関数をはさんだ時にボタンが反応しなかったりします。それを回避したい場合は、割り込み処理で対応します。次の「内蔵ブザーを鳴らす」項目で実装してみたので参考にしてみてください。

内蔵ブザーを鳴らす

M5StickC Plusには、ブザーも内蔵されいます。音色や音量は変えられませんが、音程(周波数)を変えられます。ブザーを鳴らすには非常にカンタンで、M5.Beep.tone(周波数)で指定するだけです。

ここではAボタンを押すたびにブザー音を止めたり再生したりできるように、割り込み処理も実装してみました。

割り込み処理は、attachInterrupt(割込み番号, 関数名, モード)関数を使用します。AボタンのGPIO番号は37で、ピン番号から割込み番号の解決にはdigitalPinToInterruptを使います。

#include <M5StickCPlus.h>

const int BUTTON_A = 37;
bool onBuzzer = true;

void handleInterrupt() {
  onBuzzer = !onBuzzer;
}

void setup() {
  M5.begin();
  pinMode(BUTTON_A, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_A), handleInterrupt, FALLING);
}

void loop() {
  M5.update();
  M5.Beep.update();           // tone関数で鳴らした音が指定時間経過していたら止める

  if(onBuzzer) {
    soundTest();
  }
  delay(5);
}
void soundTest() {
  M5.Beep.tone(3000);
  delay(100);
  M5.Beep.tone(4000);
  delay(100);
  M5.Beep.tone(5000);
  delay(100);
  M5.Beep.tone(6000);
  delay(100);
  M5.Beep.tone(7000);
  delay(100);
  M5.Beep.mute();
  delay(100);  
}

▼ラ=440Hzにおける音階と周波数の対応表を記しておきます。参考にしてみてください。

周波数(Hz) 音階名
440.000
466.164 ラ#
493.883
523.251
554.365 ド#
587.330
622.254 レ#
659.255
698.456 ファ
739.989 ファ#
783.991
830.609 ソ#
880.000

I2Cでセンサーモジュールと接続する

最後に、M5StickC PLUSでI2Cを使ってみましょう。今回は、非接触温度センサGY-906を使ってみました。▼

M5StickC PLUSでI2C通信を行うには、G32・G33を使用します。また、端子にI2Cデバイスを繋ぐにはGROVE規格のコネクタが必要になります。▼

GROVEコネクタケーブル
GROVEコネクタケーブル

GROVEコネクタは、ジャンパーワイヤーと違って容易には外れないためモバイル用途には安心なコネクタです。ただし、M5とGROVEコネクタのカラーには統一がないので注意が必要です!接続先のセンサーモジュールをよく確認し、SDA・SCLなど配信が間違わないように注意しましょう。

▼HATなどのG0、G26を使ってI2C通信をやりたい場合は、こちらの記事を参考にしてください。

M5StickC PLUSでI2Cによる温度測定
M5StickC PLUSでI2Cによる温度測定

さて、GY-906とGROVEコネクタ接続してLCDに温度を表示させるプログラムを書いてみました。動画のように、指を近づけるとざっくりとですが体温を測定できました。ちなみに、Objは物体の温度でAmbは周囲の環境の温度(気温)です。

#include <M5StickCPlus.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();


void setup() {
  // initialize the M5StickC object
  M5.begin();
  mlx.begin(); 
  M5.Lcd.setRotation(3); // 画面を横向きにする
}

void loop(){
  float amb = mlx.readAmbientTempC();
  float obj = mlx.readObjectTempC();
  showTempreture(amb, obj);
//  M5.update();
  delay(1000);
  
}

void showTempreture(float amb, float obj) {
  M5.Lcd.fillScreen(WHITE);
  M5.Lcd.setCursor(5, 10);
  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setTextSize(4);
  M5.Lcd.printf("%.1fC Obj", obj);
  M5.Lcd.setCursor(5, 50);
  M5.Lcd.setTextSize(4);
  M5.Lcd.printf("%.1fC Amb", amb);
}

GY-906の使い方はArduinoで非接触温度センサGY-906で詳しく解説しました。

その他

その他にも、加速度センサで振動測定SPIFFSにデータ保存内蔵ADコンバータで電圧測定Ambientへログ送信黒く塗装したりと、いろいろやってますのでご参考になさってみてください。

おわりに

以上でM5StickC PLUSのかんたんな使い方の説明を終わります。今回はじめてM5StickC PLUSを使ってみたのですが、使いやすく楽しく非常に可能性を感じました。とくにLCD・ボタン・バッテリーがすべてパッケージされているのは非常に便利で、開発作業に集中できますね!プロトタイピング的な製品はもちろん、モバイル端末としていろいろと面白い使い方ができそうです。

Githubのに上がってる M5StickC-Plusのサンプルコード も要チェックです。

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
M5Stackのオススメ参考書
M5Stack製品
M5StickCで使えるHat
関連記事