M5StickCであそぶ 〜ボタンとLEDを使う〜

前回で無事にM5StickCの開発環境が整ったので、今回から一つずつ機能確認していきます。まずは基本の、ボタンとLEDから。

ピン配列的には、それぞれ以下のように割り当てられています。

  • ボタンA(正面M5ボタン) … GPIO37
  • ボタンB(サイドボタン) … GPIO39
  • 赤色LED … GPIO10

最初「赤色LEDはどこにあるんだ?」と思いましたが、

ここの下の穴ですね。上の穴は赤外線LEDです。

ちなみにボタンBの逆サイドにもボタンがありますが、こちらは電源ボタンなのでプログラミングの対象外です(←実は限定的にはプログラミング自体は可能。後日バッテリーの扱いのところで出てきます)。

 

ではでは早速、ボタンとLEDを使うサンプルプログラムの作成です。今回はすごくシンプルに、「ボタンAを押すとLEDが1回光り、ボタンBを押すとLEDが2回光る」というプログラムにしてみました。

#include <M5StickC.h>

#define BTN_A_PIN 37
#define BTN_B_PIN 39
#define LED_PIN   10

// このLEDは、GPIO10の電位を下げることで発光するタイプ
#define LED_ON  LOW
#define LED_OFF HIGH

// INPUT_PULLUPが有効かは不明だが、有効という前提で定義
#define BTN_ON  LOW
#define BTN_OFF HIGH

uint8_t prev_btn_a = BTN_OFF;
uint8_t btn_a      = BTN_OFF;
uint8_t prev_btn_b = BTN_OFF;
uint8_t btn_b      = BTN_OFF;

void setup() {
  // Initialize the M5StickC object
  M5.begin();
  pinMode(BTN_A_PIN, INPUT_PULLUP);
  pinMode(BTN_B_PIN, INPUT_PULLUP);
  pinMode(LED_PIN,   OUTPUT);
  digitalWrite(LED_PIN, LED_OFF);
  // LCD display
  M5.Lcd.setRotation(1); // ボタンBが上になるような向き
  M5.Lcd.setTextSize(2); // フォントサイズをデフォルトの2倍に
  M5.Lcd.print("BTN&LED Test.");
}

void loop() {
  btn_a = digitalRead(BTN_A_PIN);
  btn_b = digitalRead(BTN_B_PIN);

  if(prev_btn_a == BTN_OFF && btn_a == BTN_ON){
    // ボタンAが押されたとき。今回は1回発光
    digitalWrite(LED_PIN, LED_ON);
    delay(500);
    digitalWrite(LED_PIN, LED_OFF);
  }

  if(prev_btn_a == BTN_ON && btn_a == BTN_OFF){
    // ボタンAが離されたとき。今回は何もしない
    ;
  }

  if(prev_btn_b == BTN_OFF && btn_b == BTN_ON){
    // ボタンBが押されたとき。今回は2回点滅
    digitalWrite(LED_PIN, LED_ON);
    delay(500);
    digitalWrite(LED_PIN, LED_OFF);
    delay(500);
    digitalWrite(LED_PIN, LED_ON);
    delay(500);
    digitalWrite(LED_PIN, LED_OFF);
  }

  if(prev_btn_b == BTN_ON && btn_b == BTN_OFF){
    // ボタンBが離されたとき。今回は何もしない
    ;
  }

  prev_btn_a = btn_a;
  prev_btn_b = btn_b;
}

基本的に純Arduino(?)のときとほぼ同じような感じでいけましたが、LEDを点灯させるときは電位をLOWにして電流を引き込むようにしてやる必要があり、そこだけ普段の自分のやり方とは違う感じになりました。自分は直感的にわかりやすい「電位をHIGHにすると電流が流れる」というやり方を好んで使っていたので。

実際に動作させてみたところです。

 

こんな感じで、特に問題ありません。

さて、普通のArduinoのお作法に従うと上記のようなプログラムになるのですが、M5StickCでは独自にボタンクラスを定義していて、そちらを利用することも可能です。以下、上と同じことを独自ボタンクラスを使用して書き直した場合のプログラムです。

#include <M5StickC.h>

#define LED_PIN   10

// このLEDは、GPIO10の電位を下げることで発光するタイプ
#define LED_ON  LOW
#define LED_OFF HIGH

void setup() {
  // Initialize the M5StickC object
  M5.begin();
  pinMode(LED_PIN,   OUTPUT);
  digitalWrite(LED_PIN, LED_OFF);
  // LCD display
  M5.Lcd.setRotation(1); // ボタンBが上になるような向き
  M5.Lcd.setTextSize(2); // フォントサイズをデフォルトの2倍に
  M5.Lcd.print("BTN&LED Test.");
}

void loop() {
  // ボタン全体の状態更新
  M5.update();

  if(M5.BtnA.wasPressed()){
    // ボタンAが押されたとき。今回は1回発光
    digitalWrite(LED_PIN, LED_ON);
    delay(500);
    digitalWrite(LED_PIN, LED_OFF);
  }

  if(M5.BtnA.wasReleased()){
    // ボタンAが離されたとき。今回は何もしない
    ;
  }

  if(M5.BtnB.wasPressed()){
    // ボタンBが押されたとき。今回は2回点滅
    digitalWrite(LED_PIN, LED_ON);
    delay(500);
    digitalWrite(LED_PIN, LED_OFF);
    delay(500);
    digitalWrite(LED_PIN, LED_ON);
    delay(500);
    digitalWrite(LED_PIN, LED_OFF);
  }

  if(M5.BtnB.wasReleased()){
    // ボタンBが離されたとき。今回は何もしない
    ;
  }

}

M5StickCに特化した形にはなりますが、全体的にすっきりします。他にも、自分で実装すると意外に面倒な「何秒押したら」みたいな処理も定義してくれているので、使いこなせば色々ラクになると思います。以下で詳しくまとめてくださっています。

 

今回は以上です。Arduinoのときと違って何も配線する必要がないので、大変ラクでした。次回は赤外線LEDあたりを触ってみようかなと思っています。