#include <FastLED.h>
#include <List.hpp>//https://github.com/nkaaf/Arduino-List
#define NUM_LEDS 32
#define DATA_PIN 6
#define BRIGHTNESS 255
CRGB leds[NUM_LEDS];
class RZButton
{
public:
RZButton(uint8_t _buttonPin, int _pull_mode = INPUT_PULLUP);
bool isPressed();
bool wasPressed();
bool stateChanged();
bool uniquePress();
bool longPress();
unsigned char multiclick();
unsigned long continuousPressTime();
void clearFirstPress();
void setMulticlickTimeThreshold(unsigned int time_threshold_milliseconds);
void setLongPressTimeThreshold(unsigned int time_threshold_milliseconds);
private:
uint8_t buttonPin;
bool lastStatus;
int mode;
unsigned long lastChange, firstPress, lastPress;
unsigned char multiclickCounter;
unsigned int multiclickTimeThreshold = 3000;
unsigned int longPressTimeThreshold = 2000;
};
class Driver
{
public:
Driver(uint8_t _buttonPin, unsigned char _outputLED);
~Driver() {
delete btn;
}
RZButton *btn;
unsigned char outputLED;
void run();
static void runAll() {
for (unsigned char i = 0; i < instances.getSize(); i++) {
instances.get(i)->run();
}
}
static List<Driver*> instances;
};
List<Driver*> Driver::instances;
Driver parkingInput(4, 0);
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED.show();
}
void loop() {
Driver::runAll();
//parkingInput.runAll();
}
void Driver::run() {
if (btn->uniquePress()) {
leds[outputLED] = CRGB::White;
FastLED.show();
} else if (!btn->isPressed() && !btn->wasPressed()) {
leds[outputLED] = CRGB::Black;
FastLED.show();
}
}
Driver::Driver(uint8_t _buttonPin, unsigned char _outputLED) {
btn = new RZButton(_buttonPin, INPUT);
outputLED = _outputLED;
instances.add(this);
}
RZButton::RZButton(uint8_t _buttonPin, int _pull_mode) {
buttonPin = _buttonPin;
mode = _pull_mode;
lastStatus = 0;
lastChange = 0;
firstPress = 0;
lastPress = 0;
multiclickCounter = 0;
pinMode(buttonPin, mode);
}
bool RZButton::isPressed() {
if (mode == INPUT_PULLUP) {
return !digitalRead(buttonPin);
} else {
return digitalRead(buttonPin);
}
}
bool RZButton::wasPressed() {
return lastStatus;
}
bool RZButton::stateChanged() {
bool currentStatus = isPressed();
if (currentStatus != lastStatus && millis() - lastChange > 15) {
lastStatus = currentStatus;
lastChange = millis();
return 1;
}
return 0;
}
bool RZButton::uniquePress() {
return stateChanged() && lastStatus;
}
bool RZButton::longPress() {
bool currentStatus = isPressed();
if (currentStatus && firstPress == 0)
firstPress = millis();
if (!currentStatus && firstPress != 0 && millis() - firstPress > longPressTimeThreshold) {
firstPress = lastPress = multiclickCounter = 0;
return 1;
}
if (!currentStatus) firstPress = 0;
return 0;
}
unsigned char RZButton::multiclick() {
unsigned char returnThis = 0;
if (uniquePress()) {
lastPress = millis();
multiclickCounter++;
}
if (multiclickCounter != 0 && lastPress != 0 && millis() - lastPress > multiclickTimeThreshold && !wasPressed() && firstPress == 0) {
returnThis = multiclickCounter;
lastPress = multiclickCounter = 0;
}
return returnThis;
}
unsigned long RZButton::continuousPressTime() {
if (isPressed()) {
if (firstPress == 0) {
firstPress = millis();
}
return millis() - firstPress;
} else {
firstPress = 0;
}
return 0;
}
void RZButton::clearFirstPress() {
firstPress = multiclickCounter = 0;
}
void RZButton::setMulticlickTimeThreshold(unsigned int time_threshold_milliseconds) {
multiclickTimeThreshold = time_threshold_milliseconds;
}
void RZButton::setLongPressTimeThreshold(unsigned int time_threshold_milliseconds) {
longPressTimeThreshold = time_threshold_milliseconds;
}