After looking at the famous Necomimi Arduino Cat Ears, we decided to give it a try to help us familiarise ourselves with the accelerometer and the arduino.
Using the materials that we had on hand, we managed to produce a set of moving rabbit ears that is similar but not as fantastic. :)
We made a pair of rabbit ears on a cap that move according to the direction your head turns using an accelerometer, servo motors and an Arduino Uno.
Step 1: Components & Tools & Software
(Hopefully we didn't miss out any thing.)
The rabbit ears and the cap were bought from the shop where everything costs $2, DAISO. Our friend had kindly given us one of her hairbands. The other tools and components were provided by our FYP supervisor Teo Shin Jen.
Components:
1. Arduino Uno
2. MMMA7361L 3-Axis Accelerometer ±1.5/6g with Voltage Regulator http://www.pololu.com/catalog/product/1251
3. Servo motors x2
4. Molex pins ( 2 pin & 5 pin )
5. Cable ties
6. Stripboard
7. Single core wire
8. Rabbit Ears ( bought from DAISO)
9. Hairband
10.Acrylic board
11.Cap ( bought from DAISO )
12. Breadboard ( for testing servo and accelerometer)
Tools:
1.Glue gun
2.Soldering Iron
3.Wire stripper
4.Wire cutter
5.Pliers
6.Molex Crimp tool
Software:
1. Arduino IDE
Step 2: Testing of Motor
Once we gathered all the items we needed, we noticed that there was a single iron wire inside each ear to give it its shape. It will prove extremely useful when we need to mount the ears on the motors.
The next thing to do was to test the two servo motors.
This is the code we wrote to test the motors, we fine-tuned the values to have the motors turn to the direction we need it to be.
Using the same setup as the Sweep servo example which can be found here :http://arduino.cc/it/Tutorial/Sweep
----------------------------------------------------
TestingMotor Code:
#include <Servo.h>
Servo myservoLeft;
Servo myservoRight;
int i;
void setup()
{
myservoLeft.attach(9);
myservoRight.attach(10);
}
void loop()
{
for ( i = 0 ; i < 90 ; i+=10)
{
myservoLeft.write(i);
myservoRight.write(i);
delay(100);
}
for ( i = 90 ; i > 0 ; i-=10)
{
myservoLeft.write(i);
myservoRight.write(i);
delay(100);
}
{
for ( i = 90 ; i < 180 ; i+=10)
{
myservoLeft.write(i);
myservoRight.write(i);
delay(100);
}
for ( i = 180 ; i > 90 ; i-=10)
{
myservoLeft.write(i);
myservoRight.write(i);
delay(100);
}
}
}
----------------------------------------------------------------------------
Step 3: Prototype
Step 4: Testing of Accelerometer
We found a great website that helped provide us with a basic understanding of accelerometers as well as a great code.
http://bildr.org/2011/04/sensing-orientation-with-the-adxl335-arduino/
This is the code they provided and what we used.
=================================================
//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Simple code for the ADXL335, prints calculated orientation via serial
//////////////////////////////////////////////////////////////////
//Analog read pins
const int xPin = 0;
const int yPin = 1;
const int zPin = 2;
//The minimum and maximum values that came from
//the accelerometer while standing still
//You very well may need to change these
int minVal = 265;
int maxVal = 402;
//to hold the caculated values
double x;
double y;
double z;
void setup(){
Serial.begin(9600);
}
void loop(){
//read the analog values from the accelerometer
int xRead = analogRead(xPin);
int yRead = analogRead(yPin);
int zRead = analogRead(zPin);
//convert read values to degrees -90 to 90 - Needed for atan2
int xAng = map(xRead, minVal, maxVal, -90, 90);
int yAng = map(yRead, minVal, maxVal, -90, 90);
int zAng = map(zRead, minVal, maxVal, -90, 90);
//Caculate 360deg values like so: atan2(-yAng, -zAng)
//atan2 outputs the value of -π to π (radians)
//We are then converting the radians to degrees
x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);
//Output the caculations
Serial.print("x: ");
Serial.print(x);
Serial.print(" | y: ");
Serial.print(y);
Serial.print(" | z: ");
Serial.println(z);
delay(100);//just here to slow down the serial output - Easier to read
=======================================================
Step 5: Integration of the Servos and Accelerometer and Accelerometer values
We needed to combine both circuits on a stripboard as small as possible as we wanted to place it between both motors. We connected the output pins of both the servo motors into one pin.
Here is the schematic of the combined circuit.
We took advantage of one the few acrylic boards we found lying around in our FYP lab, using it mount our circuit and motors. Using the glue gun , we glued the motors and circuit board on the acrylic board and the acrylic board on the hair band. Securing the hairband to the cap using cable ties.
Now that the accelerometer is firmly placed, we can get accurate values. Using the accelerometer code from the previous step, here are the values we collected. Wearing the cap,we took note of the values when we turn left, right and the original position.
Here are our findings :
Step 6: Final Step
The values are not very accurate. We found it difficult to pinpoint an exact value,it still isn't a perfect set of "ears" as it doesn't turn everytime we turn our heads.
Final code:
===================================================
#include <Servo.h>
int i;
const int xPin = 0;
const int yPin = 1;
const int zPin = 2;
int minVal = 265;
int maxVal = 402;
double x;
double y;
double z;
Servo myservoLeft;
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
myservoLeft.attach(9);
}
// the loop routine runs over and over again forever:
void loop() {
int xRead = analogRead(xPin);
int yRead = analogRead(yPin);
int zRead = analogRead(zPin);
//convert read values to degrees -90 to 90 - Needed for atan2
int xAng = map(xRead, minVal, maxVal, -90, 90);
int yAng = map(yRead, minVal, maxVal, -90, 90);
int zAng = map(zRead, minVal, maxVal, -90, 90);
//Caculate 360deg values like so: atan2(-yAng, -zAng)
//atan2 outputs the value of -π to π (radians)
//We are then converting the radians to degrees
x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);
Serial.print("x: ");
Serial.print(x);
Serial.print(" | y: ");
Serial.print(y);
Serial.print(" | z: ");
Serial.println(z);
delay(100);
if (z >=76){ //right
delay(100);
for ( i = 0 ; i < 90 ; i+=10)
{
myservoLeft.write(i);
delay(100);
}
for ( i = 90 ; i > 0 ; i-=10)
{
myservoLeft.write(i);
delay(100);
}
}
if ( (z >= 50 )&&(z <= 75)){ //middle
myservoLeft.write(60);
delay(100);
}
if ( z <= 49){ //left
delay(100);
for ( i = 90 ; i < 180 ; i+=10)
{
myservoLeft.write(i);
delay(100);
}
for ( i = 180 ; i > 90 ; i-=10)
{
myservoLeft.write(i);
delay(100);
}
}
}
===================================================
It's done!
Kiteman says:
Aug 3, 2012. 8:28 AMReply






















![20120803_195059[1].jpg](/files/deriv/FLW/5D26/H5ENPRGG/FLW5D26H5ENPRGG.LARGE.jpg)

Not Nice














Visit Our Store »
Go Pro Today »



