#include <LiquidCrystal_I2C.h>
#include <TM1637Display.h>
#include <Wire.h>
const int LED_Run = 2;
const int TM1637A_CLK = 32;
const int TM1637A_DIO = 33;
const int TM1637B_CLK = 13;
const int TM1637B_DIO = 14;
const int ButtonA = 26;
const int ButtonB = 53;
const int Buzzer_Pin = 4;
const int BuzzerBeepTime = 80;
const int LEDRunPulse = 1000;
const int PointsPulse = 400;
const int TM1637Pulse = 200;
const int Segundo = 885;
const int ButtonHold = 1500;
const int ButtonTime = 250;
const int LostTimeConst = 3000;
const int ResetGameTime = 3000;
uint8_t A[4] = { '0', '5', '0', '0' };
uint8_t B[4] = { '0', '5', '0', '0' };
uint8_t ASEG[4];
uint8_t BSEG[4];
byte ButtonPress;
boolean BlinkLEDFlag = false;
boolean BlinkLEDStart = false;
boolean BlinkAPointsFlag = false;
boolean BlinkAPointsStart = false;
boolean BlinkBPointsFlag = false;
boolean BlinkBPointsStart = false;
boolean TM1637RefreshFlag = false;
boolean TM1637RefreshStart = false;
boolean CounterDownAFlag = false;
boolean CounterDownAStart = false;
boolean CounterDownBFlag = false;
boolean CounterDownBStart = false;
boolean ButtonsFlag = false;
boolean ButtonsReady = false;
boolean ButtonsBefore = false;
boolean ButtonsStart = false;
boolean ButtonDebounceStart = false;
boolean GetButtonFlag = false;
boolean GameRunFlag = false;
boolean GameRunButton = false;
boolean SelectGameFlag = false;
boolean ResetGameStart = false;
boolean BuzzerBeepFlag = false;
boolean BuzzerBeepStart = false;
boolean TimeSegAStart = false;
boolean TimeSegBStart = false;
boolean LostTimeStart = false;
int BlinkLEDCount = 0;
int ButtonsCount = 0;
int ButtonDebounceCount = 0;
int BuzzerBeepCount = 0;
int BlinkAPointsCount = 0;
int BlinkBPointsCount = 0;
int TM1637RefreshCount = 0;
int TimeSegACount = 0;
int TimeSegBCount = 0;
int LostTimeCount = 0;
int ResetGameCount = 0;
const uint8_t SEG_CLEAR[] = { 0x00, 0x00, 0x00, 0x00 };
const uint8_t MODESEL[4][4] = {{'0', '5', '0', '0'},
{'1', '0', '0', '0'},
{'3', '0', '0', '0'},
{'9', '0', '0', '0'}
};
TM1637Display TM1637A( TM1637A_CLK, TM1637A_DIO );
TM1637Display TM1637B( TM1637B_CLK, TM1637B_DIO );
LiquidCrystal_I2C lcd(0x27, 20, 4);
int GameMode = 0;
void setup() {
pinMode( ButtonA, INPUT_PULLUP );
pinMode( ButtonB, INPUT_PULLUP );
pinMode( LED_Run, OUTPUT );
pinMode( Buzzer_Pin, OUTPUT );
digitalWrite( Buzzer_Pin, LOW );
ASEG[1] |= 0x80;
BSEG[1] |= 0x80;
TM1637A.setBrightness( 0x0f );
TM1637B.setBrightness( 0x0f );
TM1637A.setSegments( SEG_CLEAR );
TM1637B.setSegments( SEG_CLEAR );
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(" RELOJ AJEDREZ ");
lcd.setCursor( 0, 1 );
lcd.print(" <- A JUGAR! -> ");
BlinkLEDStart = true;
TM1637RefreshStart = true;
ButtonsFlag = true;
GetButtonFlag = true;
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
}
void loop()
{
BeatPulse();
// Procesos
if ( BlinkLEDFlag )
BlinkLED();
if ( ButtonsFlag )
Buttons();
if ( GetButtonFlag )
GetButton();
if ( GameRunFlag )
GameRun();
if ( SelectGameFlag )
SelectGame();
if ( BuzzerBeepFlag )
BuzzerBeep();
if ( CounterDownAFlag )
CounterDownA();
if ( CounterDownBFlag )
CounterDownB();
if ( BlinkAPointsFlag )
BlinkAPoints();
if ( BlinkBPointsFlag )
BlinkBPoints();
if ( TM1637RefreshFlag )
TM1637Refresh();
delay( 1 );
}
void BeatPulse()
{
if ( BlinkLEDStart )
{
if ( BlinkLEDCount >= LEDRunPulse )
{
BlinkLEDCount = 0;
BlinkLEDStart = false;
BlinkLEDFlag = true;
}
else
BlinkLEDCount++;
}
if ( ButtonDebounceStart )
{
if ( ButtonDebounceCount >= ButtonTime )
{
ButtonDebounceCount = 0;
ButtonDebounceStart = false;
}
else
ButtonDebounceCount++;
}
if ( ButtonsStart )
{
if ( ButtonsCount >= ButtonHold )
{
ButtonsCount = 0;
ButtonsStart = false;
//Realiza un Beep
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
lcd.setCursor( 0, 1 );
switch ( ButtonPress ) {
case 0x00:
lcd.print("<ELIJE TU JUEGO>");
SelectGameFlag = true;
break;
case 0x01:
lcd.print(" VAMOS! -> ");
BlinkBPointsStart = true;
TimeSegBStart = true;
GameRunButton = false;
GameRunFlag = true;
break;
case 0x02:
lcd.print(" <- VAMOS! ");
BlinkAPointsStart = true;
TimeSegAStart = true;
GameRunButton = true;
GameRunFlag = true;
break;
}
GetButtonFlag = false;
}
else
ButtonsCount++;
}
if ( ResetGameStart )
{
if ( ResetGameCount >= ResetGameTime )
{
ResetGameCount = 0;
ResetGameStart = false;
if ( ButtonPress == 0 )
{
lcd.setCursor( 0, 1 );
lcd.print(" <- A JUGAR! -> ");
TimeSegAStart = false;
BlinkAPointsStart = false;
ASEG[1] |= 0x80;
TimeSegBStart = false;
BlinkBPointsStart = false;
BSEG[1] |= 0x80;
GameRunFlag = false;
GetButtonFlag = true;
for ( ResetGameCount = 0; ResetGameCount < 4; ResetGameCount++ )
A[ ResetGameCount ] = B[ ResetGameCount ] = MODESEL[ GameMode ][ ResetGameCount ];
ResetGameCount = 0;
//Realiza un Beep
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
}
}
else
ResetGameCount++;
}
if ( BlinkAPointsStart )
{
if ( BlinkAPointsCount >= PointsPulse )
{
BlinkAPointsCount = 0;
BlinkAPointsStart = false;
BlinkAPointsFlag = true;
}
else
BlinkAPointsCount++;
}
if ( BlinkBPointsStart )
{
if ( BlinkBPointsCount >= PointsPulse )
{
BlinkBPointsCount = 0;
BlinkBPointsStart = false;
BlinkBPointsFlag = true;
}
else
BlinkBPointsCount++;
}
if ( TM1637RefreshStart )
{
if ( TM1637RefreshCount >= TM1637Pulse )
{
TM1637RefreshCount = 0;
TM1637RefreshStart = false;
TM1637RefreshFlag = true;
}
else
TM1637RefreshCount++;
}
if ( BuzzerBeepStart )
{
if ( BuzzerBeepCount >= BuzzerBeepTime )
{
BuzzerBeepCount = 0;
BuzzerBeepStart = false;
BuzzerBeepFlag = true;
}
else
BuzzerBeepCount++;
}
if ( TimeSegAStart )
{
if ( TimeSegACount >= Segundo )
{
TimeSegACount = 0;
CounterDownAFlag = true;
}
else
TimeSegACount++;
}
if ( TimeSegBStart )
{
if ( TimeSegBCount >= Segundo )
{
TimeSegBCount = 0;
CounterDownBFlag = true;
}
else
TimeSegBCount++;
}
if ( LostTimeStart )
{
if ( LostTimeCount >= LostTimeConst )
{
LostTimeCount = 0;
LostTimeStart = false;
digitalWrite( Buzzer_Pin, LOW );
//REINICIA COMIENZO DE PARTIDA
TimeSegAStart = false;
BlinkAPointsStart = false;
ASEG[1] |= 0x80;
TimeSegBStart = false;
BlinkBPointsStart = false;
BSEG[1] |= 0x80;
GetButtonFlag = true;
for ( ResetGameCount = 0; ResetGameCount < 4; ResetGameCount++ )
A[ ResetGameCount ] = B[ ResetGameCount ] = MODESEL[ GameMode ][ ResetGameCount ];
}
else
LostTimeCount++;
}
}
void BlinkLED() {
if ( digitalRead( LED_Run ) )
digitalWrite( LED_Run, LOW );
else
digitalWrite( LED_Run, HIGH );
BlinkLEDStart = true;
BlinkLEDFlag = false;
}
void Buttons() {
ButtonPress = ( digitalRead( ButtonB ) << 1 ) | digitalRead( ButtonA );
if ( ButtonPress != 0x03 ) {
if ( !(ButtonsBefore || ButtonDebounceStart) ) {
ButtonsBefore = true;
ButtonsReady = true;
}
}
else
{
if ( ButtonsBefore ) {
ButtonsBefore = false;
ButtonDebounceStart = true;
}
}
}
void GetButton() {
if ( ButtonsReady ) {
ButtonsStart = true;
ButtonsReady = false;
}
if ( !ButtonsBefore ) {
ButtonsCount = 0;
ButtonsStart = false;
}
}
void GameRun() {
if ( ButtonsReady ) {
ResetGameStart = true;
lcd.setCursor( 0, 1 );
if ( ButtonPress == 0x01 && GameRunButton ) {
GameRunButton = false;
lcd.print(" VAMOS! -> ");
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
if ( GameMode == 0x03 )
Incrementa30s( A );
BlinkBPointsStart = true;
TimeSegBStart = true;
BlinkAPointsStart = false;
ASEG[1] |= 0x80;
TimeSegAStart = false;
}
if ( ButtonPress == 0x02 && !GameRunButton ) {
GameRunButton = true;
lcd.print(" <- VAMOS! ");
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
if ( GameMode == 0x03 )
Incrementa30s( B );
BlinkAPointsStart = true;
TimeSegAStart = true;
BlinkBPointsStart = false;
BSEG[1] |= 0x80;
TimeSegBStart = false;
}
ButtonsReady = false;
}
if ( !ButtonsBefore )
{
ResetGameCount = 0;
ResetGameStart = false;
}
}
void SelectGame()
{
int i;
if ( ButtonsReady ) {
if ( ButtonPress == 0x02 ) {
GameMode++;
if ( GameMode > 0x03 )
GameMode = 0x00;
for ( i = 0; i < 4; i++ )
A[ i ] = B[ i ] = MODESEL[ GameMode ][ i ];
lcd.setCursor( 0, 1 );
switch ( GameMode ) {
case 0x00:
lcd.print("-MODO 1 FLASH ");
break;
case 0x01:
lcd.print("-MODO 2 FRIENDS ");
break;
case 0x02:
lcd.print("-MODO 3 CLASSIC ");
break;
case 0x03:
lcd.print("-MODO 4 FIDE ");
break;
}
//Realiza un Beep
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
}
if ( ButtonPress == 0x01 ) {
GetButtonFlag = true;
lcd.setCursor( 0, 1 );
lcd.print(" <- A JUGAR! -> ");
//Realiza un Beep
digitalWrite( Buzzer_Pin, HIGH );
BuzzerBeepStart = true;
SelectGameFlag = false;
}
ButtonsReady = false;
}
}
void BuzzerBeep() {
digitalWrite( Buzzer_Pin, LOW);
BuzzerBeepFlag = false;
}
void CounterDownA() {
if ( CountDown( A ) ) {
lcd.setCursor( 0, 1 );
lcd.print(" GANADOR! -> ");
TimeSegAStart = false;
BlinkAPointsStart = false;
ASEG[1] |= 0x80;
ResetGameCount = 0;
ResetGameStart = false;
digitalWrite( Buzzer_Pin, HIGH );
delay(10000);
digitalWrite( Buzzer_Pin, LOW );
LostTimeStart = true;
GameRunFlag = false;
}
CounterDownAFlag = false;
}
void CounterDownB() {
if ( CountDown( B ) ) {
lcd.setCursor( 0, 1 );
lcd.print(" <- GANADOR! ");
TimeSegBStart = false;
BlinkBPointsStart = false;
BSEG[1] |= 0x80;
ResetGameCount = 0;
ResetGameStart = false;
digitalWrite( Buzzer_Pin, HIGH );
delay(10000);
digitalWrite( Buzzer_Pin, LOW );
LostTimeStart = true;
GameRunFlag = false;
}
CounterDownBFlag = false;
}
void BlinkAPoints() {
if ( ASEG[1] & 0x80 )
ASEG[1] &= 0x7f;
else
ASEG[1] |= 0x80;
BlinkAPointsStart = true;
BlinkAPointsFlag = false;
}
void BlinkBPoints() {
if ( BSEG[1] & 0x80 )
BSEG[1] &= 0x7f;
else
BSEG[1] |= 0x80;
BlinkBPointsStart = true;
BlinkBPointsFlag = false;
}
void TM1637Refresh() {
ASEG[ 0 ] = TM1637A.encodeDigit( A[ 0 ] );
if ( ASEG[1] & 0x80 )
ASEG[ 1 ] = TM1637A.encodeDigit( A[ 1 ] ) | 0x80;
else
ASEG[ 1 ] = TM1637A.encodeDigit( A[ 1 ] );
ASEG[ 2 ] = TM1637A.encodeDigit( A[ 2 ] );
ASEG[ 3 ] = TM1637A.encodeDigit( A[ 3 ] );
BSEG[ 0 ] = TM1637B.encodeDigit( B[ 0 ] );
if ( BSEG[1] & 0x80 )
BSEG[ 1 ] = TM1637B.encodeDigit( B[ 1 ] ) | 0x80;
else
BSEG[ 1 ] = TM1637B.encodeDigit( B[ 1 ] );
BSEG[ 2 ] = TM1637B.encodeDigit( B[ 2 ] );
BSEG[ 3 ] = TM1637B.encodeDigit( B[ 3 ] );
// Refresca Displays TM1637
TM1637A.setSegments( ASEG, 4, 0 );
TM1637B.setSegments( BSEG, 4, 0 );
TM1637RefreshStart = true;
TM1637RefreshFlag = false;
}
bool CountDown(uint8_t *dir)
{
if ( dir[ 3 ] < '1' )
if ( dir[ 2 ] < '1' )
if ( dir[ 1 ] < '1' )
if ( dir[ 0 ] < '1' )
return true;
else
{
dir[ 0 ]--;
dir[ 1 ] = '9';
dir[ 2 ] = '5';
dir[ 3 ] = '9';
}
else
{
dir[ 1 ]--;
dir[ 2 ] = '5';
dir[ 3 ] = '9';
}
else
{
dir[ 2 ]--;
dir[ 3 ] = '9';
}
else
dir[ 3 ]--;
return false;
}
void Incrementa30s(uint8_t *dir) {
dir[ 2 ] = dir[ 2 ] + 0x03;
if ( dir[ 2 ] > '5' ) {
dir[ 1 ]++;
dir[ 2 ] = dir[ 2 ] - 0x06;
if ( dir[ 1 ] > '9' ) {
dir[ 0 ]++;
dir[ 1 ] = '0';
if ( dir[ 0 ] > '9' )
dir[ 0 ] = '9';
}
}
if ( dir[ 0 ] > '8' )
dir[ 3 ] = dir[ 2 ] = dir[ 1 ] = '0';
}