Midterm – Wag your tail

For this project, I created a tail that clips around your waist, which is controlled by your head movement. The head movement is detected by a dual-axis accelerometer and based on the readings, it directs a servo motor to move which in turns wags your tail.

Fabrication was a real challenge for this project. Some of the issues I encountered were being able to hide the arduino and battery (they sit under a headband and are hidden at the front by a “fur” trim and ears) and hiding wires from the controller and accelerometer to the servo motor, which was located at the back of the belt, just below the waist. These wires needed to allow for head movement without coming apart – an improvement to this project would be elasticized connecting wires.

005 006 003

I also tried a number of iterations for the tail, initially beginning with a segmented wooden snake which I was going to wrap in fur. The snake turned out to be too heavy for the servo motor to operate reliably, and in the end the fur alone attached to a wooden lever was the most successful and best mimicked a tail wagging.

004 002 001

As far as the code goes, I took an existing script for the accelerometer (0-1000) and translated its values to the servo (0-179). I set a baseline of “upright” where the tail didn’t move between -200 and 200 in both directions, and then set conditions for how the tail would move based on the further movement than that. Sometimes the movement of the tail is proportional to the degree of deviation from upright and sometimes it moves to a predetermined position.

/*
Memsic2125

Read the Memsic 2125 two-axis accelerometer. Converts the
pulses output by the 2125 into milli-g’s (1/1000 of earth’s
gravity) and prints them over the serial connection to the
computer.

The circuit:
* X output of accelerometer to digital pin 2
* Y output of accelerometer to digital pin 3
* +V of accelerometer to +5V
* GND of accelerometer to ground

http://www.arduino.cc/en/Tutorial/Memsic2125

created 6 Nov 2008
by David A. Mellis
modified 30 Aug 2011
by Tom Igoe

This example code is in the public domain.

*/
#include <Servo.h>

// these constants won’t change:
const int xPin = 2; // X output of the accelerometer
const int yPin = 6; // Y output of the accelerometer
int valX;
int valY;
int i;// variable to read the value from the accelerometer to the servo
Servo myservo;

void setup() {
// initialize serial communications:
Serial.begin(9600);
// initialize the pins connected to the accelerometer
// as inputs:
pinMode(xPin, INPUT);
pinMode(yPin, INPUT);
myservo.attach(9);
}

 

void loop() {
// variables to read the pulse widths:
int pulseX, pulseY;
// variables to contain the resulting accelerations
int accelerationX, accelerationY;

// read pulse from x- and y-axes:
pulseX = pulseIn(xPin,HIGH);
pulseY = pulseIn(yPin,HIGH);

// convert the pulse width into acceleration
// accelerationX and accelerationY are in milli-g’s:
// earth’s gravity is 1000 milli-g’s, or 1g.
accelerationX = ((pulseX / 10) – 500) * 8;
accelerationY = ((pulseY / 10) – 500) * 8;

valX = map(accelerationX, -1000, 1000, 0, 179);
valY = map(accelerationX, -1000, 1000, 0, 179);
//if (accelerationX > accelerationY && accelerationX > 50) {
if (accelerationX > 200 || accelerationY < -200) {
myservo.write(valX);
delay(100);
myservo.write(-valX);
delay(100);
}
if (accelerationX <= -200) {
myservo.write(valX);
delay(60);
}

if (accelerationY >=200) {
myservo.write(179);
delay(180);
myservo.write(-179);
delay(180);
}
// }
//else {
//myservo.write(valY);
//delay(30);
// myservo.write(-valY);
//delay(30);
// }
// print the acceleration
Serial.print(accelerationX);
// print a tab character:
Serial.print(“\t”);
Serial.print(accelerationY);
Serial.println();

delay(100);
}