前提
はるか昔に自作したIO-Kitというライブラリの布教です。
最近思うこと
digitalWrite()ってあんまよくないですよね。(思想強い)
何がよくないかというと、
- ピン自体を定義していない
- 記述が煩雑
- 入出力定義が曖昧
この三つ目は特に重要だと思ってて、ハイインピーダンス状態に保持しなければならないピンをLOWやHIGHにdigitalWriteしてしまったら普通に事故りかねないのでこれは結構重要です。
間違えてOUTPUTに設定していたピンでdigitalReadしてたから動かなかったー、じゃなくてdigitalReadできる構造にプログラムを作るべきじゃない(思想強い2回目)
簡単な思想
全てインスタンス作って定義しましょう!!というスタンスです。mbedに思想はかなり近いと思います。詳しい使い方はreadme見てもらえればと思いますが、概要だけ簡単に紹介します。
とりあえずライブラリをインクルードします。PlatformIOの方はライブラリマネージャから簡単にインストールできます。
#include <IO-Kit.h>
出力はこのようにして使います。
#include <IO-Kit.h>
Output LED = 13;
Output LED_Arr[] = {10, 4};
void setup(){}
void loop(){
LED = HIGH;
delay(500);
LED = LOW;
LED_Arr[1] = LOW;
delay(500);
}
これを使うと、Lチカがこのようにかけます。めっちゃ綺麗じゃないですか?
#include <IO-Kit.h>
Output LED = 13;
void setup(){}
void loop(){
LED = !LED; //裏返す
delay(500);
}
ちなみにInputも同じように使えます。
#include <IO-Kit.h>
Input SWITCH = 2;
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println(SWITCH);
}
内部実装
Outputのクラスはこんな感じになっています。operatorが鍵です。
bool _pwmExpはSTM32だとPWMの仕様がちょっと異なるのでこのように付け足しています。
class Output {
public:
Output(int pin);
float operator=(float val);
int operator<<=(int val);
byte raw(void);
operator float();
private:
int _pinNumber;
byte _pinStatus;
void set(bool val);
void setPWM(int val);
#ifdef _STM32_DEF_
bool _pwmExp = false;
#endif
};
そしてこの内部はこのようになっています。ただのメンバ関数の説明は省きますが、代入演算子のオーバーロードって技を使って=という記号にこちらの関数を割り当てています。
float Output::operator=(float val) {
val = constrain(val, 0.0, 1.0);
if (val == 1.0 || val == 0.0) {
this->set(bool(val));
} else {
this->setPWM(round(val * 255));
}
return val;
}
終わりに
みんな使ってください!!!