Refactor button and LED handling

This commit is contained in:
Andrea Baccega 2024-01-26 10:57:05 +01:00
parent 981cef2300
commit e76fe26042
9 changed files with 159 additions and 171 deletions

View File

@ -5,6 +5,7 @@
// Constructor
Button::Button(ButtonKind kind, uint8_t pin) : kind(kind), pin(pin), state(ButtonState::IDLE) {
pinMode(pin, INPUT_PULLUP);
this->change = new ButtonStateChange(this->kind, ButtonState::IDLE, ButtonState::IDLE);
lastStateChangeTime = 0;
}
@ -20,13 +21,21 @@ ButtonState Button::getState() {
return this->state;
}
ButtonState Button::setState(ButtonState state) {
lastStateChangeTime = millis();
this->state = state;
return this->state;
ButtonStateChange* Button::lastChange() {
return this->change;
}
void Button::loop() {
void Button::setState(ButtonState state) {
if (this->state != state) {
delete this->change; // clear memory
this->change = new ButtonStateChange(this->kind, this->state, state);
lastStateChangeTime = millis();
this->state = state;
}
}
bool Button::loop() {
ButtonState prev = this->state;
if (digitalRead(this->pin) == LOW) {
if (this->state == ButtonState::IDLE && millis() - lastStateChangeTime > 50) {
this->setState(ButtonState::PRESSED);
@ -37,4 +46,7 @@ void Button::loop() {
if (this->state == ButtonState::RELEASED && millis() - lastStateChangeTime > 50) {
this->setState(ButtonState::IDLE);
}
// Return true if the state changed
return prev != this->state;
}

View File

@ -1,4 +1,4 @@
#include "__enums.h"
#include "base.h"
#include <Arduino.h>
class Button
@ -10,8 +10,11 @@ public:
ButtonKind getKind();
uint8_t getPin();
ButtonState getState();
ButtonState setState(ButtonState state);
void loop();
ButtonStateChange* lastChange();
void setState(ButtonState state);
/// @brief Call this method in the main loop to update the button state.
/// @return true if the button state changed, false otherwise.
bool loop();
private :
@ -19,4 +22,5 @@ public:
ButtonKind kind;
uint8_t pin;
ButtonState state;
ButtonStateChange* change;
};

View File

@ -1,132 +1,30 @@
#include "Buttons.h"
extern bool yellowLedON;
Button *__buttons[4];
Button *__buttons[4];
ButtonKind Buttons::getPressedButton()
void Buttons::setup()
{
__buttons[ButtonKind::UP] = new Button(ButtonKind::UP, upButton);
__buttons[ButtonKind::DOWN] = new Button(ButtonKind::DOWN, downButton);
__buttons[ButtonKind::BACK] = new Button(ButtonKind::BACK, backButton);
__buttons[ButtonKind::SELECT] = new Button(ButtonKind::SELECT, selectButton);
}
/**
* Handle buttons state changes and return first button state change that occurred.
*/
ButtonStateChange* Buttons::handleButtons()
{
for (int i = 0; i < 4; i++)
{
if (__buttons[i]->getState() == ButtonState::PRESSED)
// If a state change occurred, print it out and return the button that changed
if ( __buttons[i]->loop())
{
return __buttons[i]->getKind();
ButtonStateChange *change = __buttons[i]->lastChange();
Serial.println(STATECHANGE_STR((*change)));
return change;
}
}
return NONE;
}
Buttons::Buttons()
{
initializeButtons();
}
void Buttons::initializeButtons()
{
__buttons[0] = new Button(ButtonKind::UP, upButton);
__buttons[1] = new Button(ButtonKind::DOWN, downButton);
__buttons[2] = new Button(ButtonKind::BACK, backButton);
__buttons[3] = new Button(ButtonKind::SELECT, selectButton);
}
Button** Buttons::getAllButtons()
{
return __buttons;
}
void Buttons::handleButtonLEDs()
{
for (int i = 0; i < 4; i++)
{
if (__buttons[i]->getState() == ButtonState::PRESSED)
{
switch (__buttons[i]->getKind())
{
case ButtonKind::UP:
Serial.println("UP");
if (!yellowLedON)
{
digitalWrite(yellowLED, HIGH);
yellowLedON = true;
}
break;
case ButtonKind::DOWN:
Serial.println("DOWN");
if (!yellowLedON)
{
digitalWrite(yellowLED, HIGH);
yellowLedON = true;
}
break;
case ButtonKind::BACK:
Serial.println("BACK");
digitalWrite(redLED, HIGH);
break;
case ButtonKind::SELECT:
Serial.println("SELECT");
analogWrite(greenLED, 20);
break;
default:
break;
}
}
else if (__buttons[i]->getState() == ButtonState::RELEASED)
{
switch (__buttons[i]->getKind())
{
case ButtonKind::BACK:
digitalWrite(redLED, LOW);
break;
case ButtonKind::SELECT:
digitalWrite(greenLED, LOW);
break;
case ButtonKind::UP:
if (yellowLedON)
{
digitalWrite(yellowLED, LOW);
yellowLedON = false;
}
break;
case ButtonKind::DOWN:
if (yellowLedON)
{
digitalWrite(yellowLED, LOW);
yellowLedON = false;
}
break;
default:
break;
}
}
}
}
ButtonKind Buttons::handleButtons()
{
for (int i = 0; i < 4; i++)
{
__buttons[i]->loop();
}
return getPressedButton();
return NULL;
}

View File

@ -17,15 +17,10 @@ class Buttons
{
public:
// Constructor
Buttons();
Buttons() {};
ButtonKind handleButtons();
ButtonKind getPressedButton();
void static initializeButtons();
Button** getAllButtons();
void handleButtonLEDs();
ButtonStateChange* handleButtons();
void setup();
};

View File

@ -1,21 +0,0 @@
#ifndef __enums_h__
#define __enums_h__
enum ButtonState
{
IDLE,
PRESSED,
RELEASED
};
enum ButtonKind
{
UP,
DOWN,
BACK,
SELECT,
NONE
};
#endif

34
src/buttons/base.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef __enums_h__
#define __enums_h__
enum ButtonState
{
IDLE,
PRESSED,
RELEASED
};
enum ButtonKind
{
UP,
DOWN,
BACK,
SELECT,
NONE
};
#define KIND_STR(kind) (kind == ButtonKind::UP ? "UP" : kind == ButtonKind::DOWN ? "DOWN" : kind == ButtonKind::BACK ? "BACK" : kind == ButtonKind::SELECT ? "SELECT" : "NONE")
#define STATE_STR(state) (state == ButtonState::IDLE ? "IDLE" : state == ButtonState::PRESSED ? "PRESSED" : "RELEASED")
#define STATECHANGE_STR(change) (String("ButtonStateChange: kind=") + KIND_STR(change.kind) + ", " + STATE_STR(change.from) + " -> " + STATE_STR(change.to))
class ButtonStateChange {
public:
ButtonStateChange(ButtonKind kind, ButtonState from, ButtonState to) : kind(kind), from(from), to(to) {}
ButtonKind kind;
ButtonState from;
ButtonState to;
};
#endif

54
src/leds/Leds.cpp Normal file
View File

@ -0,0 +1,54 @@
#include "Leds.h"
#include <Arduino.h>
bool yellowLEDUPOn = false;
bool yellowLEDSeleOn = false;
LEDS::LEDS()
{
// Constructor implementation
}
void LEDS::setup()
{
pinMode(yellowLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
}
void LEDS::handleButtonStateChange(ButtonStateChange change)
{
switch (change.kind) {
case ButtonKind::UP:
if (change.to == ButtonState::PRESSED) {
digitalWrite(yellowLED, HIGH);
} else if (!yellowLEDSeleOn) {
digitalWrite(yellowLED, LOW);
}
yellowLEDUPOn = change.to == ButtonState::PRESSED;
break;
case ButtonKind::DOWN:
if (change.to == ButtonState::PRESSED) {
digitalWrite(greenLED, HIGH);
} else {
digitalWrite(greenLED, LOW);
}
break;
case ButtonKind::BACK:
if (change.to == ButtonState::PRESSED) {
digitalWrite(redLED, HIGH);
} else {
digitalWrite(redLED, LOW);
}
break;
case ButtonKind::SELECT:
if (change.to == ButtonState::PRESSED) {
digitalWrite(yellowLED, HIGH);
} else if (!yellowLEDUPOn) {
digitalWrite(yellowLED, LOW);
}
yellowLEDSeleOn = change.to == ButtonState::PRESSED;
break;
default:
break;
}
}

View File

@ -1,4 +1,18 @@
#ifndef __leds_h__
#define __leds_h__
#include "../buttons/base.h"
//If you didnt solder the LEDS in order, change the order here
#define yellowLED 18
#define greenLED 19
#define redLED 20
#define redLED 20
class LEDS
{
public:
LEDS();
void setup();
void handleButtonStateChange(ButtonStateChange change);
};
#endif

View File

@ -40,10 +40,7 @@ Thermistor thermistor6(THERMISTOR6_PIN, 9000);
// Initialize the buttons
Buttons buttons = Buttons();
// Define global for the Yellow LED because both up and down buttons use it
bool yellowLedON = false;
LEDS leds = LEDS();
// Declare the PID
ArduPID PID;
@ -58,10 +55,9 @@ void setup()
// Set PWM frequency to 64 kHz
analogWriteFrequency(64);
pinMode(yellowLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
buttons.setup();
leds.setup();
Serial.println("Starting LCD");
@ -95,17 +91,19 @@ void loop()
{
// Return the button that was pressed
ButtonKind k = buttons.handleButtons();
// Handle the buttons outside the main loop, only put functions in here for sanity and flow purposes
buttons.handleButtonLEDs();
ButtonStateChange* k = buttons.handleButtons();
if (k != NULL) {
leds.handleButtonStateChange(*k);
}
float sysVoltage = analogRef.calculateSystemVoltage();
float inputVoltage = analogRef.calculateInputVoltage();
int thermistor1Temp = thermistor1.getTemperature();
// Print the system voltage on the tft
return;
display.clearDisplay();
Serial.print("Thermistor 1: ");
Serial.println(thermistor1Temp);