Clicking one button and debounce works now
This commit is contained in:
parent
5bce8d78c0
commit
72fded1f7b
12 changed files with 105 additions and 31 deletions
|
@ -2,14 +2,15 @@
|
|||
#include "src/game_manager.hpp"
|
||||
#include "src/randomiser.hpp"
|
||||
|
||||
Debugger* debugger;
|
||||
Input* input;
|
||||
Randomiser* randomiser;
|
||||
GameManager* game;
|
||||
|
||||
void setup() {
|
||||
debugger = new Debugger(9600);
|
||||
initDebug(9600);
|
||||
input = new Input();
|
||||
randomiser = new Randomiser(analogRead(0));
|
||||
game = new GameManager(debugger, randomiser);
|
||||
game = new GameManager(input, randomiser);
|
||||
}
|
||||
|
||||
void loop() { game->loop(); }
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "base_game.hpp"
|
||||
|
||||
BaseGame::BaseGame(Debugger* debugger, Randomiser* randomiser)
|
||||
: debugger(debugger), randomiser(randomiser) {}
|
||||
BaseGame::BaseGame(Randomiser* randomiser) : randomiser(randomiser) {}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "debugger.hpp"
|
||||
#include "randomiser.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class NextOperationType { NOOP, END, ADD_SCORE };
|
||||
|
||||
/**
|
||||
|
@ -13,11 +15,10 @@ struct NextOperation {
|
|||
};
|
||||
|
||||
class BaseGame {
|
||||
Debugger* debugger;
|
||||
Randomiser* randomiser;
|
||||
|
||||
public:
|
||||
BaseGame(Debugger* debugger, Randomiser* randomiser);
|
||||
BaseGame(Randomiser* randomiser);
|
||||
|
||||
virtual NextOperation loop() = 0;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,18 @@ const bool DEBUG = true;
|
|||
*/
|
||||
const uint8_t BUTTONS = 4;
|
||||
|
||||
/**
|
||||
* Pins of the buttons, in order from left to right in the case. Leftmost will be 0, and number will
|
||||
* increase to the right.
|
||||
*/
|
||||
const uint8_t BUTTON_PINS[BUTTONS] = {A0, A1, A2, A3};
|
||||
|
||||
/**
|
||||
* Debounce delay, i.e. how long a button must be high or low before it is accepted, to reduce
|
||||
* spurious inputs.
|
||||
*/
|
||||
const uint8_t DEBOUNCE_DELAY = 20;
|
||||
|
||||
/**
|
||||
* Delay at start of game between beeps, in milliseconds.
|
||||
*/
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#include <Arduino.h>
|
||||
#include "config.hpp"
|
||||
|
||||
Debugger::Debugger(uint16_t port) : serialPort(port) { Serial.begin(serialPort); }
|
||||
void initDebug(uint16_t port) { Serial.begin(port); }
|
||||
|
||||
void Debugger::print(const String msg, const bool newline) const {
|
||||
void debugPrint(const String msg, const bool newline) {
|
||||
if (DEBUG) {
|
||||
auto msgCopy = String(msg);
|
||||
|
||||
|
|
|
@ -2,15 +2,5 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Debugger class providing an interface to the serial port. To disable the debug calls entirely,
|
||||
* use the DEBUG configuration variable.
|
||||
*/
|
||||
class Debugger {
|
||||
uint16_t serialPort;
|
||||
|
||||
public:
|
||||
Debugger(uint16_t port);
|
||||
|
||||
void print(const String msg, const bool newline = true) const;
|
||||
};
|
||||
void initDebug(uint16_t port);
|
||||
void debugPrint(const String msg, const bool newline = true);
|
||||
|
|
|
@ -5,9 +5,22 @@
|
|||
#include "debugger.hpp"
|
||||
#include "randomiser.hpp"
|
||||
|
||||
GameManager::GameManager(Debugger* debugger, Randomiser* randomiser)
|
||||
: debugger(debugger), randomiser(randomiser), state(State::MENU), currentScore(0) {
|
||||
debugger->print("Initialising new game...");
|
||||
GameManager::GameManager(Input* input, Randomiser* randomiser)
|
||||
: input(input), randomiser(randomiser), state(State::MENU), currentScore(0) {
|
||||
debugPrint("Initialising new game...");
|
||||
}
|
||||
|
||||
void GameManager::loop() {}
|
||||
void GameManager::loop() {
|
||||
static auto prevState = ButtonState::OFF;
|
||||
|
||||
input->process();
|
||||
auto status = input->getStatus();
|
||||
auto newState = status.buttons[0];
|
||||
|
||||
if (newState != prevState) {
|
||||
prevState = newState;
|
||||
|
||||
auto msg = String(static_cast<uint8_t>(newState));
|
||||
debugPrint(msg, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
#include "config.hpp"
|
||||
#include "debugger.hpp"
|
||||
#include "input.hpp"
|
||||
#include "randomiser.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class State { MENU, INIT, GAME, SCORE };
|
||||
|
||||
class GameManager {
|
||||
Debugger* debugger;
|
||||
Input* input;
|
||||
Randomiser* randomiser;
|
||||
State state;
|
||||
uint16_t currentScore;
|
||||
|
||||
public:
|
||||
GameManager(Debugger* debugger, Randomiser* randomiser);
|
||||
GameManager(Input* input, Randomiser* randomiser);
|
||||
|
||||
void loop();
|
||||
};
|
||||
|
|
27
src/input.cpp
Normal file
27
src/input.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "input.hpp"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "config.hpp"
|
||||
|
||||
Input::Input() : lastChangeTimes{}, currentStates{}, debouncedStates{} {
|
||||
for (uint8_t i = 0; i < BUTTONS; ++i) {
|
||||
pinMode(BUTTON_PINS[i], INPUT_PULLUP);
|
||||
}
|
||||
}
|
||||
|
||||
void Input::process() {
|
||||
const auto now = millis();
|
||||
for (uint8_t i = 0; i < BUTTONS; ++i) {
|
||||
// Note that LOW is ON, HIGH is OFF when using pullup
|
||||
const auto state = (digitalRead(BUTTON_PINS[i]) == LOW) ? ButtonState::ON : ButtonState::OFF;
|
||||
|
||||
if (state != currentStates.buttons[i]) {
|
||||
currentStates.buttons[i] = state;
|
||||
lastChangeTimes[i] = now;
|
||||
} else if (now - lastChangeTimes[i] >= DEBOUNCE_DELAY && state != debouncedStates.buttons[i]) {
|
||||
debouncedStates.buttons[i] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const InputStatus& Input::getStatus() const { return debouncedStates; }
|
26
src/input.hpp
Normal file
26
src/input.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include <Arduino.h>
|
||||
#include "config.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class ButtonState { OFF, ON };
|
||||
|
||||
struct InputStatus {
|
||||
ButtonState buttons[BUTTONS];
|
||||
};
|
||||
|
||||
/**
|
||||
* Class managing the input coming from buttons, and their debouncing. Also manages setting up the
|
||||
* proper pins.
|
||||
*/
|
||||
class Input {
|
||||
uint32_t lastChangeTimes[BUTTONS];
|
||||
InputStatus currentStates;
|
||||
InputStatus debouncedStates;
|
||||
|
||||
public:
|
||||
Input();
|
||||
|
||||
void process();
|
||||
const InputStatus& getStatus() const;
|
||||
};
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "base_game.hpp"
|
||||
|
||||
SpeedGame::SpeedGame(Debugger* debugger, Randomiser* randomiser)
|
||||
: BaseGame(debugger, randomiser), waitingBeeps{}, waitingBeepsAmount(0) {}
|
||||
SpeedGame::SpeedGame(Randomiser* randomiser)
|
||||
: BaseGame(randomiser), waitingBeeps{}, waitingBeepsAmount(0) {}
|
||||
|
||||
NextOperation SpeedGame::loop() {}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "base_game.hpp"
|
||||
#include "config.hpp"
|
||||
#include "randomiser.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* The default speed test game where you need to press the buttons with an ever increasing speed.
|
||||
|
@ -9,6 +12,6 @@ class SpeedGame : BaseGame {
|
|||
uint8_t waitingBeepsAmount;
|
||||
|
||||
public:
|
||||
using BaseGame::BaseGame;
|
||||
SpeedGame(Randomiser* randomiser);
|
||||
NextOperation loop();
|
||||
};
|
||||
|
|
Reference in a new issue