#include // Pin const int gamePin = A3; const int leftPPin = 2; const int rightPPin = 3; const int modesPin = 4; const int aPin = 5; const int bPin = 6; const int selPin = A2; // States flags bool modesFlag; bool pauseFlag; bool movesFlag; // 1: considera mosse; 0 non considera mosse // Game flags bool endFlag; bool renderFlag; bool turnFlag; // true 1p - false 2p // Interface flags bool buttonActivated; bool leftPActivated; bool rightPActivated; bool pTwoActivated; bool pOneActivated; int rotReading; int rotLimitLow; int rotLimitHigh; enum States { MODES, TIME, INCREMENT, MOVES, START, FIRST, GAME, END }; enum States state; enum Modes { SUDDEN, BLITZ, MACMAHON }; enum Modes mode; // Timers unsigned long timer; long pOneTime; long pTwoTime; int incrementValue; // Counters int pOneMoves; int pTwoMoves; // Encoder variables int rotCounter; bool currentAState, lastAState, encoderFlag; // Message to matrix char messageBuffer[8]; void setup() { CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); Wire.begin(); pinMode (leftPPin, INPUT_PULLUP); pinMode (rightPPin, INPUT_PULLUP); pinMode (gamePin, INPUT_PULLUP); pinMode (modesPin, INPUT_PULLUP); pinMode (aPin, INPUT_PULLUP); pinMode (bPin, INPUT_PULLUP); pinMode (selPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(aPin), checkEncoder, CHANGE); // Init startRoutine(); state = States::START; renderFlag = true; } void loop() { readInput(); updateSystem(); render(); } void readInput() { switch(state) { case States::START: modesFlag = digitalRead(modesPin); break; case States::MODES: buttonActivated = digitalRead(selPin); if (!buttonActivated) { while (!digitalRead(selPin)); } rotReading = rotCounter; break; case States::TIME: buttonActivated = digitalRead(selPin); if (!buttonActivated) { while (!digitalRead(selPin)); } rotReading = rotCounter; break; case States::INCREMENT: buttonActivated = digitalRead(selPin); if (!buttonActivated) { while (!digitalRead(selPin)); } rotReading = rotCounter; break; case States::MOVES: buttonActivated = digitalRead(selPin); if (!buttonActivated) { while (!digitalRead(selPin)); } rotReading = rotCounter; break; case States::FIRST: rightPActivated = digitalRead(rightPPin); if (!rightPActivated) { while (!digitalRead(rightPPin)); } leftPActivated = digitalRead(leftPPin); if (!leftPActivated) { while (!digitalRead(leftPPin)); } break; case States::GAME: rightPActivated = digitalRead(rightPPin); leftPActivated = digitalRead(leftPPin); endFlag = digitalRead(gamePin); pauseFlag = digitalRead(selPin); if (!buttonActivated) { while (!digitalRead(selPin)); } break; case States::END: break; default: break; } } void updateSystem() { switch(state) { case States::START: //messageBuffer = 'modes'; if (!modesFlag) { state = States::MODES; mode = Modes::SUDDEN; //messageBuffer = 'sudden'; } break; case States::MODES: // mode si aggiorna con la lettura dall'encoder // cambia messaggeBuffer a seconda della lettura if (!buttonActivated) { state = States::TIME; pOneTime = 1; pTwoTime = 1; buttonActivated = true; rotCounter = 1; rotLimitLow = 1; rotLimitHigh = 99; } break; case States::TIME: if (rotCounter < rotLimitLow) { rotCounter = rotLimitLow; } if (rotCounter > rotLimitHigh) { rotCounter = rotLimitHigh; } pOneTime = rotCounter; pTwoTime = rotCounter; //messageBuffer = pOneTime; if (!buttonActivated) { pOneTime = pOneTime * 60 * 1000; pTwoTime = pOneTime * 60 * 1000; state = States::INCREMENT; buttonActivated = true; incrementValue = 0; rotCounter = 0; rotLimitLow = 0; rotLimitHigh = 60; } break; case States::INCREMENT: if (rotCounter < rotLimitLow) { rotCounter = rotLimitLow; } if (rotCounter > rotLimitHigh) { rotCounter = rotLimitHigh; } incrementValue = rotCounter; //messageBuffer = incrementValue; if (!buttonActivated) { incrementValue = incrementValue * 60 * 1000; state = States::MOVES; pOneMoves = 30; pTwoMoves = 30; buttonActivated = true; rotCounter = 30; rotLimitLow = 0; rotLimitHigh = 99; } break; case States::MOVES: if (rotCounter < rotLimitLow) { rotCounter = rotLimitLow; } if (rotCounter > rotLimitHigh) { rotCounter = rotLimitHigh; } pOneMoves = rotCounter; pTwoMoves = rotCounter; //messageBuffer = pOneMoves; if (!buttonActivated) { if (pOneMoves == 0) { movesFlag = false; } else { movesFlag = true; } state = States::FIRST; } break; case States::FIRST: // messageBuffer = timeValue timeValue; if (!rightPActivated) { turnFlag = true; state = States::GAME; } else if (!leftPActivated) { turnFlag = false; state = States::GAME; } if (state == States::GAME) { //inizializzazione gioco pauseFlag = false; timer = millis(); } break; case States::GAME: if (!pauseFlag) { if (turnFlag) { pOneTime -= millis()-timer; } else { pTwoTime -= millis()-timer; } timer = millis(); if (!pOneActivated && turnFlag) { pOneTime += incrementValue; pOneMoves--; turnFlag = !turnFlag; } if (!pTwoActivated && !turnFlag) { pTwoTime += incrementValue; pTwoMoves--; turnFlag = !turnFlag; } } if (!endFlag || pOneTime <= 0 || pTwoTime <= 0) { state = States::END; } if (movesFlag) { if (pOneMoves < 0 || pTwoMoves < 0) { state = States::END; } } if (!pauseFlag) { while(!digitalRead(selPin)); pauseFlag = !pauseFlag; } // messageBuffer = i tempi di entrambi break; case States::END: //messaggeBuffer = 'endgame'; if (millis() - timer >= 5000) { state = States::START; } break; default: break; } } void render() { if (renderFlag) { Wire.beginTransmission(8); Wire.write(messageBuffer); Wire.endTransmission(); } } void startRoutine() { Wire.beginTransmission(8); Wire.write('blitz'); delay(1000); Wire.write('at'); delay(1000); Wire.write('six'); delay(1000); Wire.write('fm'); delay(1000); Wire.write('ba6'); delay(1000); Wire.endTransmission(); } void checkEncoder() { currentAState = digitalRead(aPin); if (currentAState != lastAState) { if (digitalRead(bPin) != currentAState) { rotCounter--; } else { rotCounter++; } } encoderFlag = true; lastAState = currentAState; }