Disco Gear Cube




Introduction: Disco Gear Cube

This instructable was created in fulfillment of the project requirement of the Makecourse at the University of South Florida (www.makecourse.com)

The Disco Gear cube was a simple idea, take a motorized gear cube, and add lighting effects as well as more control. My final version may not have worked as well as I hoped, but it can be used as a stepping stone for designing a fully working model.
This was my attempt at making a disco ball but with the standard gear cube.
Step Zero: Get all your materials

a 5mm threaded rod
3/16 inch diameter flexible tube
JB weld or an other strong adhesive



the motor kit






motor control


laser diode


emmett's gear cube

dougc314's motor assembly


My files

Neo pixel library

keypad library


Step 1: Placing Internal Parts

in the case of the mount for the motor, there is a small nub at the bottom of the project box, I JB-welded the mount so that it rested on top of the numb, mostly centering the motor.

Step 2: Setting Up the Hobby Box

I formed ports for the power, the control pad, Arduino power and the lights by drilling multiple interconnected holes.

Step 3: Understanding the Wireing

I placed the motor control and bread board on the back wall.

The lights and laser diode wires were fed through the front port. The control wires through the right port. Power through the left. While the Arduino sticks out of the bottom right port in the front.

Each board is held on by Velcro. The Arduino is oriented so that the digital pins are up against the right wall, while the motor control chip is oriented so the power is against the wall and the heat sink is just above the floor.

The circuit is fairly simple. The 8 pins for the 4x4 are attached to digital pins 2-9.

Step 4: The Drive Shaft

I drilled out the drive shaft so the 5mm rod could screw in, I then added JB weld to hold the connection. I used about 5mm of 3/16 ID tubing to connect the drive shaft and the motor, I then used a small hose clamp to tighten the connection.

This extended shaft went through the spacers and the motor base (more in next step)

Step 5: Topping It Off

Each spacer has a 1.5 inch hole drilled through the middle as well as two small holes for nuts and bolts, matching the holes in the hobby box.

During the final gluing, I covered the cube base with JB weld, then put it over the drive shaft, and adjusted the position until the drive shaft was at perpendicular as possible.

Step 6: Finishing It Up

After the JB weld dried I used spray adhesive to attach the light stand. I then glued each laser diode into one of the mounting holes, and attached the lights with zip ties.

The stand just acts as a way of holding the LEDs and diodes, you will probably need to sand out the small holes.

Step 7: The Coding I Used, It Is a Little Jumbled But the Final File


#include #ifdef __AVR__ #include #endif

#define MOTORSPEED 13

#define MOTOR_DIRECTION_1 12 #define MOTOR_DIRECTION_2 11

#define LIGHT1 16 #define LIGHT2 17 #define LIGHT3 18

#define PIXEL_PIN 10 // Digital IO pin connected to the NeoPixels. #define PIXEL_COUNT 60

// Parameter 1 = number of pixels in strip, neopixel stick has 8 // Parameter 2 = pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_RGB Pixels are wired for RGB bitstream // NEO_GRB Pixels are wired for GRB bitstream, correct for neopixel stick // NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels) // NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); const byte ROWS = 4; //4 rows const byte COLS = 4; //4 columns char keys[ROWS][COLS] = {//maps the control pad {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} };

byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad byte colPins[COLS] = {5,4,3,2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); bool light1State = HIGH; bool light2State = HIGH; bool light3State = HIGH;

bool motorDirection = HIGH;

int showType = 0; uint16_t pixelIndex = 0; uint16_t chaseIndex = 0; uint16_t colorCycleIndex = 0;

char currentColorKeyValue; //set up for motor and diodes void setup() { strip.begin(); strip.show(); // Initialize all pixels to 'off' Serial.begin(9600); pinMode(MOTORSPEED, OUTPUT);//make two output pins pinMode(MOTOR_DIRECTION_1, OUTPUT); pinMode(MOTOR_DIRECTION_2, OUTPUT); pinMode(LIGHT1, OUTPUT); pinMode(LIGHT2, OUTPUT); pinMode(LIGHT3, OUTPUT); digitalWrite(MOTOR_DIRECTION_1, motorDirection); digitalWrite(MOTOR_DIRECTION_2, ! motorDirection);

} //this loop runs the motor and the laser diodes void loop() { analogWrite(MOTORSPEED,150); digitalWrite(LIGHT1, light1State); digitalWrite(LIGHT2, light2State); digitalWrite(LIGHT3, light3State); digitalWrite(MOTOR_DIRECTION_1, motorDirection); digitalWrite(MOTOR_DIRECTION_2, motorDirection);

char key = keypad.getKey(); if (key){ Serial.println(key); if (key >= '0' && key <= '9') { currentColorKeyValue = key; }//this will set the A,B,C and D to their respective commands if (key >= 'A' && key <= 'D') { switch(key) { case 'A': light1State = ! light1State; break; case 'B': light2State = ! light2State; break; case 'C': light3State = ! light3State; break; case 'D': motorDirection = ! motorDirection; break; } } } if (currentColorKeyValue) { runShow(currentColorKeyValue); } } //the fallowing does the same thing but for the strip LED animations void runShow(char i) { switch(i){ case '0': colorWipe(strip.Color(0, 0, 0), 50); // Black/off break; case '1': colorWipe(strip.Color(255, 0, 0), 50); // Red break; case '2': colorWipe(strip.Color(0, 255, 0), 50); // Green break; case '3': colorWipe(strip.Color(0, 0, 255), 50); // Blue break; case '4': theaterChase(strip.Color(0, 255, 0), 50); // green break; case '5': theaterChase(strip.Color(255, 0, 0), 50); // Red break; case '6': theaterChase(strip.Color( 0, 0, 255), 50); // Blue break; case '7': rainbow(20); break; case '8': rainbowCycle(20); break; case '9': theaterChaseRainbow(50); break;

} }//The fallowing is all preloaded animations by AdaFruit. they have some commenting. void clearPixelStrip() { pixelIndex = 0; for (uint16_t i = 0; i < PIXEL_COUNT; i++) { strip.setPixelColor(i, strip.Color(0, 0, 0)); } strip.show(); } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { if (pixelIndex == PIXEL_COUNT) { pixelIndex = 0; } strip.setPixelColor(pixelIndex, c); strip.show(); delay(wait); pixelIndex++; }

void rainbow(uint8_t wait) {

if (colorCycleIndex == 256) { colorCycleIndex= 0; } for (int i = 0; i < PIXEL_COUNT; i++) strip.setPixelColor(i, Wheel((i + colorCycleIndex) & 255)); strip.show(); delay(wait); colorCycleIndex++; }

// Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) {

if (colorCycleIndex == 256 * 5) { colorCycleIndex= 0; } for (int i = 0; i < PIXEL_COUNT; i++) { strip.setPixelColor(i, Wheel(((i * 256 / PIXEL_COUNT) + colorCycleIndex) & 255)); } strip.show(); delay(wait); colorCycleIndex++; }

//Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { if (chaseIndex == 10) { chaseIndex = 0; } for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show();


for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } chaseIndex++; }

//Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) {

if (colorCycleIndex == 256 * 5) { colorCycleIndex= 0; } for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, Wheel( (i+colorCycleIndex) % 255)); //turn every third pixel on } strip.show();


for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } colorCycleIndex++; }

// Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); }

Step 8: A Note on Finish Prints

I used Bill Doran's methods for finishing the cube

I airbrushed on a near mirror chrome finish, but my lacquer pulled up the dry paint exposing the black backer.

Be the First to Share


    • Metalworking Contest

      Metalworking Contest
    • Maps Challenge

      Maps Challenge
    • Tinkercad Student Design Contest

      Tinkercad Student Design Contest



    3 years ago

    This is neat :) I'd love to see what it looks like when it's on!