173 lines
2.6 KiB
C++
173 lines
2.6 KiB
C++
#include "magicSwitchBoard.h"
|
|
#include "Arduino.h"
|
|
#include "buttons.h"
|
|
|
|
#define CHANNELS 3
|
|
#define TIMEOUT 7000 //game timeout
|
|
|
|
typedef enum
|
|
{
|
|
idle,
|
|
learn,
|
|
active,
|
|
last
|
|
} states;
|
|
|
|
states state = last;
|
|
uint8_t sequence[CHANNELS] = {0xFF, 0xFF, 0xFF};
|
|
const uint8_t buttonIndex[CHANNELS] = {4, 5, 6};
|
|
const uint32_t leds[CHANNELS] = {LED1, LED2, LED3};
|
|
|
|
uint64_t lastTime = 0;
|
|
|
|
uint8_t learnIndex = 0;
|
|
|
|
void showLeds(void)
|
|
{
|
|
//loop through the button list
|
|
for (int i = 0; i < CHANNELS; i++)
|
|
{
|
|
//get the button pointer
|
|
buttons *currentbutton = getButton(buttonIndex[sequence[i]]);
|
|
|
|
//verify that the button pointer is not NULL
|
|
if (currentbutton == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//if the button is pressed, show LED or not
|
|
if (currentbutton->raw() == true)
|
|
{
|
|
//check if the position is already programmed
|
|
//write sequence led on
|
|
digitalWrite(leds[i], 1);
|
|
}
|
|
else
|
|
{
|
|
//write sequence led off
|
|
digitalWrite(leds[i], 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void resetMagicSwitchBoard(void)
|
|
{
|
|
state = idle;
|
|
lastTime = 0;
|
|
learnIndex = 0;
|
|
for (int i = 0; i < CHANNELS; i++)
|
|
{
|
|
sequence[i] = 0xff;
|
|
digitalWrite(leds[i], 0);
|
|
}
|
|
}
|
|
|
|
bool CheckTimeOut(void)
|
|
{
|
|
uint64_t currentmillis = millis();
|
|
if(!lastTime)
|
|
{
|
|
lastTime = currentmillis;
|
|
}
|
|
|
|
//check if lastTime is initialized or timeout expired
|
|
if ((currentmillis - lastTime > TIMEOUT))
|
|
{
|
|
//handle timeout
|
|
resetMagicSwitchBoard();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (anybutton())
|
|
{
|
|
//game in progress, update timer
|
|
lastTime = currentmillis;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void handleLearn(void)
|
|
{
|
|
for (int i = 0; i < CHANNELS; i++)
|
|
{
|
|
buttons *currentbutton = getButton(buttonIndex[i]);
|
|
if (currentbutton == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (currentbutton->state() == !RELEASED)
|
|
{
|
|
bool duplicate = false;
|
|
for (int n = 0; n < CHANNELS; n++)
|
|
{
|
|
if (currentbutton->index() == buttonIndex[sequence[n]])
|
|
{
|
|
duplicate = true;
|
|
}
|
|
}
|
|
|
|
if (!duplicate)
|
|
{
|
|
sequence[learnIndex] = i;
|
|
learnIndex++;
|
|
}
|
|
}
|
|
}
|
|
if (learnIndex == CHANNELS)
|
|
{
|
|
state = active;
|
|
}
|
|
}
|
|
|
|
void handleIdle(void)
|
|
{
|
|
if (anybutton())
|
|
{
|
|
state = learn;
|
|
}
|
|
else
|
|
{
|
|
for (auto &&i : leds)
|
|
{
|
|
digitalWrite(i, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void handleMagicSwitchBoard(void)
|
|
{
|
|
switch (state)
|
|
{
|
|
case idle:
|
|
{
|
|
handleIdle();
|
|
}
|
|
break;
|
|
|
|
case learn:
|
|
{
|
|
handleLearn();
|
|
}
|
|
break;
|
|
|
|
case active:
|
|
{
|
|
CheckTimeOut();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
state = idle;
|
|
}
|
|
break;
|
|
}
|
|
showLeds();
|
|
|
|
|
|
}
|