#include "Eventfun.h"
////////////////////////////////////
// definition for DigitalPin class
///////////////////////////////////
// define a class representing digital pin
template<typename T>
class DigitalPin {
protected:
int _pin; // pin number
bool _value; // last value read from the pin
unsigned long _msDebounce;
unsigned long _ms;
bool _debouncing;
public:
// declare event
typedef EventDelegate<T, bool> ChangeEvent;
ChangeEvent OnChange;
public:
// initialize DigitalPin object
DigitalPin(int pin, int pin_mode, int msDebounce = 0)
: _pin(pin), _msDebounce(msDebounce), _debouncing(false) {
pinMode(_pin, pin_mode);
if (pin_mode != OUTPUT) {
_value = digitalRead(_pin);
}
}
// read the pin value and only trigger the event if there is a change
void Update() {
auto value = digitalRead(_pin);
if (value != _value) {
if (_debouncing && millis() - _ms > _msDebounce)
{
_debouncing = false;
_value = value; // update to the new value
OnChange((T*)this, _value); // trigger event
}
else if (!_debouncing) {
_ms = millis();
_debouncing = true;
}
}
}
// accessor for _pin
int Pin() {
return _pin;
}
// for convenience overload () operator to set value
operator()(bool value) {
_value = value;
digitalWrite(_pin, value);
}
// for convenience overload bool operator to return value
operator bool() {
return _value;
}
};
// now that we have a class representing a digital pin
// we can create classes that use digital pin
// a button
class Button: public DigitalPin<Button> {
public:
Button(int pin) : DigitalPin(pin, INPUT_PULLUP, 100) {
}
};
// a LED
class Led: public DigitalPin<Led> {
public:
Led(int pin, Button& button) : DigitalPin(pin, OUTPUT) {
button.OnChange = Button::ChangeEvent(this, &Led::onButtonClick);
}
void onButtonClick(Button* sender, bool value) {
Serial.println("hello");
operator()(!value);
}
};
// it may look like too much for a simple project but when you have many
// interconnected components that need to react to changes and interact with one another
// then using classes with events may simplify your program:
//////////////////
// main program
/////////////////
Button redButton(12);
Button greenButton(2);
Led redLed(redButton.Pin() + 1, redButton);
Led greenLed(greenButton.Pin() + 1, greenButton);
void setup() {
Serial.begin(115200);;
}
void loop() {
redButton.Update();
greenButton.Update();
}