Last active
April 23, 2024 09:10
-
-
Save AFCMS/91d2bc9bcf197ece8389906e5108d8d9 to your computer and use it in GitHub Desktop.
Arduino Input System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SPDX-FileCopyrightText: 2024 AFCMS <afcm.contact@gmail.com> | |
SPDX-License-Identifier: GPL-3.0-or-later | |
*/ | |
#include <Arduino.h> | |
#include "input.hpp" | |
namespace utils | |
{ | |
namespace input | |
{ | |
void IRAM_ATTR InputSystem::ISR(void *isrData) | |
{ | |
ButtonDataISR *data = (ButtonDataISR *)isrData; | |
uint8_t btn = data->button; | |
InputSystem *inputSystem = data->inputSystem; | |
if (millis() - inputSystem->getButtonLastMillis(btn) > BUTTON_DEBOUNCE) | |
{ // Software debouncing button | |
inputSystem->buttonPressedQueue.insert(btn); | |
} | |
inputSystem->setButtonLastMillis(btn, millis()); | |
}; | |
InputSystem::InputSystem() | |
{ | |
buttons = std::vector<uint8_t>(); | |
buttonsLastMillis = std::map<uint8_t, unsigned long>(); | |
buttonPressedQueue = std::set<uint8_t>(); | |
buttonsData = std::map<uint8_t, ButtonDataISR>(); | |
}; | |
InputSystem::InputSystem(std::vector<uint8_t> _buttons) | |
{ | |
buttons = _buttons; | |
buttonsLastMillis = std::map<uint8_t, unsigned long>(); | |
buttonPressedQueue = std::set<uint8_t>(); | |
buttonsData = std::map<uint8_t, ButtonDataISR>(); | |
for (int i = 0; i < buttons.size(); i++) | |
{ | |
buttonsData[buttons[i]] = {buttons[i], this}; | |
} | |
}; | |
void InputSystem::begin() | |
{ | |
for (int i = 0; i < buttons.size(); i++) | |
{ | |
pinMode(buttons[i], INPUT_PULLUP); | |
buttonsLastMillis[buttons[i]] = 0; | |
// volatile ButtonDataISR data = {buttons[i], this}; // Create a separate ButtonDataISR object for each button | |
attachInterruptArg(buttons[i], &InputSystem::ISR, (void *)(&buttonsData[i]), RISING); | |
} | |
}; | |
std::set<uint8_t> InputSystem::step() | |
{ | |
std::set<uint8_t> pressedButtons = buttonPressedQueue; | |
buttonPressedQueue.clear(); | |
return pressedButtons; | |
}; | |
std::vector<uint8_t> InputSystem::getButtons() | |
{ | |
return buttons; | |
}; | |
unsigned long InputSystem::getButtonLastMillis(uint8_t button) | |
{ | |
return buttonsLastMillis[button]; | |
}; | |
void InputSystem::setButtonLastMillis(uint8_t button, unsigned long millis) | |
{ | |
buttonsLastMillis[button] = millis; | |
}; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SPDX-FileCopyrightText: 2024 AFCMS <afcm.contact@gmail.com> | |
SPDX-License-Identifier: GPL-3.0-or-later | |
*/ | |
#include <Arduino.h> | |
#include <vector> | |
#include <map> | |
#include <set> | |
namespace utils | |
{ | |
namespace input | |
{ | |
class InputSystem; // Forward declaration | |
struct ButtonDataISR | |
{ | |
uint8_t button; | |
InputSystem *inputSystem; | |
}; | |
/** | |
* A class to handle button presses and debouncing | |
*/ | |
class InputSystem | |
{ | |
private: | |
std::vector<uint8_t> buttons; | |
std::map<uint8_t, unsigned long> buttonsLastMillis; | |
std::set<uint8_t> buttonPressedQueue; | |
std::map<uint8_t, ButtonDataISR> buttonsData; | |
static void ISR(void *buttonPin); | |
unsigned long getButtonLastMillis(uint8_t button); | |
void setButtonLastMillis(uint8_t button, unsigned long millis); | |
public: | |
InputSystem(); | |
/** | |
* Construct a new Input System object | |
* | |
* @param _buttons A vector of button pins | |
*/ | |
InputSystem(std::vector<uint8_t> _buttons); | |
/** | |
* Initialize the input system | |
* | |
* This method should be called in the setup() function | |
* | |
* It initializes the pins and the interrupts | |
*/ | |
void begin(); | |
/** | |
* Update the input system | |
* | |
* This method should be called in the loop() function | |
* | |
* Iteturns a set of the buttons that have been pressed | |
* | |
* @return A set of the buttons that have been pressed | |
*/ | |
std::set<uint8_t> step(); | |
/** | |
* Get the registered buttons | |
* | |
* @return A vector of the button pins | |
*/ | |
std::vector<uint8_t> getButtons(); | |
/** | |
* The debounce time for the buttons | |
*/ | |
static const unsigned long BUTTON_DEBOUNCE = 10; | |
}; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SPDX-FileCopyrightText: 2024 AFCMS <afcm.contact@gmail.com> | |
SPDX-License-Identifier: GPL-3.0-or-later | |
*/ | |
#include "input.hpp" | |
// name = pins | |
enum Buttons | |
{ | |
BUTTON_A = 32, | |
}; | |
utils::input::InputSystem inputSystem({BUTTON_A}); | |
void setup() | |
{ | |
inputSystem.begin(); | |
} | |
void loop() | |
{ | |
// Buttons Input | |
auto pressedButtons = inputSystem.step(); | |
for (auto it = pressedButtons.begin(); it != pressedButtons.end(); ++it) | |
{ | |
switch (*it) | |
{ | |
case BUTTON_A: | |
// Button A pressed | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment