I may not be the best dancer but at least I can make a robot that can groove. This project is a mashup between the Make Your Own Gears and Make Your Own Slinky projects.
Here is the list of tools and materials you'll need to get going.
Standard Servo Motor with Servo Horn and screws
Access to a 3D Printer
Six M3 nuts and bolts
Soldering Iron
5 volt battery. I used one of those portable cell phone battery chargers.
Micro usb cable.
Download and print the stl files from here.
The Circuit Playground comes with alligator friendly pins which make it great for quick prototypes but we're going for a more secure and permanent connection so we will solder the wires to the pins instead.
Solder the components based on the image below. I would have used Fritzing or 123Circuits but neither had the Circuit Playground as a component so MS Paint it is.
The wiring is as follows:
VBatt from Circuit Playground connects to 5v DC Power on Neopixel Ring and Power input on Servo Motor.
Ground from Circuit Playground Connects to Ground on Neopixel Ring and Ground wire on Servo Motor.
Pin 9 on Circuit Playground connects to signal wire on Servo Motor.
Pin 12 on Circuit Playground Connects to Data In on Neopixel Ring.
Attach servo motor to the 3D printed frame with the four M3 nuts and bolts. Make sure to not over tighten as this will cause the frame to bow.
Next, attach the servo horn to the 3D printed gear using two small screws. These sometimes come with your servo motors. If not, any small screws that fit in the servo horn holes should work.
Attach the servo horn and gear assembly to the servo motor using the servo motor screw that's attached to your motor.
Complete assembly by attaching springs to the frame using the bushing and pins to secure it to the bottom of the frame and the top rod to secure it to the top of the frame.
Watch between 3:52 and 5:05 of the video below to see how all the parts are assembled.
Power is supplied with a micro usb cable. To make it portable you can simply use 5V battery charger pack that is used to charge cell phones.
My big aha! moment with Fusion 360 happened when I finally understood how to use Constraints. Get my free Fusion 360 Constraint Cheat Sheet and see what I mean.
Copy and paste the following Arduino code and you should be good to go.
For the first few seconds try not to make any noise as the program will sample the background noise to calculate the average noise level. It then relies on the set threshold to determine whether to start dancing. The threshold is set to 20 in the code below but feel free to experiment with what works best for your environment.
Here is the Arduino Code I used. You can copy and paste in your editor. Watch the above video from 13:55 onwards to see a brief explanation of the code and required libraries.
// Program to move servos and control neopixels in response to sound using the Adafruit Circuit Playground.
#include <Adafruit_TiCoServo.h> // Need to include in order to control neopixels and servos together
int r = 0; // Declare variables for red, blue, green, and white colors. int g = 0; int b = 0; int w = 0; int numLeds = 10; // Number of neopixels in the Circuit Playground
int value = 0; // variable that will store raw sound values int soundLevel = 0; int threshold;
int pos; // variable to store servo position int increment= 2; // the value to increment or decrement servo position int interval = 12; // variable that will control the amount of milliseconds to wait between servo movements long previousMillis = 0; //variable to capture time
Adafruit_TiCoServo servo; // Create servo object
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);
void setup() { //Serial.begin(9600); CircuitPlayground.begin(); strip.begin(); strip.setBrightness(255); CircuitPlayground.clearPixels(); CircuitPlayground.setBrightness(255); servo.attach(SERVO_PIN);
servo.write(90); strip.show();
for(int x = 0; x<5; x++) //Get 5 background sound readings and calculate the average { value = value + CircuitPlayground.soundSensor(); delay(500); //Serial.println(value); } soundLevel = value/5; // Calculate Average and store it in soundLevel //Serial.println("Average"); //Serial.println(soundLevel); threshold = soundLevel + 20;
}
void loop() { value=CircuitPlayground.soundSensor(); // Read raw sound data and store it in value if(value > threshold) { /////Servo Part if((millis()-previousMillis) > interval) { previousMillis = millis(); pos += increment; servo.write(pos); if((pos <= 0) || (pos >= 180)) { increment = -increment; // Reverse servo direction } for(int i =0; i<numLeds; i++) { CircuitPlayground.setPixelColor(i, pos, g, 180-pos); //Sets red and blue levels on Circuit Playground to servo position. Green remains 0 for(int p =0; p<12; p++) { strip.setPixelColor(p, pos, g, 180-pos,0); //Does the same for the Neopixel Ring // delay(2); } } strip.show(); } } }