ArduinoでC++で作った自作ライブラリを使う方法
ここではArduino開発において、C++で外部ファイルにクラスを作り、その自作ライブラリを読み込んでビルドする方法を解説します。 具体的には、前回製作した匂いチェッカーのプログラムを、C++で外部ファイルのクラスに移し、それをメインプログラムで読み込んで動作させてみます。こうすることで、プログラムが整理され読みやすくなり、保守・メンテナンスが楽になります。 なお、前回作った匂いチェッカーはArduino互換機のESP32 PICOが使われた __M5StickC PLUS__を使用しました。プログラム中にM5Stack系のライブラリ関数が使われますが、Arudinoでも大枠は同じやり方で可能ですので、ぜひ参考にしてみて下さい。
▼ 半導体不足のため入手困難な場合は、ひとつ前のモデルのM5StickCも選択に入れてみてください。
C++でArduinoの自作ライブファイルをつくる
C++の新規ファイルの追加
まず、Arduino IDEで同じプロジェクト内に新規ファイルを追加するには、画像のように「▼」ボタンを押してファイルを作成します。 「New Tab」をクリックすると、ファイル名を入力できますので、C++のファイル名を入力しましょう。ここでは「GasSensor.h」「GasSensor.cpp」の二つのファイルを作りました。
.hヘッダファイル
ヘッダファイルでは変数名や関数名の登録をします。外部からアクセスされる関数などにはpublicを、内部のみで使用する変数にはprivateをしていしてあげます。
/*
GasSensor.h - Library for Gas sensor.
Created by Toshihiko Arai, July 6, 2021.
Copylight https://101010.fun
*/
#ifndef GasSensor_h // 2重インクルードを防ぐ
#define GasSensor_h
#include "M5StickCPlus.h"
class GasSensor {
public:
GasSensor(); // ←コンストラクタと合わせる
void setup();
void readSensor();
private :
bool _isSetuped;
}; // ←セミコロン忘れずに
#endif
コンストラクタはクラスからインスタンスを作るときに呼び出されます。初期化するときに引数を渡したい場合は、関数と同様に括弧内に引数を記述します。
.cpp実装ファイル
次に、実装ファイルでコンストラクタや関数などの内容を書いていきます。先ほどのヘッダファイルをインクルードしましょう。 書き方としては クラス名::関数名 のように二つのコロンで繋げてあげるのがC++の特徴となってます。 それ以外の内容は、前回の匂いチェッカーのプログラムとほとんど同じです。inoファイルのsetup()とloop()でやっていたことを、GasSensor::setup()とGasSensor::readSensor()へ書き写しただけです。
/*
GasSensor.cpp - Library for Gas sensor.
Created by Toshihiko Arai, July 6, 2021.
Copylight https://101010.fun
*/
#include "GasSensor.h"
#define PIN_HEATER 0
#define PIN_SENSOR 26
#define PIN_OUTPUT 36
uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue){
return ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
}
const int SMELL_BAD = 1000;
const int SMELL_NORMAL = 4095;
const int SMELL_DIFF = SMELL_NORMAL - SMELL_BAD; // // 2500 - 2000
GasSensor::GasSensor() { // コンストラクタ
}
void GasSensor::setup() {
if (!_isSetuped) {
// M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextColor(WHITE);
pinMode(PIN_HEATER,OUTPUT);
pinMode(PIN_SENSOR,OUTPUT);
digitalWrite(PIN_HEATER,LOW); // Heater Off
digitalWrite(PIN_SENSOR,LOW); // Sensor Pullup Off
pinMode(PIN_OUTPUT, INPUT);
gpio_pulldown_dis(GPIO_NUM_25); // Disable pull-down on GPIO.
gpio_pullup_dis(GPIO_NUM_25); // Disable pull-up on GPIO.
_isSetuped = true;
Serial.println("GasSensor 'setup' was completed!");
}
}
void GasSensor::readSensor() {
int val = 0;
int val_origin = 0;
float rate = 0.0;
delay(237);
digitalWrite(PIN_SENSOR,HIGH); // Sensor Pullup On
delay(3);
val = analogRead(PIN_OUTPUT); // Get Sensor Voltage
delay(2);
digitalWrite(PIN_SENSOR,LOW); // Sensor Pullup Off
digitalWrite(PIN_HEATER,HIGH); // Heater On
delay(8);
digitalWrite(PIN_HEATER,LOW); // Heater Off
// Serial.println(val);
val_origin = val;
if (SMELL_BAD > val) {
val = SMELL_BAD;
} else if (SMELL_NORMAL < val) {
val = SMELL_NORMAL;
}
val -= SMELL_BAD;
rate = float(val) / float(SMELL_DIFF);
Serial.println(rate);
int red = int((1.0 - rate) * 255.0);
int green = int(rate * 255.0);
// Serial.println(red);
M5.Lcd.fillScreen(getColor(red,green,0));
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(10, 10);
M5.Lcd.printf("%d", val_origin);
M5.Lcd.setTextSize(5);
M5.Lcd.setCursor(35, 100);
M5.Lcd.printf("%d", (int)(rate * 100.0));
}
.inoメインプログラムで読み込んでアップロード
最後にメインプログラムの内容を書き込みます。先ほど作った、C++の自作ライブラリファイルGasSensor.hをインクルードしましょう。 GasSensor gasSensor = GasSensor(); でクラスのインスタンスを作成します。 ここではBボタンが押された時、初めて匂いチェッカーのプログラムを起動するようにしてます。また今後、複数のライブラリを追加して切り替えられるように、enumで管理してみました。外部ライブラリにすることで、非常に管理しやすくなり機能追加もしやすくなりました。また、何より、別のプロジェクトでも自作ライラリを使いまわせるようになります。ちょっとした資産になるわけです。
#include <M5StickCPlus.h>
#include "GasSensor.h"
enum project_num {
GAS_SENSOR = 1,
};
int selected_num = 0;
GasSensor gasSensor = GasSensor();
void setup() {
// put your setup code here, to run once:
M5.begin();
M5.Axp.ScreenBreath(9);
Serial.begin(115200);
}
void loop() {
M5.update(); // Buttonの状態更新のため必要
if(M5.BtnB.wasPressed()){
selected_num++;
if (selected_num > 1) {
selected_num = 0;
}
switch (selected_num) {
case GAS_SENSOR:
gasSensor.setup();
break;
}
}
switch (selected_num) {
case GAS_SENSOR:
gasSensor.readSensor();
break;
}
}
Visual Studino CodeでArduino開発をはじめよう
さて、ここまででArduino IDEを使って作業を行いました。実際やってみるとArduino IDEでは非常にやりにくいです。C++を書いたり複数ファイルを管理したりするには、Arduino IDEでは限界があるでしょう。 そこで、インテリセンスやエクスプローラーが充実しているVisual Studino CodeでArduino開発を行いましょう。VS Codeでは、Microsoftが拡張機能にArduinoライブラリを出してます。それを使えばVS Codeからスケッチのアップロードなどが行えてとても快適な開発環境を構築できます。
詳しいやり方はこちらに書きましたので、ぜひ参考にしてみて下さい。
他にもArduino開発の他の選択肢として、PlatformIOを使う方法もありますので調べてみて下さい。