This week, Martin and Kilian created the shaky whacky pencil dog.
It uses two servos to generate a forward and upward movement to simulate an actual dog's walk.
Please find a video of the dog here: http://www.youtube.com/watch?v=QYTv6OPAzto
Materials used:
- two servos
- two plastic forks (rear feet)
- two pencils with rubber capes (front feet)
- lots of elastic tape
- drawing of a dog face
Here's the code:
/*
* Shaky whacky pencil dog
* Theory and Practice of Tangible User Interfaces
* October 18 2011
* Martin Kiechle, Kilian Moser
*/
int servoPin_one = 7; // Control pin for servo motor one
int servoPin_two = 3; // Control pin for servo motor two
int servoPin = 0; // Control pin variable
int pulseWidth = 0; // Amount to pulse the servo
long lastPulse = 0; // the time in millisecs of the last pulse
int refreshTime = 20; // the time in millisecs needed in between pulses
int cycleTime = 600; // Set the cycle time for the servos
int lastCycle = 0; // the time in millisecs of the last cycle
int mov_state = 0; // controls movement states from 1 to 4
int one_deg = 0; // angle for servo one 0-180 deg
int two_deg = 0; // angle for servo two 0-180 deg
int servoDeg = 0; // angle variable 0-180 deg
int one_deg_min = 95; // min angle servo one 0-180 deg
int one_deg_max = 115; // max angle servo one 0-180 deg
int two_deg_min = 0; // min angle servo two 0-180 deg
int two_deg_max = 60; // max angle servo two 0-180 deg
int minPulse = 500; // minimum pulse width
void setup() {
pinMode(servoPin_one, OUTPUT); // Set servo pin as an output pin
pinMode(servoPin_two, OUTPUT); // Set servo pin as an output pin
pulseWidth = minPulse; // Set the motor position to the minimum
Serial.begin(9600); // connect to the serial port
Serial.println("servos ready");
}
void loop() {
if(millis() - lastCycle >= cycleTime) {
mov_state = mov_state + 1;
switch(mov_state) {
case 1:
servoPin = servoPin_one;
servoDeg = one_deg_min;
break;
case 2:
servoPin = servoPin_two;
servoDeg = two_deg_max;
break;
case 3:
servoPin = servoPin_one;
servoDeg = one_deg_max;
break;
case 4:
servoPin = servoPin_two;
servoDeg = two_deg_min;
mov_state = 0;
break;
default:
mov_state = 0;
break;
}
lastCycle = millis();
Serial.println(mov_state+1, DEC);
}
if (millis() - lastPulse >= refreshTime) {
servo(servoDeg, servoPin);
lastPulse = millis(); // save the time of the last pulse
}
}
void servo(int deg, int pin) {
pulseWidth = deg*11 + minPulse; // convert angle to microseconds
digitalWrite(pin, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth); // Length of the pulse sets the motor position
digitalWrite(pin, LOW); // Turn the motor off
}
Some Pictures: