Arduino LED Pong V2.0 - Let There Be LIGHT!

by NewsonsElectronics in Circuits > Arduino

170 Views, 2 Favorites, 0 Comments

Arduino LED Pong V2.0 - Let There Be LIGHT!

DSC_0080.JPG
DSC_0081.JPG
Arduino LED Pong V2.0 | Fun Electronics Project – Part 2: Build Video

In this tutorial, I’ll guide you through my new and improved LED Pong Version 2.0. This updated design is only 6mm thick and significantly more affordable than my first version, as I plan to mass-produce it for one of my school’s ECA projects. I’ve also enhanced the gameplay: now you can hold down to charge an LED, and the longer you hold it, the faster it will bounce toward your opponent. Whether you’re a beginner or have some experience with Arduino, this guide will walk you through all the steps you need to get started!

Build Video

Design Video

Cad files

Supplies

IMG20251019165057.jpg
cost breakdown.jpg
Electronic Diagram.png

Cut Out the Wood

1. Laser cutting.jpg

Download the CAD file and cut out the main wood board Cad files

Insert the Buttons and Speaker

2. Buttons.jpg
3. Speaker.jpg


Gently insert the two push buttons using a rubber mallet, ensuring they fit securely. If they do not fit properly, adjust the tolerance of the hole dimensions in the wood. Make sure the buttons are oriented correctly.

Next, insert the speaker and ensure the wires are positioned in the correct direction.

Insert LED Strip

4. LED strip.jpg
5. Power switch.jpg

Cut a section of 7 LEDs from the addressable LED strip. Remove the 3M adhesive backing and carefully bend the ends so they fit through each of the slots. Make sure the arrows on the strip are pointing in the correct direction.

Next, insert the small switch.

Solder the GND Wires

6. Solder GND on button.jpg
7. GND of speaker wire to switch.jpg

Using a piece of copper wire, solder one of the push button LEDs to the GND terminal of the LED strip.

Next, solder the black ground wire from the speaker to one of the LED terminals on the power switch.

Solder 3PIN to D4,5,6

8. Digital pins on Nano.jpg
9. power to GND and 3 pins to LED strip.jpg

Solder three pins to digital ports 4, 5, and 6 on the Arduino Nano. Once soldered, bend the pins horizontally so they can be connected to the LED strip contacts for GND, DATA, and 5V.

Insert the switch pin into the GND port of the Arduino Nano.

Solder Speaker

10. Solder GND to LED strip for second push button.jpg
12. Solder Speaker + to D13.jpg

Solder the second leg of the button to GND.

Solder the positive wire of the speaker to digital pin 13.

Solder D2 to the push button.


Solder Button Sense Pins

11. Solder D2 to button leg.jpg
13. Solder A1 to button.jpg

Solder D2 to the right push button

Solder A1 to the left push button

Solder Battery Charger

14. Solder battery charger.jpg
15. Glue on battery and charger.jpg

Solder the positive and negative wires of the 3.7V battery to the TP4056 battery charger.

Using thicker wire, solder the positive wire to the 3-pin terminal of the power switch and the negative wire to VIN on the Arduino Nano.

Apply a small amount of hot glue under the charger and battery to secure them to the board.

Upload the Code

16. upload code.jpg
DSC_0080.JPG

Plug in the board and open up Ardunio IDE to download the code,


If you are interested in the design process check out this video. Design Video


// Newson's Electronics
// October 20,2025


void (*resetFunc)(void) = 0;

unsigned long previousMillis = 0UL;
unsigned long interval = 500UL;
unsigned long storeInterval = 500UL;
int buttonState = 1;
int buttonState2 = 1;

#include <Adafruit_NeoPixel.h>
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN 5

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 7

int soundA = 800;
int soundB = 1000;
int brightness = 5;
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// --- Define colors as variables ---
uint32_t red = strip.Color(255, 0, 0);
uint32_t green = strip.Color(0, 255, 0);
uint32_t blue = strip.Color(0, 0, 255);
uint32_t yellow = strip.Color(255, 255, 0);
uint32_t purple = strip.Color(255, 0, 255);
uint32_t cyan = strip.Color(0, 255, 255);
uint32_t white = strip.Color(255, 255, 255);

const int button1 = A1; // the number of the pushbutton pin
const int button2 = 2; // the number of the pushbutton pin
int dir = 1;
int pos = 2;
int A = 1;
int B = 1; //no bounce
int score1 = 0;
int score2 = 0;
int bounce = 0;


// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
Serial.begin(9600);

pinMode(4, OUTPUT);
pinMode(6, OUTPUT);
digitalWrite(6, LOW);
digitalWrite(4, HIGH) ;

pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.

strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(15); // Set BRIGHTNESS to about 1/5 (max = 255)

// up
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, green);
strip.show();
delay(100);
}
// --- Turn off LEDs one by one (same direction) ---
for (int i = 0; i < LED_COUNT; i++) {
strip.setPixelColor(i, 0, 0, 0); // Turn LED off
strip.show();
delay(100);
}
}


// loop() function -- runs repeatedly as long as board is on ---------------


void scoreFlash() {
bounce = 0;
interval = storeInterval;
brightness = 5;
strip.setBrightness(brightness);

for (int i = 0; i <= 5; i++) {
if (pos < 0) strip.setPixelColor(0, red);
if (pos > 6) strip.setPixelColor(6, red);
strip.show();
delay(100);
//tone(8, 1000, 50);
tone(13, 100, 100);

strip.clear();
strip.show();
delay(100);
tone(13, 200, 100);
}

//show score 2
if (pos < 0){
for (int i = 0; i <= score2; i++)
strip.setPixelColor(LED_COUNT-i, blue);
strip.show();
delay(500);
}

//show score 1
if (pos == LED_COUNT){
for (int i = 0; i < score1; i++)
strip.setPixelColor(i, blue);
strip.show();
delay(500);
}


// winner flash
if (score1==7||score2==7)
{
for (int i = 0; i <= 10; i++) {
if (score1==7)strip.setPixelColor(0, blue);
if (score2==7)strip.setPixelColor((LED_COUNT-1), blue);
strip.show();
tone(13, 1440, 50);
delay(100);
strip.clear();
strip.show();
noTone(13);
delay(100);
}


rainbowCycle(50);


//reset the game
score1=0;
score2=0;
interval = 500UL;
storeInterval = 500UL;
}
// if winner

strip.clear();

delay(500);
}
int vccValue=0;
int vccValue2=0;
void loop() {
unsigned long currentMillis = millis();
buttonState = digitalRead(button1);
buttonState2 = digitalRead(button2);



Serial.print(buttonState);
Serial.print(",");
Serial.print(buttonState2);
Serial.print(score1);
Serial.print(",");
Serial.println(score2);


if (buttonState == 0 && pos > 2 && A == 1) {
dir = -1;
A = 0;
strip.setBrightness(5);

if (bounce == 1) {

bounce = 0;
interval = storeInterval;
}
if (interval > 40) interval = interval - 5;

if (pos == 6) {

//catch and hold
bounce = 1;
storeInterval = interval;
interval = 60;

while (buttonState == 0) {
buttonState = digitalRead(button1);
strip.setPixelColor(pos, blue);
brightness += 1;
if (brightness > 50) brightness = 0;

interval = 80 - brightness;
strip.setBrightness(brightness);
strip.show();
delay(50);
}
}
}
if (buttonState2 == 0 && pos < 4 && B == 1) {
dir = 1;
B = 0;
strip.setBrightness(5);
if (bounce == 1) {
bounce = 0;
interval = storeInterval;
}
if (interval > 40) interval = interval - 5;

if (pos == 0) {
bounce = 1;
storeInterval = interval;
interval = 60;
while (buttonState2 == 0) {
buttonState2 = digitalRead(button2);
strip.setPixelColor(pos, blue);
brightness += 1;
if (brightness > 50) brightness = 0;

interval = 80 - brightness;
strip.setBrightness(brightness);
strip.show();
delay(50);
}
}
}
//reset the push button can hold it down.
if (buttonState == 1) A = 1;
if (buttonState2 == 1) B = 1;


if (currentMillis - previousMillis > interval) {


strip.clear();
pos = pos + dir;
if (dir == 1) tone(13, soundB, 50);
if (dir == -1) tone(13, soundA, 50);
strip.setPixelColor(pos, green);
if (pos == 0 || pos == 6) strip.setPixelColor(pos, red);
//if (pos==1 || pos==5) strip.setPixelColor(pos, yellow);

if (bounce == 1) strip.setPixelColor(pos, blue);
strip.show();

if (pos > 6) {
dir = -1;
score1 += 1;
scoreFlash();
}
if (pos < 0) {
dir = 1;
score2 += 1;
scoreFlash();
}


previousMillis = currentMillis;
}
//strip.clear();
}




void rainbowCycle(uint8_t wait) {
for (int j = 0; j < 256; j++) { // cycle through color wheel
for (int i = 0; i < LED_COUNT; i++) {
int pixelHue = (i * 256 / LED_COUNT + j) & 255;
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue * 256)));

}
strip.show();
delay(wait);
}
}