今回で「VBAでオブジェクト指向を理解する」の連載を終える。
前回では、VBAのクラスモジュールで複数のオブジェクトを駆動させた。最終回である本稿は、VBAで得た知見によって Arduino に接続した複数のLEDを点滅させる。
コード 1 は、Arduino C++ のLED点滅プログラムである。前回掲載した VBA のコードに倣ってコーディングしているので、クラスの名称も敢えて同じにした。セルをLEDに見立てた疑似LEDと現実のLEDでは違いがあるものの、基本的には同様の処理で動作することがわかる。
写真 1 は実験に使用した Arduino nano にLEDを接続したボード、動画 1 はLEDの点滅状態である。この動画で 3種類のタイミングで点滅を繰り返す LED と、2種類の周期で明さが変化する LED を確認できる。
コード 1. Arduino C++ による LED / BAR クラスの実装
#include <Arduino.h>
// LED クラス
class LED {
private:
int pin; // LED のピン番号
int T_on; // LED の点灯時間(ミリ秒)
int T_off; // LED の消灯時間(ミリ秒)
unsigned long T_st; // LED が点灯を開始した時間(ミリ秒)
int flg; // タイマー監視フラグ 1:監視中 0:監視中でない
public:
void SpecSet(int pinNumber, int TimeON, int TimeOFF){
pin = pinNumber;
T_on = TimeON;
T_off = TimeOFF;
flg = 0;
pinMode(pin, OUTPUT);
}
void Blink(){
unsigned long Now_ms = millis();
if (flg == 0) {
T_st = Now_ms; // 点灯開始時間を更新
flg = 1; // 監視フラグ ON
}
if (Now_ms < T_st + T_on){
digitalWrite(pin, HIGH);
} else if (Now_ms < T_st + T_on + T_off){
digitalWrite(pin, LOW);
} else {
flg = 0; // 監視フラグ OFF
}
}
};
// BAR クラス
class BAR {
private:
int pin; // LED のピン番号
long Max; // 最大値(ミリ秒)
public:
void SpecSet(int pinNumber,unsigned long MaxValue){
pin = pinNumber; // ArduinoのPWM対応ピン 3, 5, 6, 9, 10, 11
Max = MaxValue;
pinMode(pin, OUTPUT);
}
void update(unsigned long num){
unsigned long filled;
filled = 255 * (num % Max) / Max; // filled:0 -> 255を繰り返す
analogWrite(pin, filled); // filled値でLEDの光量変化
}
};
void setup() {
// LEDのインスタンス生成
LED LED1; // (5,1000,500);
LED LED2; // (6,200,500);
LED LED3; // (13,100,1000);
// BARのインスタンス生成
BAR BAR1; //(9,2000);
BAR BAR2; //(10,1000);
// LEDの属性設定
LED1.SpecSet(5,500,500);
LED2.SpecSet(6,200,200);
LED3.SpecSet(7,100,100);
// BARの属性設定
BAR1.SpecSet(9,3000);
BAR2.SpecSet(10,1000);
unsigned long msec;
while(1){
LED1.Blink();
LED2.Blink();
LED3.Blink();
msec = millis();
BAR1.update(msec);
BAR2.update(msec);
}
}
void loop() {
}

C++ のクラスでは、コンストラクタというインスタンス化の際に属性設定も同時に行える機能がある。今回は VBA との対比を重視し、敢えてコンストラクタは使わなかった。
オブジェクト指向には、本連載では扱わなかった機能や特徴があって奥深い。本連載はオブジェクト指向の概念を体得するのが目的であり、これ以上の深掘りをせずに連載を終える。