How to make an Interactive 2 player Arcade Game using WS2811 LED Strip and Arduino Nano

Published  September 1, 2023   0
LED Arcade Game using Arduino Nano

Tired of your old Arcade games which all looks and works in the same way? Want to create a quick fun game which you can enjoy with your friends and family without using any thought? You are at the right place, then. In this blog, we will learn how to create this fun 2 player game made using Arduino. We will learn about WS2811 LED strip and then we will learn about the design, electronics as well as coding of this game.

Before this, we built game like Space Race Game using ArduinoTetris Game with ArduinoBuzz Wire Game with an Arduino.

So here are the components needed to make this Arcade Game project are:-

  • WS2811 LED Strip
  • Flat AHF push button X2
  • Arduino Nano
  • Buzzer
  • Li-ion battery
  • Switch
  • M3 x 50mm spacers
  • M3 x 20mm spacers
  • M3 x 10mm bolts

WS2811 LED Strip Pinout

WS2811 LED Strip Pinout

The LED strip gets power through Vcc and Gnd of WS2811 LED strip. The led strip consists of a single male connector and a female connector with its center pin as the data pin.

Now, let’s dive step by step into the making of this fun project

Designing the Acrylic Casing in SolidWorks

So, the first thing we needed to do was create a dxf file using any solidmodelling software. I chose solidWorks but well you can chose any software you like. We needed to make the design so that it is big enough to have all the 50 LEDS and the two push buttons in the led strip. It needed to have an aesthetic appeal. It also needed to have a switch button slot so that we can switch the game on and off whenever required. So after several hours of trying and testing, we finally concluded at this design.

Designing Acrylic Casing in SolidWorks

Arcade Game Laser Cutting Files

You can download the stl files by going on the circuitdigest’s led arcade game page on Thingiverse.

LED arcade game

Circuit Diagram - Interfacing WS8211 LED Strip with Arduino Nano

Circuit Diagram - Interfacing WS8211 LED Strip with Arduino Nano

The circuit diagram of the complete setup is quite simple. For the WS8211 IC. The two open wires are vcc and gnd which should be connected to 5v and gnd of Arduino. Take its female connector. Out of its three holes, the middle one is the data pin. Connect it to the digital Data out pin of Arduino (In our case, it pin no 5).

Connect one terminal of the flat push button to pin no 2 of Arduino and the other one to the ground through jumper wires. This is how you need to take wires out from the push button.

flat push button

Connect one terminal of the second flat push button to pin 3 of Arduino and the other one to ground through jumper wires.

Similarly, you can connect the (+) of buzzer to pin 7 of Arduino and the other one to ground through jumper wires.

And finally you can connect the switch between Arduino’s Vin Pin and 7.4 V li-ion battery.

Software Implementation of the LED Arcade Game

When electronics interfacing is over you need to program the Arduino Nano using Arduino IDE.

Here’s the explanation for the code for this project. You can find the complete code at the absolute bottom of the blog.

#include <FastLED.h>

This line includes the FastLED library, which provides functions for controlling addressable LED strips.

#define LED_PIN 5
#define BUZZER_PIN 7
#define NUM_LEDS 50
#define BUTTON_PIN1 2
#define BUTTON_PIN2 3
#define DELAY_MS 50
#define RED_BUTTON_FREQ 100 // Frequency for the red button sound
#define GREEN_BUTTON_FREQ 200  // Frequency for the green button sound

These lines define constant values for the pins used to connect the LED strip, buzzer, buttons, and other parameters.

CRGB leds[NUM_LEDS];

This line declares an array of CRGB objects, which represents the LED strip. It has a length of NUM_LEDS, which is set to 50.

int ledCount1 = 0; // Number of red LEDs to light up from one end
int ledCount2 = 0; // Number of green LEDs to light up from the other end
bool buttonState1 = false;
bool lastButtonState1 = false;
bool buttonState2 = false;
bool lastButtonState2 = false;
bool isRedButtonPressed = false;
bool isGreenButtonPressed = false;

These lines declare variables used to store the current and previous states of the buttons, the number of red and green LEDs to light up, and flags to indicate whether the red or green button has been pressed.

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  pinMode(BUTTON_PIN1, INPUT_PULLUP);
  pinMode(BUTTON_PIN2, INPUT_PULLUP);
  pinMode(BUZZER_PIN, OUTPUT);
}

The setup() function is called once when the Arduino board starts. It initializes the LED strip, sets the button pins as input with pull-up resistors, and configures the buzzer pin as an output.

void loop() {
  buttonState1 = digitalRead(BUTTON_PIN1) == LOW;
  buttonState2 = digitalRead(BUTTON_PIN2) == LOW;

The loop() function is called repeatedly after setup() completes. It reads the current state of the buttons connected to BUTTON_PIN1 and BUTTON_PIN2 using the digitalRead() function and updates the corresponding buttonState1 and buttonState2 variables.

if (buttonState1 != lastButtonState1) {
    if (buttonState1) {
      // Button 1 is pressed
      ledCount1++;
      if (ledCount1 > NUM_LEDS) {
        ledCount1 = NUM_LEDS;
      }
      isRedButtonPressed = true;
      tone(BUZZER_PIN, RED_BUTTON_FREQ);  // Play the red button sound
    }
    lastButtonState1 = buttonState1;
  }

This code block checks if the state of buttonState1 (the first button) has changed since the last iteration. If the button is pressed (buttonState1 is true), it increments ledCount1 and ensures it does not exceed the total number of LEDs. It also sets isRedButtonPressed to true and plays a tone on the buzzer using the tone() function with a frequency defined by RED_BUTTON_FREQ.

if (buttonState2 != lastButtonState2) {
    if (buttonState2) {
      // Button 2 is pressed
      ledCount2++;
      if (ledCount2 > NUM_LEDS) {
        ledCount2 = NUM_LEDS;
      }
      isGreenButtonPressed = true;
      tone(BUZZER_PIN, GREEN_BUTTON_FREQ);  // Play the green button sound
    }
    lastButtonState2 = buttonState2;
  }

This code block is similar to the previous one but handles the second button (buttonState2), increments ledCount2, ensures it does not exceed the total number of LEDs, sets isGreenButtonPressed to true, and plays a tone on the buzzer with a frequency defined by GREEN_BUTTON_FREQ.

FastLED.clear();

This line clears the LED strip by turning off all LEDs.

for (int i = 0; i < ledCount1; i++) {
    leds[i] = CRGB::Green;
  }

This loop sets the color of the first ledCount1 LEDs to green.

for (int i = NUM_LEDS - 1; i >= NUM_LEDS - ledCount2; i--) {
    leds[i] = CRGB::Red;
  }

This loop sets the color of the last ledCount2 LEDs to red, starting from the end of the LED strip.

if ((ledCount1 + ledCount2) >= NUM_LEDS) {
    if (ledCount1 > ledCount2) {
      greenChaserEffect();
    } else if (ledCount2 > ledCount1) {
      redChaserEffect();
    } else {
      // It's a tie
      tieChaserEffect();
    }
    ledCount1 = 0;
    ledCount2 = 0;
  }

This block of code checks if the total number of lit LEDs (ledCount1 + ledCount2) is equal to or greater than the total number of LEDs (NUM_LEDS). If it is, it determines which color has more lit LEDs and calls the corresponding function (greenChaserEffect(), redChaserEffect(), or tieChaserEffect()) to display a chasing effect on the LED strip. After that, it resets ledCount1 and ledCount2 to zero.

FastLED.show();

This line updates the LED strip with the new colors set in the previous steps.

if (isRedButtonPressed || isGreenButtonPressed) {
    delay(50);
    noTone(BUZZER_PIN);
    isRedButtonPressed = false;
    isGreenButtonPressed = false;
  }

If either the red or green button was pressed (isRedButtonPressed or isGreenButtonPressed is true), it introduces a delay to control the duration of the buzzer sound, stops the buzzer sound using noTone(), and resets the button press flags.

delay(50);

This line introduces a delay to debounce the buttons and control the response speed of the code.

void tieChaserEffect() {
  // ...
}

This is the definition of the tieChaserEffect() function, which displays a chasing effect where red and green LEDs move towards the center of the LED strip, creating a tie effect.

void greenChaserEffect() {
  // ...
}

This is the definition of the greenChaserEffect() function, which displays a chasing effect where green LEDs move from one end to the other end of the LED strip.

void redChaserEffect() {
  // ...
}

This is the definition of the redChaserEffect() function, which displays a chasing effect where red LEDs move from one end to the other end of the LED strip.

That covers the explanation of the code. Let me know if you have any further questions!

Assembly of Arcade Game with Outercase

After the Circuit diagram is complete. You need to assemble the electronics with the acrylic case and this is how it will look.

Assembly of Arcade Game

The process of building this game was lot of fun and the results were also amazing at the end. This is our team enjoying the game in the end.

If you have any doubts about this topic. Let us know in the comment section. Also, you can follow us on youtube for more such project videos and tutorials. Sayonara!

Projects Using Arduino Nano

Crafting Melodies with Arduino Tone() Function and ChatGPT's Collaborative Symphony
Crafting Melodies with Arduino Tone() Function and ChatGPT's Collaborative Symphony

Unveil the harmony of technology and creativity in our latest blog! Discover the magic of Arduino's Tone() function as we delve into crafting mesmerizing melodies through code. But that's not all – we take it a step further by inviting ChatGPT to join the symphony. Explore how AI-generated suggestions and human ingenuity harmonize to compose a collaborative masterpiece. Whether you're a tech enthusiast or a music aficionado, this blog will inspire you to bridge the gap between coding and musical artistry.

18650 Lithium Battery Capacity Tester using Arduino
18650 Lithium Battery Capacity Tester using Arduino

Join us as we delve into the world of Arduino-powered battery testing. Discover how to build an efficient 18650 Lithium Battery Capacity Tester using Arduino, allowing you to measure and evaluate battery performance with precision. Whether you're a DIY enthusiast, tech hobbyist, or someone seeking to optimize their battery usage, this blog will guide you step-by-step through the process. Learn how to harness the power of Arduino to make informed decisions about your batteries and ensure optimal device performance.

Build a DIY Oscilloscope using Arduino Nano and OLED Display
Build a DIY Oscilloscope using Arduino Nano and OLED Display

Learn how to create your very own DIY Oscilloscope using an Arduino Nano and OLED Display. Our step-by-step guide will walk you through the process of assembling and programming this budget-friendly oscilloscope, allowing you to visualize electrical signals with ease. Whether you're a student, electronics enthusiast, or just curious about tinkering, this project offers an exciting hands-on opportunity to explore waveform visualization. Join us in turning theory into practice and gain insights into electronic signals like never before.

Code

#include <FastLED.h>

#define LED_PIN 5

#define BUZZER_PIN 7

#define NUM_LEDS 50

#define BUTTON_PIN1 2

#define BUTTON_PIN2 3

#define DELAY_MS 50

#define RED_BUTTON_FREQ 100 // Frequency for the red button sound

#define GREEN_BUTTON_FREQ 200  // Frequency for the green button sound

CRGB leds[NUM_LEDS];

int ledCount1 = 0; // Number of red LEDs to light up from one end

int ledCount2 = 0; // Number of green LEDs to light up from the other end

bool buttonState1 = false;

bool lastButtonState1 = false;

bool buttonState2 = false;

bool lastButtonState2 = false;

bool isRedButtonPressed = false;

bool isGreenButtonPressed = false;

void setup() {

  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);

  pinMode(BUTTON_PIN1, INPUT_PULLUP);

  pinMode(BUTTON_PIN2, INPUT_PULLUP);

  pinMode(BUZZER_PIN, OUTPUT);

}

void loop() {

  buttonState1 = digitalRead(BUTTON_PIN1) == LOW;

  buttonState2 = digitalRead(BUTTON_PIN2) == LOW;

  if (buttonState1 != lastButtonState1) {

    if (buttonState1) {

      // Button 1 is pressed

      ledCount1++;

      if (ledCount1 > NUM_LEDS) {

        ledCount1 = NUM_LEDS;

      }

      isRedButtonPressed = true;

      tone(BUZZER_PIN, RED_BUTTON_FREQ);  // Play the red button sound

    }

    lastButtonState1 = buttonState1;

  }

  if (buttonState2 != lastButtonState2) {

    if (buttonState2) {

      // Button 2 is pressed

      ledCount2++;

      if (ledCount2 > NUM_LEDS) {

        ledCount2 = NUM_LEDS;

      }

      isGreenButtonPressed = true;

      tone(BUZZER_PIN, GREEN_BUTTON_FREQ);  // Play the green button sound

    }

    lastButtonState2 = buttonState2;

  }

 

  // Turn off all LEDs

  FastLED.clear();

 

  // Light up the specified number of red LEDs from one end

  for (int i = 0; i < ledCount1; i++) {

    leds[i] = CRGB::Green;

  }

 

  // Light up the specified number of green LEDs from the other end

  for (int i = NUM_LEDS - 1; i >= NUM_LEDS - ledCount2; i--) {

    leds[i] = CRGB::Red;

  }

 

  if ((ledCount1 + ledCount2) >= NUM_LEDS) {

    if (ledCount1 > ledCount2) {

      greenChaserEffect();

    } else if (ledCount2 > ledCount1) {

      redChaserEffect();

    } else {

      // It's a tie

      tieChaserEffect();

    }

 

    // Reset the LED counts

    ledCount1 = 0;

    ledCount2 = 0;

  }

 

  // Show the updated LED strip

  FastLED.show();

 

  if (isRedButtonPressed || isGreenButtonPressed) {

    delay(50); // Adjust this delay to control the duration of the buzzer sound

    noTone(BUZZER_PIN); // Stop the buzzer sound

    isRedButtonPressed = false;

    isGreenButtonPressed = false;

  }

 

  delay(50); // Adjust this delay to debounce the buttons and control the response speed

}

 

void tieChaserEffect() {

 

  for (int i = 0; i < NUM_LEDS / 2; i++) {

    leds[i] = CRGB::Red;  // Set the color of the current LED to red

    FastLED.show();       // Update the LED strip

    delay(DELAY_MS);      // Wait for a short period

  }

 

  for (int i = NUM_LEDS; i >= NUM_LEDS / 2; i--) {

    leds[i] = CRGB::Green;  // Set the color of the current LED to red

    FastLED.show();       // Update the LED strip

    delay(DELAY_MS);      // Wait for a short period

  }

}

 

void greenChaserEffect() {

  // Set all LEDs to green initially

  for (int i = 0; i < ledCount1; i++) {

    leds[i] = CRGB::Green;

  }

  FastLED.show();  // Update the LED strip with the initial green color

 

  for (int i = ledCount1; i < NUM_LEDS; i++) {

    leds[i] = CRGB::Green;  // Set the color of the current LED to red

    FastLED.show();       // Update the LED strip

    delay(DELAY_MS);      // Wait for a short period

  }

}

 

void redChaserEffect() {

  // Set all LEDs to green initially

  for (int i = NUM_LEDS - 1; i >= NUM_LEDS - ledCount2; i--) {

    leds[i] = CRGB::Red;

  }

  FastLED.show();  // Update the LED strip with the initial green color

 

  for (int i = ledCount2; i > 0; i--) {

    leds[i] = CRGB::Red;  // Set the color of the current LED to red

    FastLED.show();       // Update the LED strip

    delay(DELAY_MS);      // Wait for a short period

  }

}

Have any question realated to this Article?

Ask Our Community Members