Introduction: Necomimi Arduino Cat Ears

They are so dang cute. If you have ever seen the cool promo for the Necomimi Neurowear wearable set of cat ears that respond to brainwaves, you would want a set too. But it seems they may be vaporware since it hasn't materialized on the market yet, not that I would be able to afford them though. Necomimi or nekomimi is Japanese for "cat ears".

What do you do with them? You can wear it for Halloween or everyday, if desired. It may be for the anime otaku seriously into their cosplay. For the furries out there, I'm not asking so don't tell me.

Now what would the simplified caitlinsdad version be? Well, getting into advanced monitoring and feedback of brainwaves might be kinda expensive(they are dumping at the toy mega-store those Star Wars force trainers - control the floating ball with your mind- now $60 from $100 or maybe gut an i-dog but then I don't think the gears are powerful enough) and building some raw circutry is way more than I want to do. Pulley and invisible strings is so ghetto(Not that there's anything wrong with that...). A joystick that controls some motors on a headband? I know, how about servos controlled by an Arduino? And how about using an accelerometer to determine tilt/movement/position of the head to trigger ear movement. Tilt sensor switches might be too basic. GPS gets complicated and compass magnetomometer only points North.

This gives me a project to use with my recently acquired Arduino(no, it did not fall off a truck...I have a receipt). Besides, Caitlin says I have to make this or sew her a custom sling/messenger book bag.

This instructable may be more of an Arduino primer than about the cat ears. Note that this is a prototype project and I am throwing it out at this stage in the spirit of Open Source. I know it can be improved a lot by others and with more time to tweak it.

Okay, they look like bunneh ears, kinda like a cat.


With one of the ear coverings on...


and the star of the show...

Step 1: Getting Started With Arduino

I found that my local computer supergeekstore had stocked Sparkfun retail Arduino components. Maker Faire sells them at the Make: Shed. Adafruit has them also. You could get them from Sparkfun themselves. Hmmm, tax works out about what I would pay in shipping and would not have to wait at the door for the package. I had bought an Arduino Uno $30(other variants($25) require the FTDI programmer USB interface($15) which is built in to the Uno). Other add-ons can run up the tab. I have a 2x16 LCD display($20) to play with next. See if the kits will save you any money. The books were all text-book priced and I was sure info could be gleaned from the internet.

You have to go to arduino.cc to download the Arduino programming interface for your PC. It allows you to create "sketches" or programs that get uploaded to the ATmega microprocessor chip on the Arduino board. The site contains tutorials and examples of code used to implement the devices you want to interface with the Arduino.

On a PC, only thing tricky in getting started is you have to manually install the USB drivers so that it recognizes the Arduino on a COM port.

A computer with the Arduino software installed, USB drivers, a USB cable to connect the PC and Arduino, and the Arduino Uno is all you need to get started. The Uno has an LED onboard that you can control with a sketch.

I wanted to get an Arduino so I could do some of those cool things like build 3-D LED matrices and light reactive tabletops.

It is easy to get your LED blinking and fading. It was easy to modify an example sketch to do Cylon lights(Knight Rider lights),  just add more LEDs and resistors.  Read up on all the LED instructables and you can throw around terms like "charlieplexing".

So, always hook up an LED with a resistor so you don't burn it out(search "LED calculator" for widgets to find the right resistor value). A trip to Radio Snacks to get a bag of assorted LEDs and 100 ohm resistors. A trip back to get a protoboard and 100 ohm resistors because I failed to note 100k resistors are not 100 ohm resistors. And another trip back after realizing I do not have any wire thin enough (22 gauge?) that fit in the holes on the protoboard (and get solid not stranded).

I saw a precut pack of jumpers but hey, I have a nice pair of wire strippers and can do that. I saw online some premade jumpers that had a patch-cord plug-like cover on the ends of the wires. Hey, I could get some tiny plastic jewelry beads, and pass the wire through and maybe solder or tin the ends of the wire to keep it in place. Do not do that, tinning the ends makes it not fit in the holes. Find a bead that fits snugly or put a drop of glue to hold it in place.

Back to this project:

Once you are comfortable enough to wire up your protoboard and have done a few sketches, you should be able to tackle this project.

You will need to get:

* Protoboard or breadboard to wire the circuit together.

* Wire, lotsa wire with the ends stripped

* 2 standard servos (My brother flies radio-controlled jets and helicopters so he had some spares to give me. Free is always good)
 three wire, 6 volts DC in, pulse-width-modulation PWM signal

* ADXL345 accelerometer breakout board - $30 

* some LEDs and appropriate resistors (200-300 ohm usually works for your standard red/green/yellow medium sized 5mm LED)
The LEDs are really just diagnostic LEDs and indicators to help you fine tune your programming.

* You will need some basic soldering skills and tools.

* Power pack for your Arduino and power pack for your servos to make it portable

* Some craft fur, craft sheet foam and ear lining material

* Basic sewing skill. You can sew this by hand, machine or just use tape, glue/iron-on interfacing.


Step 2: ADXL345 Accelerometer Breakout Board

I had purchased 2 accelerometer boards at the store. 1. I knew I would be making two sets of necomimi. 2. Always have a backup. 3. When you experiment, prepare to toast one of your components. So I also got another Uno to back up the one I already had.

This breakout board(you can buy just the chip and figure out how to do that surface mount soldering which is really tricky) has the chip mounted with some other critical capacitors/resistors on a circuit board ready for you to wire up. Man, is this breakout board tiny.

At The Shack, I got their digitally controlled soldering station on sale for $50 and this was the first time I got to fire it up.
Everything was connected and powered up. I had forgot there was a clear plastic shipping tube on the soldering tip and I had just put it back into the soldering station holder well. So I had to spend some time scraping off the melted plastic and gunk off the tip. Minor setback.

I decided to hardwire 8 jumper wires to the breakout board so I could plug the leads into my protoboard.

No instructions come with this board so I took a good guess on how to solder the leads in. If they surface mount on one side then I would plug the wires in on the bottom side. The pads were not pretinned and did not have a copper surface so I couldn't tell which would be better to solder on.

Did I mention how small this breakout board is?

I used the first preset temperature setting on the soldering station figuring, I am working with sensitive electronics, too much heat is bad...

It was kinda hard to melt the solder but I got one wire in. Crank up the next higher setting. Solder still doesn't melt on contact but seems to work.

Third pad I futz around with. I think I pressed in the hole or on the wire too long to get a nice blob of solder going. Dang, the circuit trace lifted off. Of course, stronger epithets were used. You know when that happens, you may be so f...... Desolder the wire and survey the damage. The trace to the pin on the chip is so thin, that pulled away too. I try to salvage it by scraping further up the trace, tin it and try to attach a jumper wire to the wire anchored in the hole with a blob of solder. This usually works but later on I find out my board is fried since I can't get it to communicate. I had originally burnt off the INT1 line. I didn't know I would not need it later on. I had also burnt off the pad on the SCL line. That was worse since I couldn't tell if I needed to jump the ground pad. I see some other complaints on the internet that the pads and traces are so small. I think I would get a Lilypad version next time which has big pads for sewing with conductive thread. So a warning here, use header pins to solder in if you can get them and fire up the iron to 670 degrees F with a light touch(third soldering preset happened to be 680, high).

So I discovered this accelerometer would be a pain to work with. At least I had a backup, others may not be able to afford blowing away $30 like that, kinda like the tolls to New Jersey. I was lucky to get the second breakout board wired up. I went in blind thinking this would be a snap to hook up. I check to see if there are any tutorials on this. I may be in over my head on this. There is minimal support on this product, here, go read the datasheet. By the way, there are two methods of interfacing this and wiring diagrams are pretty sparse. One nice tutorial - most searches seem to point to this one, was way to complicated in getting the data out and scared me off. I don't think that was using the Sketch software either.

Then I found this tutorial  from Love Electronics - it had an ADXL345 library of code and functions to get the data out.   Read up on how an electronic accelerometer works and look at all the images which are helpful.  Download their ADXL345 library to use as I based my sketch on their code example. There are built in functions to easily read the accelerometer data.

Their example allowed me to view the data streaming out of the ADXL345 by using the serial monitor that is part of the Arduino sketch software. I would just need to figure out how to interpret the raw data numbers and g-forces that were being pumped out.

Step 3: Come Together, Right Now...

Use pieces of masking tape to put tags on the ends of the wires of the breakout board for easy identification.

Wire up the ADXL345 breakout board to the Arduino

Connect  VCC, SDO and CS to 3.3v on the Arduino, make sure it is the 3.3v or you may burn up the ADXL345
Connect the GND to ground on the Arduino.
Connect  SDA to Arduino 3.3V with 100 ohm resistor.
Connect  SCL to Arduino 3.3V  with 100 ohm resistor.
Connect  SDA to Arduino analog pin 4 
Connect  SCL to Arduino analog pin 5

Learn about pull-up resistor switch wiring and why that is needed.


Wire up the ADXL345 connected status LED

Ground the ground pin side (shorter length)

Put a 200 ohm resistor in the path

Connect the resistor from the anode or long lead of the LED to digital signal pin 2.

Wire up the three axis indicator LEDs

I initially thought about putting in four leds in a diamond formation to indicate the tilt direction.  I only used three in the mockup because I went with mapping the x, y, and z values from the accelerometer.

Ground the ground pin side (shorter length)

Put a 200 ohm resistor in the path.

Connect the resistor from anode or long lead of the LED to the appropriate digital signal pins in on the arduino.  

I used pins 8, 9 , 11.  They must be defined for output in the setup().

Go to Fritzing.org to get the prototyping software to make a fancy hardware diagram and have it generate a nifty circuit board if you plan to take it further.

I am working on the Fritzing diagram for my test setup.  You can simplify the wiring but that is how is works out on the protoboard.

Of course, you can omit all the LEDs when you build the final product.


Step 4: Sketchy Details

Here is the code of the sketch.

Just cut and paste as uploading a file at ibles may not retain the filename and will be confusing.

//====start of sketch==================
/*
This program is based Arduino sketch examples and the following:
ADXL345_Example.pde - Example sketch for integration with an ADXL345 triple axis accelerometer.
Copyright (C) 2011 Love Electronics (loveelectronics.co.uk)

This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

*/

// Include the Wire library so we can start using I2C.
#include <Wire.h>

// Include the Love Electronics ADXL345 library so we can use the accelerometer.
#include <ADXL345.h>

// include the servo library to control the servo
#include <Servo.h> 

Servo myservoA; // create servo object to control a servo 
                 // a maximum of eight servo objects can be created 

Servo myservoB; // create servo object to control a servo 
                 // a maximum of eight servo objects can be created 

int posA = 0; // variable to store the servo position 
int posB = 0;

// Declare a global instance of the accelerometer.
ADXL345 accel;

// Set up a pin we are going to use to indicate our status using an LED.
int statusPin = 2; // I'm using digital pin 2.

//------------------------------------------------------

void setup()
{
  myservoA.attach(7); // attaches the servo on pin 6 to the servo object 
  myservoB.attach(6); // attaches the servo on pin 7 to the servo object

  // Begin by setting up the Serial Port so we can output our results.
  Serial.begin(9600);
  // Start the I2C Wire library so we can use I2C to talk to the accelerometer.
  Wire.begin();

  // Ready an LED to indicate our status.
  pinMode(statusPin, OUTPUT);


  // Create an instance of the accelerometer on the default address (0x1D)
  accel = ADXL345();

  // Check that the accelerometer is infact connected.
  if(accel.EnsureConnected())
  {
    Serial.println("Connected to ADXL345.");
    digitalWrite(statusPin, HIGH); // If we are connected, light our status LED.
  }
  else 
  {
    Serial.println("Could not connect to ADXL345.");
    digitalWrite(statusPin, LOW); // If we are not connected, turn our LED off.
  }

  // Set the range of the accelerometer to a maximum of 2G.
  accel.SetRange(2, true);
  // Tell the accelerometer to start taking measurements.
  accel.EnableMeasurements();
}

//----------------------------------
void loop()
{

  if(accel.IsConnected) // If we are connected to the accelerometer.
  {
    // Read the raw data from the accelerometer.
    AccelerometerRaw raw = accel.ReadRawAxis();
    //This data can be accessed like so:
    int xAxisRawData = raw.XAxis;

    // Read the *scaled* data from the accelerometer (this does it's own read from the accelerometer
    // so you don't have to ReadRawAxis before you use this method).
    // This useful method gives you the value in G thanks to the Love Electronics library.
    AccelerometerScaled scaled = accel.ReadScaledAxis();
    // This data can be accessed like so:
    float xAxisGs = scaled.XAxis;

    // We output our received data.
    Output(raw, scaled);

  }

}


// Output the data down the serial port.
void Output(AccelerometerRaw raw, AccelerometerScaled scaled)
{
 // initialize the LED pin as an output:
  pinMode(8, OUTPUT); 
   pinMode(9, OUTPUT); 
    pinMode(11, OUTPUT); 
     pinMode(12, OUTPUT); 

  // Tell us about the raw values coming from the accelerometer.
   Serial.print("Raw:\t");
   Serial.print(raw.XAxis);
   Serial.print(" ");
Serial.print(raw.YAxis);
Serial.print(" ");
Serial.print(raw.ZAxis);

// Tell us about the this data, but scale it into useful units (G).
Serial.print(" \tScaled:\t");
Serial.print(scaled.XAxis);
Serial.print("G ");
Serial.print(scaled.YAxis);
Serial.print("G ");
Serial.print(scaled.ZAxis);
Serial.println("G");

// show led for axis
if (scaled.XAxis > 0) {
digitalWrite(8, HIGH); // set the LED on
}
else
{
digitalWrite(8, LOW); // set the LED off

}
//
if (scaled.YAxis > 0) {
digitalWrite(9, HIGH); // set the LED on
}
else
{
digitalWrite(9, LOW); // set the LED off

}
//
if (scaled.ZAxis > 0.8) {
digitalWrite(11, HIGH); // set the LED on
}
else
{
digitalWrite(11, LOW); // set the LED off

}

// make servo move according to conditions sensed -----------------------------

if (scaled.ZAxis < 0.8) {
Serial.println("*** Raise Lower-----------Raise Lower");
RaiseLower();
delay(265);
}

//
if (scaled.YAxis < 0) {
Serial.println("*** Twitch Middle---------Twitch Middle");
twitchMiddle();
delay(400);

}

//
if (scaled.XAxis < 0 and scaled.YAxis > 0 and scaled.ZAxis >0) {
Serial.println("*** Wink Right---------------Wink Right");
winkRight();
delay(265);
}


}

//-------------------------------
// subroutine for raise and lower
void RaiseLower()
{

twitchshort();
twitch();

for(posA = 0; posA < 135; posA += 1) // goes from 0 degrees to 135 degrees
{ // in steps of 1 degree
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(12); // waits 15ms for the servo to reach the position
}
for(posA = 135; posA>=1; posA-=1) // goes from 135 degrees to 0 degrees
{
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(12); // waits 15ms for the servo to reach the position
}

}

// subroutine for twitch -------------------------
void twitch()
{
for(posA = 0; posA < 45; posA += 1) // goes from 0 degrees to 45 degrees
{ // in steps of 1 degree
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(8); // waits 15ms for the servo to reach the position
}
for(posA = 45; posA>=1; posA-=1) // goes from 45 degrees to 0 degrees
{
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(8); // waits 15ms for the servo to reach the position
}
}
// subroutine for short twitch --------------------
void twitchshort()
{
for(posA = 0; posA < 25; posA += 1) // goes from 0 degrees to 25 degrees
{ // in steps of 1 degree
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(5); // waits 15ms for the servo to reach the position
}
for(posA = 25; posA>=1; posA-=1) // goes from 25 degrees to 0 degrees
{
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(5); // waits 15ms for the servo to reach the position
}
}

// subroutine for twitch middle --------------------
void twitchMiddle()
{
for(posA = 0; posA < 100; posA += 1) // goes from 100 degrees to 0 degrees
{ // in steps of 1 degree
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(10); // waits 15ms for the servo to reach the position
}
for(posA = 100; posA>=1; posA-=1) // goes from 100 degrees to 0 degrees
{
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(10); // waits 15ms for the servo to reach the position
}
delay(250);
for(posA = 0; posA < 120; posA += 1) // goes from 100 degrees to 0 degrees
{ // in steps of 1 degree
myservoA.write(posA); // tell servo to go to position in variable 'pos'
myservoB.write(180-posA);
delay(10); // waits 15ms for the servo to reach the position
}
}

// subroutine for wink right --------------------
void winkRight()
{
for(posA = 0; posA < 120; posA += 1) // goes from 0 degrees to 120 degrees
{ // in steps of 1 degree
myservoA.write(posA); // tell servo to go to position in variable 'pos'
// myservoB.write(180-posA);
delay(10); // waits 15ms for the servo to reach the position
}
for(posA = 120; posA>=1; posA-=1) // goes from 180 degrees to 0 degrees
{
myservoA.write(posA); // tell servo to go to position in variable 'pos'
// myservoB.write(180-posA);
delay(10); // waits 15ms for the servo to reach the position
}
myservoB.write(180); // raise other ear if resting to match upright
}  
//====end of sketch==================



If you tilt your head forward, the ears should do a full up and down .

If you tilt your head to the right, the left ear should go up and down.

There should be a slight wiggle if a slight tilt.  The ears drop to a down position.

Play around with the delay values and servo timing loops for realistic action.

Remember, you may have to figure out where your servos are positioned at 0 degrees start  and what way they rotate.  You then have to accomodate the movement with the servo commands in the sketch.

X, Y, Z and servo movement in my prototype may not match yours.




Step 5: Prototyping

You can try to run this without the servos hardwired in.

Servos are controlled with PWM (pulse-width-modulation) digital control signals from the Arduino.

The control wire(white wire) is hooked up to Arduino digital pin 6 or pin 7.

The red wire is hooked up to +5v power.  Note on the prototype breadboard diagram that the power bus blocks are broken in the middle.  Jumpers on one side to continue the 3.3v rail and 5v isolated for the servos.

The black wire is hooked up to ground.

If you are providing a separate power pack for the servos, as recommended as not to pull out a lot of power through the Arduino, the ground must be common with the arduino otherwise the signal won't work.


I was trying to see what kind of data was coming out of the ADXL345 to see how I could use it as a tilt sensor.

Comments about the board say that the axis reference markings are wrong so orient the board in different ways and see how the data changes.

Modify the code accordingly.

Please see the comments in the code to see what each step does.

To mimic realistic action, I had to put in a delay each time the servos finish their action.  The ears would be constantly moving if the person wearing this stayed completely still.

I guess you would have to be a real animal behaviourist to figure out all of the motions to program in.  I used basic assumptions to create the algorithm on how it reacts to the accelerometer values.

A simple tilt to one side, tilt forward, and tilt to the other side is all I worked on.  You would need to observe the data for the different movement of the sensors. Use the raw data or converted g-force values.

Step 6: The Fuzzy Part...

Attach the two servos to a headband. I just used electrical tape to secure them on.

Note that when the unit is powered up, the motors are constantly spinning and you will detect a slight vibration so you may want to damp them with padding or foam tape. There is no noticible heat from the servos.

I didn't have any fancy custom machined parts to attach to the servos so I just taped on some wire and went from there.

You can mock up a pattern or eyeball it with cutting out a D shape on a folded piece of craft fur fabric.

Cut out a similar shape out of craft foam to be the cartilage support for the ears..

Cover the good or furry side with the inner ear fabric.

Sew around the outside but leave a bottom opening so you can turn it inside out.

Play around with forming the ears, you may have to go back to sew the correct shape.

I just tucked in the bottom end of the ear.  You will need it to attach the ear covering to the servo.  Sew it up later.

I used a serger because,  I can....well, I have found it to be the fastest way to sew some stuff, only pain is when the thread breaks because you are pushing too much fabric thickness through or trying to carve a shape like the roads of Monte Carlo.

Place the cover on the servo ears.

Mount the ADXL345 breakout board in the center of the headband. Route the wires to the center and back.

Cover electronics with more craft fur.


Step 7: Crash Test Bunnies

So depending on how your fabric ear coverings turned out...

The operation of this is pretty rudimentary.

Put it on.

Power it up.

Move your head.

Correct and shift.

You know, this is kinda neat....

Step 8: Much to Do About Something...

There are so many ideas for further development:

Make an early warning earthquake detector alarm, that accelerometer is pretty sensitive.

Make a game to see who twitches first.

Mount the servos sideways to get dog ears or any other animal, you might get tired...

Map the tilt sensor for wider or more natural range of corresponding ear movement.

Map the readings in polar coordinates to make it easier to program for use as a tilt sensor.

Normalize the data - some kind of debouncing as there are some erratic readings - may need to adjust for atmospheric conditions or enviroment such as temperature

Adjust sensitivity by software filtering of the data to reduce "noise"

Create a calibration/stabilization routine when needed to orient the headband on the wearer.

Don't know if adding gyroscopic functions gives it other features.

Have it respond to audio stimuli.

Have ears move to the rhythm of music being heard.

Have ears respond to heart rate monitor.

Have ears respond according to brain wave monitor.

Use lilypad for control module to include battery pack on headband.

As for the Japanese manufacturing ethos: Make it smaller and faster.

As for the Chinese manufacturing ethos: We can reverse engineer anything.

As for the Instructables ethos: Make it yourself.


Halloween Props Challenge

Third Prize in the
Halloween Props Challenge