Carnival Lights Game

2,656

18

10

Introduction: Carnival Lights Game

About: Visit myminifactory: https://www.myminifactory.com/users/andrewgoldberg

Welcome to an Arduino beginner project. It's a simplification of my previous instructable; it's designed to be easier to reproduce.

This is a timing minigame where the active light moves back and forth across a row of lights in order. When the button is pressed the light stops. If the light stops on the center light the level and difficulty increases. If the button is pressed one away from the middle the level stays the same. If the button is pressed and it lands on a light which isn't the middle three the level and speed are lowered.

To win the player must reach level ten when the display shows a smiley face.

Supplies

Step 1: Clarifications

I will use the terms in the above diagram to identify parts of the breadboard. This project can be made without the LED matrix since it's only used as a level display. If you choose not to use the LED matrix then the libraries are not necessary.

Step 2: LED Wiring

Wire the ground pin (GND) into one of the bus strips.

Order the LEDs so the center light will be clearly distinct from the others. I chose to order my LEDs red, white, orange, orange, medium green, center large green. I mirrored the pattern to the other side.

Place the positive end of each LED (long end) with three holes between them and insert the negative end into the ground bus strip.

From the positive end of each LED wire a resistor across the center divider. Then use jumper wires to connect digital ports 2-12 to the resistors in order.

Step 3: Push Button

Wire a 5V current into a bus rail opposite the LEDs and wire ground into the other rail.

Place the button straddles on the center divider.

Place a wire from the 5V bus rail to the push button.

From the other side of the pushbutton place a resistor into the ground bus rail and place a wire on the same row into D13.

Step 4: LED Matrix

Place the LED matrix into the breadboard.

Wire from the 5V power rail to the VCC pin.

Place a wire from the ground power rail to GND

Place a wire from A4 to SDA

Place a wire from A5 to SCL

Install the required matrix libraries from here

Step 5: Code

/*This a minigame where the active light moves back and forth across a row of lights in order.  
 * When it reaches the end it travels back in the opposite direction.
 * When a button is pressed the light stops and if the light stops in the middle the level increases also increasing the speed.
 * if the button is pressed one away from the middle the speed and level stays the same
 * if the button is pressed and it lands on a light which isn't the middle or next to the middle the level and speed is lowered.
 * 
 * Digital ports 2-12 are eached wired directly to the positive end of LEDs.
 * The other end of the LED is in ground.
 * The button has 5V in and a second wire in inputting to D13 and a resistor wired to ground
 * 
 * The Matrix screen is wired:
 * 5v to vcc
 * GND to GND
 * A4 to SDA
 * A5 to SCL
 * 
 * At a negative level a sad face is displayed and at levels > 10 a happy face is displayed.
 */


#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

static const uint8_t PROGMEM    // Setting Static Constants for the LED Matrix
  Sad_bmp[] =                    // Declaring sad face
  { B00000000,
    B01100110,
    B01100110,
    B00000000,
    B00111100,
    B01000010,
    B01000010,
    B00000000
 },
  Happy_bmp[] =     //declaring happy face
 {
  B00000000,
  B01100110,
  B01100110,
  B00000000,
  B01000010,
  B01000010,
  B00111100,
  B00000000
 };

const int buttonPin = 13;     //Where the button inputs
int i = 2;      //The port number which the first LED is hooked on
bool dirflag = true;      //flag used to determine the direction of the LED
int lightRate = 125;      //rate in ms for how long each light stays on
int level = 0;     //stores what level the player is on
boolean buttonUp = true;      //flage which ensures the button isn't being held

void setup() {
  matrix.setTextSize(1);                          // Setting matrix text size to 1
  matrix.setTextWrap(true);                     // Preventing text wrapping to scroll text continuously through matrix
  matrix.setTextColor(LED_ON);                  // Turning LED On
  matrix.setRotation(1);                  // rotate
  matrix.begin(0x70);  // pass in the address
  matrix.setCursor(random(0,4),random(0,2));                   // Where the numbers should be printed, can't center so why not have them jump around!!!
  matrix.clear();
  matrix.print(level);            //start with 0 on screen
  matrix.writeDisplay();
  
  Serial.begin(9600);             //start Serial communication
  
  //Initialize LED pins
  pinMode(2, OUTPUT); 
  pinMode(3, OUTPUT); 
  pinMode(4, OUTPUT); 
  pinMode(5, OUTPUT); 
  pinMode(6, OUTPUT); 
  pinMode(7, OUTPUT); 
  pinMode(8, OUTPUT); 
  pinMode(9, OUTPUT); 
  pinMode(10, OUTPUT); 
  pinMode(11, OUTPUT); 
  pinMode(12, OUTPUT); 
  
  //initialize pin attatched to button
  pinMode(buttonPin, INPUT); 
}

void loop() {
  int buttonState = digitalRead(buttonPin);       //get the state of the input when button pressed == HIGH when not pressed == LOW
  
  if (buttonState == HIGH) {              //if the button is pressed
    if (buttonUp) {                 //ensure the button is not being held to repeat the loop
      digitalWrite(i, HIGH);          //light up on the light where the button was pressed
      
      if (i == 7) {             //if stopped on the middle light
        lightRate /= 1.2;       //speed up
        level++;                //increment level
        matrix.setCursor(random(0,4),random(0,2));                      //Setting the cursor to a random location so the number jumps around since it can't be centered
        matrix.clear();               //matrix must be clear before printing

        
        if (level<0) {
          matrix.drawBitmap(0, 0, Sad_bmp, 8, 8, LED_ON);      // Drawing the sad face when the level is negative
        }
        else if (level>9) {                             //draw a happy face if the level is 2 digits
          matrix.drawBitmap(0, 0, Happy_bmp, 8, 8, LED_ON);
        }
        else {
          matrix.print(level);            //display the current level
        }
        matrix.writeDisplay();
      }
      else if (i != 6 & i !=8) {               //if the stop is not on a green light (middle light was checked, making sure it's not the two lights next to that)
        lightRate *= 1.2;                       //slow down
        level --;                               //decrease the level
         matrix.setCursor(random(0,4),random(0,2));
         matrix.clear();
         if (level<0) {
          matrix.drawBitmap(0, 0, Sad_bmp, 8, 8, LED_ON); 
        }
         else if (level>9) {
          matrix.drawBitmap(0, 0, Happy_bmp, 8, 8, LED_ON);
         }
        else {
          matrix.print(level);
        }
         matrix.writeDisplay();
      }
    }
      delay(2000);        //stay with the stopped light for 2 seconds
      buttonUp = false;         //set the flag to false so if the button is held the loop isn't repeated
    }

  else {                    //when the button is up
    buttonUp = true;            //reset the flag so the button can be pressed to stop again
    digitalWrite(i, HIGH);            //light the current light
    delay(lightRate);                 //wait
    digitalWrite(i, LOW);             //turn off light
    
    if (i == 2){            //if the led being lit is on the end change the direction flag
      dirflag = false;
    }
    else if (i == 12){
      dirflag = true;
    }
    if (dirflag) {         //Increment based on the direction the led is going
      i--;
    }
    else {
      i++;
    }   
  } 
}

Step 6: Finishing

Copy the code into your Arduino IDE and upload it to the Arduino.

Adjustments:

  • To change the starting speed adjust the variable lightRate on line 53. The lightRate is the starting duration each light stays on in milliseconds.
  • To change the factor which the lights speed up by change the variable speedFactor. Larger values will increase the amount the lights speed up at each level.
  • If you want the level to be decremented when the light lands one off from the middle change line 113 " else if (i != 6 & i !=8) { " to " else { "
Microcontroller Contest

Participated in the
Microcontroller Contest

Be the First to Share

    Recommendations

    • Lamps and Lighting Contest

      Lamps and Lighting Contest
    • Tinkercad Student Design Contest

      Tinkercad Student Design Contest
    • Plastic Challenge

      Plastic Challenge

    10 Comments

    0
    MTlatelpa
    MTlatelpa

    5 months ago

    I had a worrying concern, I'm doing this for a class tech project, and I was wondering on how to download the matrix libraries

    0
    Thisguyjeff
    Thisguyjeff

    Question 6 months ago on Step 5

    Im not too sure if the code is correct.. please help. I have installed the Adafruit_GFX packs. But when it comes to the actual code it stops at redefinition of void..

    0
    apgoldberg
    apgoldberg

    Answer 6 months ago

    I can promise that the code does compile on my computer. I can think of some possibilities of why this is happening to you:
    1. The libraries aren't in the "libraries" folder in your "Arduino" folder
    2. All three libraries aren't installed
    3. The libraries haven't been unzipped
    4. The code is being compiled for the incorrect board

    If none of these are why it's failing then please paste your error message.

    0
    Thisguyjeff
    Thisguyjeff

    Reply 5 months ago

    Yes they were good to go. I had no problem after uploading the code properly. Thanks again.

    0
    apgoldberg
    apgoldberg

    Reply 5 months ago

    That's great to hear! Enjoy!

    0
    milad77991
    milad77991

    Answer 6 months ago

    how do you install Adafruit_GFX?

    0
    apgoldberg
    apgoldberg

    Reply 6 months ago

    He's referring to the libraries linked in step 4. Here they are again: https://drive.google.com/drive/folders/1FUTIwsfGdx...
    right click and click download on all three. They will download as zip files. You may need to extract it (it's good practice to do so and examine the files). The files need to be placed in the libraries folder inside of your Arduino folder. Here is the documentation of the part if needed: https://wiki.keyestudio.com/Ks0064_keyestudio_I2C_8x8_LED_Matrix_HT16K33

    0
    milad77991
    milad77991

    6 months ago

    Is it possible to use an LDR sensor instead of a pushbutton and how?

    0
    apgoldberg
    apgoldberg

    Reply 6 months ago

    I've never used an LDR in a project before; however, based on looking at some diagrams it seems as though it should work. This article: https://maker.pro/arduino/tutorial/how-to-use-an-l... has a simple diagram which should work for the cake code as well. It shows the part being wired to an analog input, but it should be possible to use with the digital pin (D13) that the button is already coded for. This won't allow you to set for a specific light strength and I'm not sure how much light will be needed to set it off. It will also require that you do the "button press" by turning on a light rather than off. There's a few other potential issues like the occasional chaos you'll get from switching from LOW to HIGH or if you're too close to the divide between the two.

    Because of all these issues I'd recommend that you rewrite some code. You can plug the photoresistor into an analog input as it normally goes. Then change all the lines which check if the digital button is high to something like
    if (analogRead(A3) > toleranceValue) {
    I'm not sure exactly what value you'll want to check against. Using a greater than should mean that when the light is on it's as if the button is pressed and if the light is of the button is not pressed. Flipping the sign will flip the button state.

    Let me know how it goes and good luck!