Clicking one button and debounce works now

This commit is contained in:
Mikko Ahlroth 2019-10-17 20:44:26 +03:00
parent 5bce8d78c0
commit 72fded1f7b
12 changed files with 105 additions and 31 deletions

View file

@ -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(); }

View file

@ -1,4 +1,3 @@
#include "base_game.hpp"
BaseGame::BaseGame(Debugger* debugger, Randomiser* randomiser)
: debugger(debugger), randomiser(randomiser) {}
BaseGame::BaseGame(Randomiser* randomiser) : randomiser(randomiser) {}

View file

@ -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;
};

View file

@ -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.
*/

View file

@ -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);

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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
View 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
View 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;
};

View file

@ -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() {}

View file

@ -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();
};