New Year's ball drop on an Arduino Uno
Press the button and a servo lowers a ball of LEDs over the last ten seconds, beeping each second, then the ball bursts into a rainbow and a piezo cheers. The whole build, an Arduino Uno and 5 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Beginner Runs in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// New Year's ball drop: a ball of LEDs on a servo arm comes down over the
// last ten seconds, with a beep for every second, then lights up in a burst
// of color as the new year arrives.
//
// button pin 2 -> button -> GND (INPUT_PULLUP, pressed reads LOW)
// servo PWM -> pin 9, VCC -> 5 V, GND -> GND
// piezo pin 8 -> piezo -> GND
// ball 12 WS2812B LEDs in a ring, DIN <- 330 ohms <- pin 6
//
// Press the button and the countdown starts. The servo moves from 180 degrees
// (the top of the pole) to 0 (the bottom) in small steps across ten seconds,
// so the ball glides rather than jumping once a second. The last three beeps
// are higher, the way a crowd gets louder at "three, two, one".
//
// Build it with a ping-pong ball or a small plastic ornament around the LED
// ring, hung on a thread from the servo horn, or mount the servo at the top
// of a cardboard pole and let the arm lower the ball.
//
// Things to try. Change COUNT_FROM to 60 for a full minute. Write your own
// tune into CHEER.
#include <Servo.h>
#include <Adafruit_NeoPixel.h>
const int BUTTON_PIN = 2;
const int SERVO_PIN = 9;
const int PIEZO_PIN = 8;
const int BALL_PIN = 6;
const int LEDS = 12;
const int COUNT_FROM = 10;
const int TOP = 180, BOTTOM = 0;
Servo pole;
Adafruit_NeoPixel ball(LEDS, BALL_PIN, NEO_GRB + NEO_KHZ800);
const int CHEER[] = {523, 659, 784, 1047, 784, 1047};
const int CHEER_MS[] = {120, 120, 120, 300, 120, 500};
bool running = false;
unsigned long startedAt = 0;
int lastSecondShown = -1;
unsigned long celebrateUntil = 0;
void glow(uint8_t r, uint8_t g, uint8_t b) {
for (int i = 0; i < LEDS; i++) ball.setPixelColor(i, r, g, b);
ball.show();
}
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pole.attach(SERVO_PIN);
pole.write(TOP);
ball.begin();
ball.setBrightness(150);
glow(40, 40, 60); // a soft silver while it waits
Serial.println("Ball at the top. Press the button to start the countdown");
}
void loop() {
unsigned long now = millis();
if (!running && celebrateUntil == 0 && digitalRead(BUTTON_PIN) == LOW) {
running = true;
startedAt = now;
lastSecondShown = -1;
glow(120, 120, 160);
Serial.println("Countdown started");
}
if (running) {
unsigned long t = now - startedAt;
unsigned long total = (unsigned long)COUNT_FROM * 1000;
if (t >= total) {
running = false;
pole.write(BOTTOM);
Serial.println("Happy New Year!");
for (int n = 0; n < 6; n++) {
tone(PIEZO_PIN, CHEER[n], CHEER_MS[n]);
delay(CHEER_MS[n] + 30);
}
celebrateUntil = millis() + 8000;
return;
}
// Glide: the angle follows the clock, not the beeps.
pole.write(TOP - (int)((long)(TOP - BOTTOM) * t / total));
int second = COUNT_FROM - (int)(t / 1000);
if (second != lastSecondShown) {
lastSecondShown = second;
Serial.println(second);
tone(PIEZO_PIN, second <= 3 ? 1760 : 880, 80);
}
}
// After midnight: the ball spins through the rainbow for a while.
if (celebrateUntil > 0) {
if (now < celebrateUntil) {
ball.rainbow((uint16_t)(now * 40));
ball.show();
} else {
celebrateUntil = 0;
glow(40, 40, 60);
pole.write(TOP);
Serial.println("Ball back at the top");
}
}
}
Parts list
7 parts, plus the jumper wires. Every one is in the editor's parts bin.
- 1 × Arduino Uno R3
- 1 × Half breadboard
- 1 × Pushbutton
- 1 × Resistor, 330 Ω
- 1 × Piezo speaker
- 1 × Addressable RGB LEDs
- 1 × Hobby servo
How it is wired
7 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 9; Hobby servo pin PWM
- Arduino Uno R3 pin 8; Piezo speaker pin 1
- Arduino Uno R3 pin 6; Resistor, 330 Ω pin 1
- Arduino Uno R3 pin 2; Pushbutton pin 1a
- Arduino Uno R3 pin 5V; Addressable RGB LEDs pin VDD; Hobby servo pin VCC
- Ground: Arduino Uno R3 pin GND; Pushbutton pin 2a; Piezo speaker pin 2; Addressable RGB LEDs pin VSS; Hobby servo pin GND
- Resistor, 330 Ω pin 2; Addressable RGB LEDs pin DIN
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.