Arduino | Animate Shield Code
Overview
The following code is what we include preloaded on our Animate shield/Arduino board. If you decide to modify or upload your own code to your board, you can always grab this code and upload it to your Arduino.Upload the default code below using the Board Reset Tool
The Code
// Make Stuff Move | Animate Shield v8.0 // This is the code that comes preloaded on our animate shield/Arduino board combo int VERSION = 2; #include <Adafruit_NeoPixel.h> #include <Servo.h> #include <EEPROM.h> // Setup the LED #define LED_PIN 7 #define LED_COUNT 1 Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); #define MIC_PIN A5 int mic_value; int curr_level = 0; int prev_level = 0; int servo_level = 0; int light_level = 0; int is_beat = 0; int mic_cut_default = 180; int mic_cut = 180; // min and max values from the sensor int vol_min = 300; int vol_max = 600; // Cabibration of min and max values from analog #define ANALOG_MAX 1023 #define ANALOG_MIN 0 #define SERVO_MIN 2 #define SERVO_MAX 178 // Delay between reading for recording movement int frame = 0; int playSpeed = 50; // in ms, 50ms seems good #define FRAME_DELAY 50 // in ms, 50ms seems good #define FRAME_LIMIT 1024 // number of samples to store // Arduino Pin assignments int recordButtonPin = 12; int playButtonPin = 11; int ledPin = 13; int ledState = 0; int servoPinA = 8; int servoPinB = 9; int servoPinC = 10; int knobPinA = A0; int knobPinB = A1; int knobPinC = A2; // Variables for record/play state int repeat = 1; int playing = 0; int recording = 0; long pressTime = 0; // Create the servo objects Servo myServoA; Servo myServoB; Servo myServoC; void setup() { Serial.begin(9600); Serial.println("Make Stuff Move | 3 Servo Record and Play"); pinMode(recordButtonPin, INPUT); digitalWrite(recordButtonPin, HIGH); pinMode(playButtonPin, INPUT); digitalWrite(playButtonPin, HIGH); pinMode(ledPin, OUTPUT); pinMode(knobPinA, INPUT); pinMode(knobPinB, INPUT); pinMode(knobPinC, INPUT); myServoA.attach(servoPinA); myServoB.attach(servoPinB); myServoC.attach(servoPinC); //Light strip.begin(); strip.show(); versionBlink(VERSION); } void loop() { // Check for the play button being clicked or held if (digitalRead(playButtonPin) == LOW) { pressTime = 0; while (digitalRead(playButtonPin) == LOW) { delay(1000); pressTime = pressTime + 1; } if (pressTime < 2) { Serial.println("PLAY ONLY"); playServos(playButtonPin); } else { Serial.println("PLAY DANCE"); playServosDance(playButtonPin); } pressTime = 0; } // Check for Record button else if (! digitalRead(recordButtonPin)) { delay(10); // wait for released while (! digitalRead(recordButtonPin)) { delay(100); // OK released! } Serial.println("RECORD"); recordServos(recordButtonPin); } // Otherwise just read the knobs to move the servos else { moveServos(); } } // Move Function ------------------------------------------------------------------------- void moveServos() { // Read the value from the mic int mic_value = analogRead(MIC_PIN); //Serial.print("MIC | "); //Serial.println(mic_value); curr_level = map(mic_value, vol_min, vol_max, 0, 100); // If the current level is lower than the previous level fade the pixel and move the meter down // This provides a smoother movement if (curr_level < prev_level) { curr_level = prev_level - 2; // Don't let the level drop below zero if (curr_level < 0) { curr_level = 0; } } // Enable the following to get visual output in the Serial Monitor // Warning this slows down the servo ...adds lag /* for (int i = 0; i <= curr_level/5; i++) { Serial.print("|"); } Serial.println("|"); */ int a = analogRead(knobPinA); int b = analogRead(knobPinB); int c = analogRead(knobPinC); int red = map(a, ANALOG_MIN, ANALOG_MAX, 255, 0); int green = map(b, ANALOG_MIN, ANALOG_MAX, 255, 0); int blue = map(c, ANALOG_MIN, ANALOG_MAX, 255, 0); light_level = map(curr_level, 0, 100, 0, 50); light_update(red, green, blue, light_level); a = map(a, ANALOG_MIN, ANALOG_MAX, SERVO_MIN, SERVO_MAX); myServoA.write(a); b = map(b, ANALOG_MIN, ANALOG_MAX, SERVO_MIN, SERVO_MAX); myServoB.write(b); //c = map(c, ANALOG_MIN, ANALOG_MAX, SERVO_MIN, SERVO_MAX); //myServoC.write(c); int servo_meter = map(curr_level, 0, 100, SERVO_MAX, SERVO_MIN); myServoC.write(servo_meter); Serial.print("SERVO | "); Serial.println(servo_meter); prev_level = curr_level; } // Play Function Dance void playServosDance(int buttonPin) { Serial.println("Playing and Dancing"); frame = 0; playing = 1; digitalWrite(ledPin, HIGH); while (digitalRead(buttonPin) == HIGH) { //Allow for beat cut-in value to be adjusted with holding record and knob A if (digitalRead(recordButtonPin) == LOW) { mic_cut = analogRead(knobPinA); mic_cut = map(mic_cut, ANALOG_MIN, ANALOG_MAX, 300, 50); Serial.print("mic_cut: "); Serial.println(mic_cut); } // Read the value from the mic int mic_value = analogRead(MIC_PIN); //Serial.print("MIC: "); //Serial.println(mic_value); // Set the cutoff value and if lower, fade the current level for the servo and led if (mic_value > mic_cut) { is_beat = 1; curr_level = 50; } else { is_beat = 0; curr_level = prev_level - 7; } int a = EEPROM.read(frame + 0); int b = EEPROM.read(frame + 1); int c = EEPROM.read(frame + 2); // Check for stop/loop frame if (a == 255 or b == 255 or c == 255) { frame = 0; Serial.println("loop"); continue; } if (frame == 0 and is_beat == 0) { //Serial.println("waiting"); } else { if (frame == 0) { Serial.println("BEAT!!"); } frame = frame + 3; } myServoA.write(a); myServoB.write(b); myServoC.write(c); int red = map(a, 0, 180, 255, 0); int green = map(b, 0, 180, 255, 0); int blue = map(c, 0, 180, 255, 0); light_update(red, green, blue, 50); delay(playSpeed); prev_level = curr_level; } Serial.println("Stoped Playing"); //reset the mic_cut mic_cut = mic_cut_default; delay(200); digitalWrite(ledPin, LOW); } // Play Function Frames ------------------------------------------------- void playServos(int buttonPin) { Serial.println("Playing"); frame = 0; playing = 1; digitalWrite(ledPin, HIGH); while (digitalRead(buttonPin) == HIGH) { int a = EEPROM.read(frame + 0); int b = EEPROM.read(frame + 1); int c = EEPROM.read(frame + 2); int red = map(a, 0, 180, 255, 0); int green = map(b, 0, 180, 255, 05); int blue = map(c, 0, 180, 255, 0); light_update(red, green, blue, 50); // Check for stop/loop frame if (a == 255 or b == 255 or c == 255) { frame = 0; if (repeat == 1) { Serial.println("loop"); continue; } else { Serial.println("stop"); break; } } myServoA.write(a); myServoB.write(b); myServoC.write(c); // Set speed from first knob A0 while the recordbutton is held down during playback if (! digitalRead(recordButtonPin)) { playSpeed = analogRead(knobPinA); playSpeed = map(playSpeed, ANALOG_MIN, ANALOG_MAX, 100, 0); } delay(playSpeed); frame = frame + 3; } Serial.println("Stoped Playing"); delay(200); digitalWrite(ledPin, LOW); } // Record Function ------------------------------------------------- void recordServos(int buttonPin) { frame = 0; Serial.println("Recording"); while (digitalRead(buttonPin)) { //int last_a = a; int a = analogRead(knobPinA); // Create a smoothing by looking at the difference between values // ie if change is not more than say 5 then do not make a change. a = map(a, ANALOG_MIN, ANALOG_MAX, 0, 180); myServoA.write(a); EEPROM.write(frame, a); int b = analogRead(knobPinB); b = map(b, ANALOG_MIN, ANALOG_MAX, 0, 180); myServoB.write(b); EEPROM.write(frame + 1, b); int c = analogRead(knobPinC); c = map(c, ANALOG_MIN, ANALOG_MAX, 0, 180); myServoC.write(c); EEPROM.write(frame + 2, c); Serial.print(frame); Serial.print(" | "); Serial.print(a); Serial.print(","); Serial.print(b); Serial.print(","); Serial.print(c); Serial.println(""); int red = map(a, 0, 180, 255, 0); int green = map(b, 0, 180, 255, 0); int blue = map(c, 0, 180, 255, 0); light_update(red, green, blue, 50); if (frame == FRAME_LIMIT) break; frame = frame + 3; // Only take a reading every so many miliseconds to store delay(FRAME_DELAY); // Blink the light if (ledState == 0) { digitalWrite(ledPin, HIGH); ledState = 1; } else { digitalWrite(ledPin, LOW); ledState = 0; } } Serial.println("Stopping Rcording"); // If we stop before the end of the storage limit, store 999 so the play funciton will know when to loop. if (frame != FRAME_LIMIT) { Serial.println("Adding Loop Frame"); //Set an arbitrary frame number that we will never store ir "999" EEPROM.write(frame, 255); } digitalWrite(ledPin, LOW); Serial.println("Finished Recording"); delay(500); } void light_update(int red, int green, int blue, int brightness) { uint32_t color = strip.Color(red, green, blue); strip.setBrightness(brightness); strip.fill(color, 0, LED_COUNT); strip.show(); } void versionBlink(int codeVersion) { int ledBlink = 0; for (int i = 0; i < codeVersion * 2; i++ ) { if (ledBlink == 0) { light_update(50, 255, 0, 0); ledBlink = 1; delay(200); } else { light_update(50, 255, 0, 50); ledBlink = 0; delay(300); } } }