今回は、mBotプログラミングシリーズ(Arduino編)の第10回です。
この回では、mBotのボード上にあるボタンを使ってmBotを制御する方法を学びます。
このボタンを利用することで、mBotの動作を手動で制御したり、特定のアクションをトリガーしたりすることができます。
実際にプログラムを作成しながら、その応用例も紹介していきます。

全講座の一覧はこちら
目標
- ボード上のボタンの仕組みを理解する。
 - ボード上のボタンに関するAPIを学ぶ
 - ボード上のボタンを用いたプログラムを作成する。
 
Arduinoプログラムファイルの作成
ここでは、プログラムファイルをイチから作成していきます。
Arduino IDEを立ち上げ、ファイル -> 新規スケッチで真っ新なプロジェクトを用意しましょう。

mBot上のボタンの基本
mBot上のボタンとは
mBotのボードには、ユーザーが押すことで状態を切り替えるためのボタンが搭載されています。
このボタンの状態はアナログ入力ピン(7)を通じて読み取られ、押されている場合は低い値、押されていない場合は高い値として取得されます。

mBot上のボタンに関するAPI
API(Application Programming Interface)は、ソフトウェアやハードウェアが外部のプログラムとやり取りをするためのインターフェース(接点)です。
簡単に言うと、『決められたルールに従って機能を利用するための仕組み』です。
mBotのArduinoライブラリを使用すると、mBotのモーター、LED、ブザー、センサーなどの各機能を簡単に利用できます。
mBot上のボタンを制御するための専用クラスは用意されていません。
このボタンは、アナログ入力ピン(7)に接続されているため、analogRead関数を使用してボタンの状態を読み取ることができます。
int buttonState = analogRead(7);  // アナログ入力ピン7のアナログ値を読み出しAPIを利用した簡単なプログラム
APIを用いて、次のような簡単なプログラムが作成できます。
ボード上のボタンの状態を取得し、その状態をブザーで鳴らすプログラムを作成します。
#include <MeMCore.h>
MeBuzzer buzzer;
void setup() {}
void loop() {
  buzzer.tone(analogRead(7) + 300, 500); // 入力ピンのアナログ値に応じた周波数を 500ms 再生
  delay(600);                            // 600ms待つ
}ボタンを押すと低い音、ボタンを離すと高い音が出るはずです。
ボタンで制御するプログラムの注意点
mBotの工場出荷ソフトウェアのように、ボタンを押してモードを切り替えるプログラムを作成する場合は注意が必要です。
入力ピンのアナログ値を参照して判定するプログラムとした場合、繰り返し処理内で何度もボタンが押された判定となり、モードがどんどん変わっていってしまう可能性があります。
これを解決するためには、アナログ値を参照するのではなく、繰り返し処理における一周期前からボタンの状態が変化したかどうかで判断すべきです。
mBot上のボタンで動作を開始するプログラム
以下のコードは、『ボタンを押すことにより、動作を開始する』プログラムです。
mBot起動後に突然走り出さないための便利な機能です。
#include <MeMCore.h>
MeDCMotor MoterL(M1);
MeDCMotor MoterR(M2);
void setup() {
  while(analogRead(7) > 100){     // ボタンが離されている間、ループを続ける
  }
  // 前進
  MoterL.run(-100);
  MoterR.run(100);
}
void loop() {}(analogRead(7) > 100)の間、つまりボタンが押されるまでループ処理を続けることで、次の処理へ移行しないようにしています。
ボタンが押されるとwhileループを終了し、mBotの前進処理へ移ります。
mBot上のボタンを使ったモード変更プログラム
以下のコードは、『ボタンを押すごとに、2つのモードが切り替わる』プログラムです。
モードAはブザー制御、モードBはLED制御としています。
#include <MeMCore.h>
MeBuzzer buzzer;
MeRGBLed rgb(7,2);
boolean currentPressed = false;    // 今のボタンの状態
boolean pre_buttonPressed = false; // 一周期前のボタンの状態
#define MODE_A 0
#define MODE_B 1
uint8_t mode = MODE_A;
void setup() {}
void loop() {
  currentPressed = !(analogRead(7) > 100);
  // モード切替処理
  if(currentPressed != pre_buttonPressed){  // ボタンの状態が一周期前と異なる場合
    if(currentPressed == true){             // ボタンが押されたとき
      if(mode == MODE_A ){
        mode = MODE_B;
      }
      else{
        mode = MODE_A;
      }
    }
  }
  pre_buttonPressed = currentPressed;       // 一周期前のボタンの状態を更新
  // モード毎の処理
  // モードAの処理
  if(mode == MODE_A ){
    buzzer.tone(261.6, 500); // ド (C4) を 500ms 再生
    delay(600);              // 600ms待つ
  }
  // モードBの処理
  else{
    rgb.setColor(0, 255, 0, 0); // 赤色
    rgb.show();
    delay(500);              // 0.5秒待つ
    rgb.setColor(0, 0, 255, 0); // 緑色
    rgb.show();
    delay(500);              // 0.5秒待つ
    rgb.setColor(0, 0, 0, 0); // 消灯
    rgb.show();
  }
}ボタンの状態currentPressedは、「!(analogRead(7) > 100)」で表しています。
ピンのアナログ値が、
・100より大の時:ボタンを離している状態 ⇒ currentPressed が false
・100以下の時 :ボタンを押している状態 ⇒ currentPressed が true
モードの切り替え条件は、
・ボタンの状態currentPressedが一周期前の状態pre_buttonPressedと異なり
かつ
・ボタンの状態currentPressedがtrue(押されているとき)
としています。
これにより、ボタンを押す操作を複数周期で認識することなく、モードを切り替えることができます。
まとめ
今回は、analogRead(7)を使って、mBo上のボタンを認識する基本的なプログラムを学びました。
また、ボタンの状態変化を検出してモードを切り替える方法についても紹介しました。
これにより、ボード上のボタンを活用してmBotの動作を手動で制御する方法が理解できたと思います。
次回は、より複雑なプログラミングを可能とする、関数について学びます。
mBlockを使ったmBotのプログラミング方法を丁寧に解説していておススメです。
mBotを使用した拡張的な遊びは『mBotでものづくりをはじめよう』が参考になります。mBotのパーツを段ボールと組み合わせてオリジナルのロボットを作るといったような拡張的な遊びが楽しめます。

  
  
  
  

					
					
Arduino IDEからmBotへ書き込みして、動作を確認してみましょう。