Skip to content

Instantly share code, notes, and snippets.

@benwtr
Created June 4, 2020 06:46
Show Gist options
  • Save benwtr/f6467d4fc0508fa5b010e12fd1c8e734 to your computer and use it in GitHub Desktop.
Save benwtr/f6467d4fc0508fa5b010e12fd1c8e734 to your computer and use it in GitHub Desktop.
/*
* Air Hockey Score Board
*
* This project added electronic score keeping to a little tabletop air hockey game
*
* I made light blocking sensors for the goals using pairs of infrared LEDs, one
* emitting light, the other acting as a sensor, amplified through an NPN transistor
*
* The scoreboard itself contains a small speaker, a 4 digit LED display and a push
* button attached to the arduino's reset pin. The display is a TM1637 which is an
* i2c device. We use a library that makes it easy so we can just print strings to it.
*
*/
#include <TM1637.h>
// 4 digit LED display
TM1637 tm(A5, A4);
// I heard somewhere, in the official rules of air hockey, the winner is the
// first to reach 7 points..
int max_points = 9;
// copypasta from arduino smoothing example
const int numReadings = 100; // tune this for smoothing vs responsiveness
int readIndex = 0;
int g0_readings[numReadings];
int g0_total = 0;
int g0_average = 0;
int g0_inputPin = A2; // Goal 0 sensor pin
int g1_readings[numReadings];
int g1_total = 0;
int g1_average = 0;
int g1_inputPin = A3; // Goal 1 sensor pin
unsigned int counter = 0; // just an arbitrary int to count how many times we've been through the loop and we don't care if we overflow it
bool g0_puck = false; // puck in goal?
bool g1_puck = false;
bool g0_last_puck = false; // puck state last time through the loop
bool g1_last_puck = false;
int g0_score = 0;
int g1_score = 0;
bool warmed_up = false;
void setup() {
Serial.begin(115200);
tm.init();
// tm.setBrightness(0);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
g0_readings[thisReading] = 0;
g1_readings[thisReading] = 0;
}
// beep
tone(9, 262, 500);
// display the score
tm.display(String(String(g0_score) + " " + String(g1_score)));
}
void loop() {
// avoid jankyness on boot, might not still be needed
if (counter > 1000) {
warmed_up = true;
}
// read the voltage from the goal 0 sensor, 0-5V is represented as 0-1023
g0_total = g0_total - g0_readings[readIndex];
g0_readings[readIndex] = analogRead(g0_inputPin);
g0_total = g0_total + g0_readings[readIndex];
// sleep for 1ms between readings for stability
delay(1);
// read the goal 1 sensor
g1_total = g1_total - g1_readings[readIndex];
g1_readings[readIndex] = analogRead(g1_inputPin);
g1_total = g1_total + g1_readings[readIndex];
// calculate averages
g0_average = g0_total / numReadings;
g1_average = g1_total / numReadings;
delay(1);
readIndex = readIndex + 1;
if (readIndex >= numReadings) {
readIndex = 0;
}
// when the puck is in the goal, the average is something like -233, otherwise it is > 300 typically
g0_puck = g0_average < 0;
g1_puck = g1_average < 0;
if (warmed_up) {
if (g0_puck != g0_last_puck) {
if (g0_puck == true) {
g0_score++;
tm.display(String(String(g0_score) + " " + String(g1_score))); // display score
tone(9, 523, 400); // beep
delay(100); // debounce
}
if (g0_puck == false) {
delay(4000); // allow 4 seconds to get the puck out
}
}
if (g1_puck != g1_last_puck) {
if (g1_puck == true) {
g1_score++;
tm.display(String(String(g0_score) + " " + String(g1_score))); // display
tone(9, 523, 400);
delay(100); // debounce
}
if (g1_puck == false) {
delay(4000); // allow 3 seconds to get the puck out
}
}
}
// Serial.print(g0_val);
// Serial.print("\t");
// Serial.println(g1_val);
// Serial.println(scoreString);
// Game over, max points reached
if ((g0_score == max_points) || (g1_score == max_points)) {
// beep 3 times
delay(900);
tone(9, 523, 500);
delay(1000);
tone(9, 523, 500);
delay(1000);
tone(9, 523, 500);
while (true) {
// flash the score forever, or until someone hits the reset button
tm.display(" ");
delay(1000);
tm.display(String(String(g0_score) + " " + String(g1_score)));
delay(1000);
}
}
counter++;
g0_last_puck = g0_puck;
g1_last_puck = g1_puck;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment