Introduction: LightBalls by Clara&Blanca
A fun and interactive lighting game.
The game consists of the following:
All six lights start turned off. To start the game, any button needs to be pushed. Than the game starts. A random light will be turned on, and the timer will start counting the seconds. Once pressed the button, immediately another random one will be turned on and so... until 10 times. You need to press the lighted buttons the fast as possible to achieve the record of the lowest time on oush them all!
In case you don't make a mistake, lights will illuminate in a fun way. However, if you go wrong, an alert sound will notice you and the timer will turn to 0 again so that you can play.
Have fun playing and let's see if you achieve the best record!
Step 1: WATCH THE VIDEO!
https://vimeo.com/246106650
Step 2: Electronic Components and Supplies
Arduino Genuino UNO
LEDs x6
Button x6
Cables
Sound Buzzer
Display 7 segments
Resistor x12
Step 3: LEDs Connection: Physical Setup
Firstly, we connect the LEDS as shown
Step 4: LEDs & Pushbuttons Connection: Physical Setup
Connect Leds and buttons as shown. For every led needs to be a related pushbutton.
Step 5: Buzzer Connection: Physical Setup
Once we have the leds and pushbuttons already connected, we add the buzzer in order to add sound to the system. Buzzer needs to be connected as shown.
Step 6: Display Connection: Physical Setup
The last step of the physical setup is connecting the display, as shown.
Step 7: Final Disposition
Finally, the connections board needs to be displayed as in the picture.
Step 8: Code
Upload the next code to your Arduino:
#include
#include "TM1637.h"
#define ON 1
#define OFF 0
int8_t TimeDisp[] = {0x00, 0x00, 0x00, 0x00};
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char halfsecond = 0;
unsigned char second;
unsigned char minute = 0;
unsigned char hour = 12;
#define CLK A1//pins definitions for TM1637 and can be changed to other ports
#define DIO A2 TM1637 tm1637(CLK, DIO);
int pinArray[] = {8, 9, 10, 11, 12, 13}; //LEDS
int countB = 0;
int countL = 0;
int timer = 1000;
int voltes = 0;
int estado = 1;
const int boton1 = 2;
const int boton2 = 3;
const int boton3 = 4;
const int boton4 = 5;
const int boton5 = 6;
const int boton6 = 7;
void setup() { //SETUP
pinMode (boton1, INPUT); //BUTTON
pinMode (boton2, INPUT); //BUTTON
pinMode (boton3, INPUT); //BUTTON
pinMode (boton4, INPUT); //BUTTON
pinMode (boton5, INPUT); //BUTTON
pinMode (boton6, INPUT); //BUTTON
pinMode(8, OUTPUT); //LED
pinMode(9, OUTPUT); //LED
pinMode(10, OUTPUT); //LED
pinMode(11, OUTPUT); //LED
pinMode(12, OUTPUT); //LED
pinMode(13, OUTPUT); //LED
Serial.begin(9600);
tm1637.set();
tm1637.init();
Timer1.initialize(100000); //timing for 50ms
Timer1.attachInterrupt(TimingISR); //declare the interrupt serve routine: TimingISR
}
void loop() { //LOOP FUNCTION OF REPETITION. GENERAL
paraRellotge();
run_time();
if (digitalRead(2) == LOW || digitalRead(3) == LOW || digitalRead(4) == LOW || digitalRead(5) == LOW || digitalRead(6) == LOW || digitalRead(7) == LOW) { //mira si apretes algun boto per comensar a jugar
delay (1000);
while (digitalRead(2) == LOW || digitalRead(3) == LOW || digitalRead(4) == LOW || digitalRead(5) == LOW || digitalRead(6) == LOW || digitalRead(7) == LOW) {
paraRellotge();
}
joc ();
}
}
void joc () { //GAME FUNCTION. MAIN
for (int i = 0; i <= 9; i++) {
countL = numero(countL); // Randomly we choose that led is going to turn on ...
countB = countL - 6; //buttons depending on leds
Serial.print("LED: ");
Serial.print(countL);
Serial.print(" Button: ");
Serial.println(countB);
digitalWrite(countL, HIGH); //Turn ON the one randomly
while (digitalRead(countB) == HIGH) {
run_time();
if (digitalRead(2) == LOW || digitalRead(3) == LOW || digitalRead(4) == LOW || digitalRead(5) == LOW || digitalRead(6) == LOW || digitalRead(7) == LOW) { //Looks if you pressed the wrong button
if (digitalRead(countB) == LOW)
break;
while (digitalRead(2) == LOW || digitalRead(3) == LOW || digitalRead(4) == LOW || digitalRead(5) == LOW || digitalRead(6) == LOW || digitalRead(7) == LOW) {
run_time();
}
run_time();
error();
Serial.println("ERROR!"); //to be able to check on screen if the program does the error correctly
for (int i = 8; i <= 13; i++) {
digitalWrite(i, HIGH);
}
delay (500);
for (int i = 8; i <= 13; i++) {
digitalWrite(i, LOW);
}
delay (500);
for (int i = 8; i <= 13; i++) {
digitalWrite(i, HIGH);
}
delay (500);
for (int i = 8; i <= 13; i++) {
digitalWrite(i, LOW);
}
delay (200);
return;
}
}
while (digitalRead(countB) == LOW) { //While the button is pressed, it does not refresh
run_time();
}
run_time();
voltes++;
Serial.println("OK");
digitalWrite(countL, LOW); //Turn OFF leds
Serial.println(voltes);
if (i == 9) {
acabar();
}
}
}
int numero (int antic) { //FUNCTION TO CHOOSE A NON-REPEATED NUMBER OF LED RANDOM
int i = random (8, 14);
while (i == antic) {
i = random(8, 14);
}
return i; // returns the good number in case there is a repeat.
}
void error () { // FUNCTION THAT IS GIVEN IN THE EVENT OF ERROR
estado = 4;
tone(A0, 80, 1000); // Error sound
TimeDisp[0] = 0;
TimeDisp[1] = 0;
TimeDisp[2] = 0;
TimeDisp[3] = 0;
delay (500);
second = 0;
minute = 0;
halfsecond = 0;
loop();
}
void acabar () { // FUNCTION TO REPRODUCE WHEN YOU FINALLY FIND THE GAME CORRECTLY
//tone(A0, 40, 2500); //tone of sound when game finished correctly. optional
// Lighting set of lights
for (int i = 8; i <= 13; i++) {
digitalWrite(i, HIGH);
}
delay (200);
for (int i = 8; i <= 13; i++) {
digitalWrite(i, LOW);
}
for (int i = 8; i <= 13; i++) {
digitalWrite(i, HIGH);
delay (150);
}
for (int i = 8; i <= 13; i++) {
digitalWrite(i, LOW);
delay (150);
}
for (int i = 8; i <= 13; i++) {
digitalWrite(i, HIGH);
delay (150);
}
for (int i = 8; i <= 13; i++) {
digitalWrite(i, LOW);
delay (150);
}
for (int i = 8; i <= 13; i++) {
digitalWrite(i, HIGH);
delay (150);
}
for (int i = 8; i <= 13; i++) {
digitalWrite(i, LOW);
delay (150);
}
mostraTemps();
delay (6000);
loop ();
}
void TimingISR() { //FUNCTION THAT RUNS TIME
halfsecond ++;
if (halfsecond == 5) {
ClockPoint = (~ClockPoint) & 0x01;
}
if (halfsecond == 10) {
Update = ON;
ClockPoint = (~ClockPoint) & 0x01;
second ++;
if (second == 60) {
minute ++;
if (minute == 60) {
hour ++;
if (hour == 24)hour = 0;
minute = 0;
}
second = 0;
}
halfsecond = 0;
}
// Serial.println(second);
}
void TimeUpdate(void) { // TIME UPDATING FUNCTION
if (ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF);
TimeDisp[0] = minute / 10;
TimeDisp[1] = minute % 10;
TimeDisp[2] = second / 10;
TimeDisp[3] = second % 10;
Update = OFF;
}
void run_time () {
if (Update == ON) {
TimeUpdate();
tm1637.display(TimeDisp);
}
}
void paraRellotge() { // FUNCTION TO STOP THE TIME
second = 0;
minute = 0;
}
void mostraTemps() { // FUNCTION TO SHOW THE TIME
second = second;
minute = minute;
}
Step 9: Structure
The first step of building the exterior structure is cutting a 4mm wood as the image shown. *On the .pdf attached, comcrete measures of how cutting the material. And so, the box will be ready to be built.
However, a coat of any color paint would be recommended to personalize the box.
Once the box is cutted and paited, it can be built.
Step 10: Pushbuttons Location
Place the six pushbuttons of the set as displayed in the image.
Step 11: Welding
In order to ensure the good working of all electronics, it is recommended to weld all the circuit to a welding plate. All elements will now be fixed.
Step 12: LEDs Location
LEDs need to pass through two holes located at the same level as the pushbuttons. Three on every hole.
Additionally, every LED needs to pass though a round transparent base in order to be able to play later.
Each base will fit in its transparent semi-sphere, as we will see in next step.
Step 13: Buttons & Screen
The last step is to locate the buttons (the translucid semi-spheres). They will be the exterior buttons. They can be painted with any soft and translucid color or simply left transparent.
The screen will be located in the front rectangular hole.