第6回 解答例

LEDクラスを作る

演習の解答例。まず自分で書いてから読むこと。

解答

#include <Arduino.h>

class LED {
public:
    LED(int pin)
        : pin(pin), state(false) {
    }

    void begin() {
        pinMode(pin, OUTPUT);
        off();
    }

    void on() {
        state = true;
        digitalWrite(pin, HIGH);
    }

    void off() {
        state = false;
        digitalWrite(pin, LOW);
    }

    void toggle() {
        if (state) {
            off();
        } else {
            on();
        }
    }

private:
    int pin;
    bool state;
};

LED led1(LED_BUILTIN);
LED led2(23);

void setup() {
    led1.begin();
    led2.begin();
}

void loop() {
    led1.toggle();
    delay(500);

    led2.toggle();
    delay(500);
}

pinMode()をどこで呼ぶか

これが今回いちばん考えどころになる。候補は2つある。

書く場所利点問題
コンストラクタ呼び忘れがないオブジェクトが作られる時点でハードウェアがまだ初期化されていない場合がある
begin()を用意するsetup()の中で確実に呼べる呼び忘れる可能性がある

Arduinoでは、グローバル変数のコンストラクタがsetup()より前に動く。この時点でのハードウェア操作は安全とは限らないため、begin()を分ける書き方を勧める。

ポイント

  • stateを持つことでtoggle()が書ける。データと処理が同じ場所にある利点
  • led1とled2はそれぞれ独立したpinとstateを持つ
  • メンバ初期化リスト: pin(pin), state(false)を使う
  • クラス定義の末尾の;を忘れない

→ 第6回の本文に戻る