The code below I've made is supposed to act as a chess clock when uploaded to a compatible Arduino. I've written everything, but I just want another set of eyes to look over the code in case I've missed something obvious and/or forgotten a certain feature before I solder all the wires and hardware together. There's no errors when I verify in the Arduino IDE, but that doesn't mean there's no bugs.
There's supposed to be two lights to indicate the turn, two HT16K33 4 digit 7 segment clocks for time display, and three buttons for various operations.
Used libraries:
HT16K33 - https://github.com/RobTillaart/HT16K33/tree/master
Code:
#include <HT16K33.h>
using namespace std;
// !!
// Pin numbers start. Modify to ensure numbers line up with wires.
// !!
const int P1L = 29; // Player 1 (left) indicator LED.
const int P2L = 37; // Player 2 (right) indicator LED.
const int P1B = 2; // P1s button.
const int P2B = 13; //P2s button.
const int PR = 12; // Pause/Reset button.
// !!
// Pin numbers end. Do not modify anything outside of this.
// !!
bool turn = false; // False for P1s turn, true for P2s.
bool gameActive = false; // Controls if timers act or not.
int P1T = 1800; // P1s timer. Starts at 30:00, in seconds.
int P2T = 1800; // Ditto, for P2.
bool GO = false; // Game Over bool.
HT16K33 P1(0x71); //P1s clock. (Sodder the bottom address jumper to set the address to 0x71.)
HT16K33 P2(0x70); //P2s clock. (Leave address jumpers untouched.)
int secTime = 0; // A built in delay mechanism.
int PRH = 0; // How long the Pause/Reset button has been held for.
int GOT = 0; //Timer used in game over routine.
bool GOI = false; //Bool used in game over routine.
unsigned long sysTime = millis(); // Delay tracker.
uint8_t G[4] = { 125, 119, 55, 121 }; // Raw bytes for GAME OVER display.
uint8_t O[4] = { 63, 62, 121, 49 }; // Ditto.
void setup() {
// Setting pin types.
pinMode(P1L, OUTPUT);
pinMode(P2L, OUTPUT);
pinMode(P1B, INPUT);
pinMode(P2B, INPUT);
pinMode(PR, INPUT);
// Begin LED clock startup.
Wire.begin();
Wire.setClock(100000);
P1.begin();
P2.begin();
P1.displayOn();
P2.displayOn();
P1.displayInt(3000);
P2.displayInt(3000);
P1.displayColon(1);
P2.displayColon(1);
// End LED clock startup.
}
void loop() {
secTime = (millis() - sysTime); // Decrement sectime based on how many MS the last loop took.
sysTime = millis(); // Adjust sysTime after secTime is adjusted.
if (digitalRead(P1B) or digitalRead(P2B)) // Are either of the player buttons pressed?
{
secTime = 1000; //Reset secTime.
if (digitalRead(P1B)) //Is P1s button pressed?
{
turn = false; // false = P1s turn
digitalWrite(P1L, HIGH); // Turn on P1s LED
digitalWrite(P2L, LOW); // Turn off P2s LED.
} else //No, P2s button is pressed.
{
turn = true; // Do the opposite of above.
digitalWrite(P2L, HIGH);
digitalWrite(P1L, LOW);
}
}
// No? Than is the pause/reset button pressed?
if (digitalRead(PR)) { // Yes.
secTime = 1000; // Reset secTime.
PRH = (PRH + (millis() - sysTime)); //Increment PRH.
if (PRH >= 2000) // Has PR been held for 2 seconds or longer?
{ // Yes.
gameActive = false; // Stop the game.
P1T = 1800;
P2T = 1800; // Reset timers.
P1.displayInt(3000);
P2.displayInt(3000); // Reset displays.
GO = false; //Reset GAME OVER.
}
}
if (!digitalRead(PR) && (PRH > 0)) // Has PR been released?
{ // Yes.
if (PRH >= 2000) //Was PR held for two seconds or longer?
{ // Yes.
PRH = 0; // Reset PRH and do nothing more.
} else { // No, PR was held for less than 2 seconds.
secTime = 1000; //Reset secTime.
gameActive = !gameActive; // Toggle gameActive.
}
}
if (gameActive = true) // Is game active?
{ // Yes.
if (secTime <= 0) // Has a second passed?
{ // Yes.
if (turn = false) // Is it P1s turn?
{ // Yes.
if (P1T = 0) // Is P1 out of time?
{ // Yes.
GO = true; // Set GAME OVER to true.
gameActive = false; // Stop the game.
} else { // No, P1 still has time.
P1T = timesub(P1T, P1); // Subtract 1 unit (second).
secTime = 1000; // Set the delay timer to 1 second.
}
} else { // No, it's P2s turn.
if (P2T = 0) // Is P2 out of time?
{ // Yes.
GO = true; // Set GAME OVER to true.
} else { // No, P2 still has time.
P2T = timesub(P2T, P2); // Subtract 1 second.
secTime = 1000; // Set the delay timer to 1 second.
}
}
}
}
if (GO = true) // Has someone ran out of time?
{
if (secTime <= 0) //Is secTime 0 or less?
{
if (turn = false) //Is it P1's turn?
{
if (GOI = false) {
P1.displayRaw(G); // GAME
P1.displayColon(false); // disable colon
GOI = true;
secTime = 750;
}
if (GOI = true) {
P1.displayRaw(O); // OVER
GOI = false;
secTime = 750;
}
} else {
if (GOI = false) {
P2.displayRaw(G); // GAME
P2.displayColon(false); // disable colon
GOI = true;
secTime = 750;
}
if (GOI = true) {
P2.displayRaw(O); // OVER
GOI = false;
secTime = 750;
}
}
}
}
}
int timesub(int timer, HT16K33 player) {
timer = timer - 1;
int tempMin = timer / 60;
int tempSec = timer % 60;
player.displayInt((tempMin * 100) + tempSec);
return timer;
}
// -- END OF FILE --