M5StickCのButtonクラスを調べてみた

Homeボタンと右ボタン、そして電源ボタンの制御について調べてみました。

ボタンについて

ざっくりと上記で取得できます。

ホームボタンと右ボタンについて

M5.update()

ボタンの状態を更新する関数です。Buttonクラスを利用する場合にはloop()の先頭に近い場所で必ず実行するようにしましょう。

この関数を呼ばないとボタンの状態は更新されません。

isPressed()

今現在ボタンを押しているかを返却します。ボタンを押している間は常にTRUEが戻ってきます。

isReleased()

今現在ボタンを離しているかを返却します。ボタンを押していない間は常にTRUEが戻ってきます。

wasPressed()

ボタンを押してから最初に呼び出した時だけTRUEを返却します。1度しか状態を取得できないので注意して呼び出しましょう。

wasReleased()

ボタンを押して、離してから最初に呼び出した時だけTRUEを返却します。1度しか状態を取得できないので注意して呼び出しましょう。一般的にボタンを押した判定はこの関数の戻り値で判定したほうが自然だと思います。

pressedFor(ms)

ボタンをms以上押している場合にTRUEが返却されます。次のループでもTRUEを返却するので長押し処理で数値をカウントアップする場合などに利用すると良いと思います。

releasedFor(ms)

ボタンを離してからms以上経過している場合にTRUEが返却されます。ボタン連打防止などでこの関数で一定以上時間経過後にフラグ更新して、次の入力を受け付ける処理などに利用できると思います。

wasReleasefor(ms)

ms以上ボタンを押して、離してから最初に呼び出した時だけTRUEを返却します。1度しか状態を取得できないので注意して呼び出しましょう。

長押しを戻るボタンに設定した場合などに利用すると、便利だと思います。

lastChange()

最後にボタンの状態が変更された時の millis() の値が返却されます。現在のmillis()からの差分が経過時間になります。

電源ボタン

M5.Axp.GetBtnPress()

  • 戻り値1:電源ボタンを1秒以上押した場合
  • 戻り値2:電源ボタンを1秒未満押してから離した場合
  • 戻り値0:上記以外

この関数は0以外の数値は1度しか取得できないので注意してください。

また6秒以上電源ボタンを押すと、電源が切れるので長押しの操作はあまり適していません。

サンプルスケッチ

#include <M5StickC.h>

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3); // 画面に入らないので横向きにする
}

void loop() {
  // Buttonクラスを利用するときには必ずUpdateを呼んで状態を更新する
  M5.update();

  // カーソル初期化
  M5.Lcd.setCursor(0, 0);

  // ホームボタンが現在押されているか?
  M5.Lcd.print("BtnA.isPressed():");
  M5.Lcd.println( M5.BtnA.isPressed() );

  // ホームボタンが現在離しているか?
  M5.Lcd.print("BtnA.isReleased():");
  M5.Lcd.println( M5.BtnA.isReleased() );

  // ホームボタンを押したか?(1度だけ取得可能)
  if ( M5.BtnA.wasPressed() ) {
    Serial.println("BtnA.wasPressed() == TRUE");
  }

  // ホームボタンを離したか?(1度だけ取得可能)
  if ( M5.BtnA.wasReleased() ) {
    Serial.println("BtnA.wasReleased() == TRUE");
  }

  // ホームボタンを現在ms以上押しているか?
  if ( M5.BtnA.pressedFor(1000) ) {
    Serial.println("BtnA.pressedFor(1000) == TRUE");
  }

  // ホームボタンを離してからms以上経過しているか?
  M5.Lcd.print("BtnA.releasedFor(1000):");
  M5.Lcd.println( M5.BtnA.releasedFor(1000) );

  // ホームボタンをms以上押してから離したか?(1度だけ取得可能)
  if ( M5.BtnA.wasReleasefor(1000) ) {
    Serial.println("BtnA.wasReleasefor(1000) == TRUE");
  }

  // ホームボタンが最後に更新した起動経過時間 millis()
  M5.Lcd.print("BtnA.lastChange():");
  M5.Lcd.println( M5.BtnA.lastChange() );

  // 空行を追加
  M5.Lcd.println();

  // 右ボタンが現在押されているか?
  M5.Lcd.print("BtnB.isPressed():");
  M5.Lcd.println( M5.BtnB.isPressed() );

  // 右ボタンが現在離しているか?
  M5.Lcd.print("BtnB.isReleased():");
  M5.Lcd.println( M5.BtnB.isReleased() );

  // 右ボタンを押したか?(1度だけ取得可能)
  if ( M5.BtnB.wasPressed() ) {
    Serial.println("BtnB.wasPressed() == TRUE");
  }

  // 右ボタンを離したか?(1度だけ取得可能)
  if ( M5.BtnB.wasReleased() ) {
    Serial.println("BtnB.wasReleased() == TRUE");
  }

  // 右ボタンを現在ms以上押しているか?
  if ( M5.BtnB.pressedFor(1000) ) {
    Serial.println("BtnB.pressedFor(1000) == TRUE");
  }

  // 右ボタンを離してからms以上経過しているか?
  M5.Lcd.print("BtnB.releasedFor(1000):");
  M5.Lcd.println( M5.BtnB.releasedFor(1000) );

  // 右ボタンをms以上押してから離したか?(1度だけ取得可能)
  if ( M5.BtnB.wasReleasefor(1000) ) {
    Serial.println("BtnB.wasReleasefor(1000) == TRUE");
  }

  // 右ボタンが最後に更新した起動経過時間 millis()
  M5.Lcd.print("BtnB.lastChange():");
  M5.Lcd.println( M5.BtnB.lastChange() );

  // 電源ボタンの状態取得(一度しか0以外のステータスは取得できない)
  int axpButton = M5.Axp.GetBtnPress();
  if ( axpButton == 1 ) {
    // 1秒以上電源ボタンを押している
    Serial.println("M5.Axp.GetBtnPress() == 1");
  }
  if ( axpButton == 2 ) {
    // 1秒未満電源ボタンを押して離した
    Serial.println("M5.Axp.GetBtnPress() == 2");
  }
}

まとめ

電源ボタンも利用できるようになったので、ボタンの利用用途が広がりますね。ただ取得できるタイミングが違うので、完全に同じように使うことはできないみたいです。

普通のボタンクリックは wasReleased() と axpButton == 2 が同じような動きになりますが、電源の長押しは1秒以上押したら1度だけ1が返却されるので、押しっぱなしかどうかがわからないんですよね。

6秒以上電源ボタン押していると電源切れるので、長押しは電源ボタンにはあまり割り振らないほうがいいですね。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)