Introduction: The Party Box - Basic (Spin Your Disco Ball and More)

About: Trying to make hobbying my profession

This is the quick, easy to throw together party accessory you didn't know you needed.

I've made it on 2 occasions for house parties, when the urge strikes to make something. Luckily for you all, this time I kept it so I can show you how it's done :)

You will need:

  1. Arduino Power source - Battery bank + USB cable is ideal, or just a (probably very long) USB cable plugged into any powered USB port
  2. Arduino
  3. Continuously rotational servo *
  4. Disco Ball
  5. Breadboards and jumper cables (I'll be using a protoshield because I have it on hand, but you can easily do this without)
  6. Firefly string (because normal wires/string just aren't as cool)
  7. Cableties/rubberbands/dentalfloss/whatever-you-have-on-hand if you got to do this on the fly and have the other ingredients lying around.

*The other type of servo can be made continuously rotational by hacking the potentiometer. I did this the first time and it worked, but obviously a normal continuously rotational one would be preferable. If you only have a motor, you could use PWM from the Arduino to achieve similar results.

Optionally you may want individually addressable LED strips (maybe WS2812), other LED's, lasers or whatever additions you may wish to add on.

One day, I'll create the Party Box 9000. The plug 'n play advanced version I've got envisioned. Maybe I'll make it in time for the upcoming Mozamboogy party.

Step 1: Basic Assembly

The focus of your assembly should be on weight distribution.

Your disco ball is heavy and if you are creating a setup like mine, you will need to distribute the weight as centrally as possible.

So, from beneath your battery bank, you will want the centre of your servo to be roughly centred.

The Arduino will be cable tied (or attached through other means) to the battery bank (if it is made of a conductive material, you may wish to put a piece of plastic between it and the battery bank to insulate it and prevent shorts or other weird behaviour), and the breadboard too. In this version I made, I used the protosheild and breadboard so everything is cable tied to the one side of the battery bank. It's all light enough that it didn't make much of a difference with regards to weight distribution.

To prevent the servo from slipping down, I have attached it to the horizontal cable tie with a wire tie thing, but you can use cable ties or whatever, or some mirror tape and and secure it using the cable tie that holds your Arduino on.

If your disco ball is larger/heavier, you may wish to cable tie both horizontally and vertically, although for me, this wasn't necessary.

A short USB cable is recommended for best aesthetics.

Connect the firefly string to the 5v and ground, (creating a 5v and GND rail on the breadboard if you need to. I did, because my firefly wire was previously soldered onto header pins from last time - If you don't have a protosheild and are just using a breadboard, you will want to do this too)

Firefly string is obviously not a necessity, but if you can, it beats using string or something to hang your device. Since I have some, I consider it a necessity :D

Step 2: Additional Components

Downfacing lighting - I've added one (but add as many as you would like I say!) bright white LED facing downwards towards the disco ball. I put a 330ohm resistor between the 5v and a breadboard rail, and then the LED between that and GND and pointed it downwards. Would be great to have a bright ring of these - make one. I shall not because it's getting late and I have things to do tomorrow. I want to publish this tonight - I may be repurposing components tomorrow.

Individually addressable LEDs (WS2812B) - I've added a strip of individually addressable LED's that are rather short in this example (because I have used most of them elsewhere) but you can make your strip pretty long - just adjust the code accordingly. I've done a couple of meters in the past of 60 leds per meter. Apparently capping off around 512 pixels long, but I've not fact checked this.

Laser - I had a laser which I've never tried on anything so I attached it to the 3.3v and GND and orientated it towards the disco ball too. It created little trails on the wall after reflecting off the disco ball.

Step 3: Some Code to Make Everything Run

Here is the code I used - Please adjust for the amount of individually addressable LED's you want and the patterns you want (their functions are below the rest of the code. I've only included my favourites), the servo speed, etc.

I've attached my servo data pin to the digital port 9, and my LED strip data pin to digital port 10. If you wanna blink your downward facing LEDs, go ahead and add in some code for that and pin your LED into appropriate digital ports. If you have a logic converter, you can do that for your 3.3v laser too.


To make your life easy, I've made the variables you are most likely to adjust accessible at the top of the code.

To compile this you will need the FastLED library, and if you don't have it, the servo library (but I think it's standard)

<p>//Variables<br>#define DISCO_SERVO 9
#define SERVO_SPEED 3
//Strip of ws2812b
#define LED_PIN   10
#define NUM_LEDS  30</p><p>//Disco ball servo 
#include <servo.h>
Servo myservo;</servo.h></p><p>//LED strip
#include <fastled.h></fastled.h></p><p>FASTLED_USING_NAMESPACE
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif</p><p>//LED config - adjust accordingly
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define BRIGHTNESS         125
#define FRAMES_PER_SECOND  120
CRGB leds[NUM_LEDS];</p><p>void setup() {
  //Setup Disco ball servo
  myservo.attach(DISCO_SERVO);</p><p>  //FastLed Setup
  delay(3000); // 3 second delay for recovery
  
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<led_type,led_pin,color_order>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<led_type,data_pin,clk_pin,color_order>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);</led_type,data_pin,clk_pin,color_order></led_type,led_pin,color_order></p><p>  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);</p><p>}</p><p>// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
//add the patterns you'd like here
SimplePatternList gPatterns = { confetti, sinelon, juggle, bpm };
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
 </p><p>void loop() {
  //Setup Disco ball servo
  myservo.attach(DISCO_SERVO);
  myservo.write(90+SERVO_SPEED);</p><p>// Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();</p><p>  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND); </p><p>  // do some periodic updates
  EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
  EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
}</p><p>#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))</p><p>void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}</p><p>void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}</p><p>void rainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}</p><p>void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}</p><p>void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}</p><p>void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);
}</p><p>void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
  }
}</p><p>void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}</p>

Step 4: Test and Hang Your Self Contained Party Box Basic

It's probably best to do this all before plugging it into the battery bank, powering the device.

Test that everything works to your liking, find a place from which you can hang your device. Eg. put a hook in the ceiling (should you be allowed to) or find a curtain rail or something.

I used a big bulldog clip and some rubber bands to secure the battery bank and Arduino etc to the firefly string - adjusting so that it hangs straight - and hung the firefly string from the hook in the ceiling.

Hang your disco ball from the servo arms.

Plug in the USB to power the device and let the party begin! Or continue... now with all this additional stimuli!

Party Challenge

Participated in the
Party Challenge