sTodo-m5paper-client/libraries/FastLED/examples/LuminescentGrand/arduino/buttons.h
2025-06-30 20:47:33 +02:00

157 lines
No EOL
3.4 KiB
C++

#pragma once
#include <Arduino.h>
#include "fl/ui.h"
#include "fl/dbg.h"
using namespace fl;
// Done by hand. Old school.
class ToggleButton {
public:
ToggleButton(int pin) : pin_(pin), on_(false), debounce_timestamp_(0), changed_(false) {
pinMode(pin_, OUTPUT);
digitalWrite(pin_, LOW);
delay(1);
}
// true - button is pressed.
bool Read() {
Update(millis());
return changed_;
}
void Update(uint32_t time_now) {
if ((time_now - debounce_timestamp_) < 150) {
changed_ = false;
return;
}
int val = Read_Internal();
changed_ = on_ != val;
if (changed_) { // Has the toggle switch changed?
on_ = val; // Set the new toggle switch value.
// Protect against debouncing artifacts by putting a 200ms delay from the
// last time the value changed.
if ((time_now - debounce_timestamp_) > 150) {
//++curr_val_; // ... and increment the value.
debounce_timestamp_ = time_now;
}
}
}
private:
bool Read_Internal() {
// Toggle the pin back to INPUT and take a reading.
pinMode(pin_, INPUT);
bool on = (digitalRead(pin_) == HIGH);
// Switch the pin back to output so that we can enable the
// pulldown resister.
pinMode(pin_, OUTPUT);
digitalWrite(pin_, LOW);
return on;
}
int pin_;
bool on_;
uint32_t debounce_timestamp_;
bool changed_;
};
// This is the new type that is built into the midi shield.
class MidiShieldButton {
public:
MidiShieldButton(int pin) : pin_(pin) {
pinMode(pin_, INPUT_PULLUP);
delay(1);
}
bool Read() {
// Toggle the pin back to INPUT and take a reading.
int val = digitalRead(pin_) == LOW;
return val;
}
private:
int pin_;
};
class Potentiometer {
public:
Potentiometer(int sensor_pin) : sensor_pin_(sensor_pin) {}
float Read() {
float avg = 0.0;
// Filter by reading the value multiple times and taking
// the average.
for (int i = 0; i < 8; ++i) {
avg += analogRead(sensor_pin_);
}
avg = avg / 8.0f;
return avg;
}
private:
int sensor_pin_;
};
typedef MidiShieldButton DigitalButton;
class CountingButton {
public:
explicit CountingButton(int but_pin) : button_(but_pin), curr_val_(0), mButton("Counting UIButton") {
debounce_timestamp_ = millis();
on_ = Read();
}
void Update(uint32_t time_now) {
bool clicked = mButton.clicked();
bool val = Read() || mButton.clicked();
bool changed = val != on_;
if (clicked) {
++curr_val_;
debounce_timestamp_ = time_now;
return;
}
if (changed) { // Has the toggle switch changed?
on_ = val; // Set the new toggle switch value.
// Protect against debouncing artifacts by putting a 200ms delay from the
// last time the value changed.
if ((time_now - debounce_timestamp_) > 16) {
if (on_) {
++curr_val_; // ... and increment the value.
}
debounce_timestamp_ = time_now;
}
}
}
int curr_val() const { return curr_val_; }
private:
bool Read() {
return button_.Read();
}
DigitalButton button_;
bool on_;
int curr_val_;
unsigned long debounce_timestamp_;
UIButton mButton;
};
class ColorSelector {
public:
ColorSelector(int sensor_pin) : but_(sensor_pin) {}
void Update() {
but_.Update(millis());
}
int curr_val() const { return but_.curr_val() % 7; }
private:
CountingButton but_;
};