Update InputManager to record any button hold time

This commit is contained in:
Dave Allie
2025-12-06 11:32:45 +11:00
parent 9b7d94f06e
commit 06b4cf0c71
3 changed files with 134 additions and 58 deletions

View File

@@ -1,7 +1,21 @@
#include "InputManager.h"
const int InputManager::ADC_THRESHOLDS_1[] = {3470, 2655, 1470, 3};
const int InputManager::ADC_THRESHOLDS_2[] = {2205, 3};
// Recorded ADC values from real devices
// BACK CONF LEFT RGHT UP DOWN
// 3597 2760 1530 6 2300 6
// 3470 2666 1480 6 2222 5
// 3470 2655 1470 3 2205 3
// Averages
// BACK CONF LEFT RGHT UP DOWN
// 3512 2694 1493 5 2242 5
// Setup ranges, if ADC value is between value `i` and `i + 1`, button `i` is being pressed
// These ranges are based on real world values above, and are much more tolerant of different
// devices than a fixed threshold check
// These values are calculated by taking the midpoint of the pairs of averaged values above
const int InputManager::ADC_RANGES_1[] = {ADC_NO_BUTTON, 3100, 2090, 750, INT32_MIN};
const int InputManager::ADC_RANGES_2[] = {ADC_NO_BUTTON, 1120, INT32_MIN};
const char* InputManager::BUTTON_NAMES[] = {"Back", "Confirm", "Left", "Right", "Up", "Down", "Power"};
InputManager::InputManager()
@@ -10,8 +24,8 @@ InputManager::InputManager()
pressedEvents(0),
releasedEvents(0),
lastDebounceTime(0),
powerButtonPressStart(0),
powerButtonWasPressed(false) {}
buttonPressStart(0),
buttonPressFinish(0) {}
void InputManager::begin() {
pinMode(BUTTON_ADC_PIN_1, INPUT);
@@ -20,13 +34,9 @@ void InputManager::begin() {
analogSetAttenuation(ADC_11db);
}
int InputManager::getButtonFromADC(int adcValue, const int thresholds[], int numButtons) {
if (adcValue > ADC_NO_BUTTON) {
return -1;
}
int InputManager::getButtonFromADC(const int adcValue, const int ranges[], const int numButtons) {
for (int i = 0; i < numButtons; i++) {
if (abs(adcValue - thresholds[i]) < ADC_TOLERANCE) {
if (ranges[i + 1] < adcValue && adcValue <= ranges[i]) {
return i;
}
}
@@ -38,15 +48,15 @@ uint8_t InputManager::getState() {
uint8_t state = 0;
// Read GPIO1 buttons
int adcValue1 = analogRead(BUTTON_ADC_PIN_1);
int button1 = getButtonFromADC(adcValue1, ADC_THRESHOLDS_1, NUM_BUTTONS_1);
const int adcValue1 = analogRead(BUTTON_ADC_PIN_1);
const int button1 = getButtonFromADC(adcValue1, ADC_RANGES_1, NUM_BUTTONS_1);
if (button1 >= 0) {
state |= (1 << button1);
}
// Read GPIO2 buttons
int adcValue2 = analogRead(BUTTON_ADC_PIN_2);
int button2 = getButtonFromADC(adcValue2, ADC_THRESHOLDS_2, NUM_BUTTONS_2);
const int adcValue2 = analogRead(BUTTON_ADC_PIN_2);
const int button2 = getButtonFromADC(adcValue2, ADC_RANGES_2, NUM_BUTTONS_2);
if (button2 >= 0) {
state |= (1 << (button2 + 4));
}
@@ -60,8 +70,8 @@ uint8_t InputManager::getState() {
}
void InputManager::update() {
unsigned long currentTime = millis();
uint8_t state = getState();
const unsigned long currentTime = millis();
const uint8_t state = getState();
// Always clear events first
pressedEvents = 0;
@@ -78,39 +88,58 @@ void InputManager::update() {
// Calculate pressed and released events
pressedEvents = state & ~currentState;
releasedEvents = currentState & ~state;
currentState = state;
// Track power button press timing
if (pressedEvents & (1 << BTN_POWER)) {
powerButtonPressStart = currentTime;
powerButtonWasPressed = true;
// If pressing buttons and wasn't before, start recording time
if (pressedEvents > 0 && currentState == 0) {
buttonPressStart = currentTime;
}
if (releasedEvents & (1 << BTN_POWER)) {
powerButtonWasPressed = false;
// If releasing a button and no other buttons being pressed, record finish time
if (releasedEvents > 0 && state == 0) {
buttonPressFinish = currentTime;
}
currentState = state;
}
}
}
bool InputManager::isPressed(uint8_t buttonIndex) {
bool InputManager::isPressed(const uint8_t buttonIndex) const {
return currentState & (1 << buttonIndex);
}
bool InputManager::wasPressed(uint8_t buttonIndex) {
bool InputManager::wasPressed(const uint8_t buttonIndex) const {
return pressedEvents & (1 << buttonIndex);
}
bool InputManager::wasReleased(uint8_t buttonIndex) {
bool InputManager::wasAnyPressed() const {
return pressedEvents > 0;
}
bool InputManager::wasReleased(const uint8_t buttonIndex) const {
return releasedEvents & (1 << buttonIndex);
}
const char* InputManager::getButtonName(uint8_t buttonIndex) {
bool InputManager::wasAnyReleased() const {
return releasedEvents > 0;
}
unsigned long InputManager::getHeldTime() const {
// Still hold a button
if (currentState > 0) {
return millis() - buttonPressStart;
}
return buttonPressFinish - buttonPressStart;
}
const char* InputManager::getButtonName(const uint8_t buttonIndex) {
if (buttonIndex <= BTN_POWER) {
return BUTTON_NAMES[buttonIndex];
}
return "Unknown";
}
bool InputManager::isPowerButtonPressed() {
bool InputManager::isPowerButtonPressed() const {
return isPressed(BTN_POWER);
}