Shaky whacky pencil dog

martin.kiechle's picture

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:

0
Your rating: None