Instructables

Arduino animatronics- make your awesome costumes more awesome!

FeaturedContest WinnerContest Winner
Picture of Arduino animatronics- make your awesome costumes more awesome!
Here's how to add lights, sound and action to your favorite Halloween project using the open source Arduino microcontroller. Arduino is easy to learn to use and it opens up a whole new world for costume builders and creature creators. If you want to learn how to connect wires, servos, LEDs and use sound effects to add that something special to your latest project then this is for you.

p { } I'll show you how to make a neat little compact Arduino servo controller board with built in servo connectors that is perfect for costuming and haunted house applications. There are multiple code examples, wiring diagrams and I'll show you how to connect sensors and even how to connect two controllers using wireless radios.

Here's a little movie clip of what is easily possible- an animatronic Predator cannon with laser sight, cannon firing sound and head tracking motion control.




Here's an Iron Man hand repulsor with servo to open the forearm missile compartment. Follow along and find out how to make your awesome costumes more awesome...

Update: My instructable for showing how to make an animatronic Stargate helmet is here-
http://www.instructables.com/id/Animatronic-Stargate-helmet/

I've also created an animatronics forum where people can go to get help with their costume and prop projects. I get so many messages for specific project help from people that I decided to create a dedicated forum where everyone can get help and share ideas!



Note- While this instructable is written for the beginner, this tutorial assumes you know how to use a soldering iron and other assorted tools like wire strippers and wire cutters. Please be sure to take proper safety precautions, wear safety glasses when using cutting tools and have adequate ventilation when soldering. If you aren't yet comfortable soldering small surface mount components don't fret- I've posted links in the reference section that will help you become a soldering champ in no time.

 
Remove these adsRemove these ads by Signing Up

Step 1: First you need an Arduino

Picture of First you need an Arduino
ProMiniServoBoardv1.3.jpg

Arduino? What exactly is Arduino?

Arduino is an open source microcontroller- essentially it is a small computer with an easy to use cross platform programming language. It allows you to create interactive objects based on sensory inputs (physical computing.) You can use it to do something simple like make an LED fade or have a servo move when you push a button or have it do something very complex like control a robot by processing sensor inputs, send the inputs to a computer over a wireless network and then send commands back to the robot. The applications are really limited only by your imagination and there are thousands of examples of cool projects all over the Web. There are several books about Arduino and its capabilities and I've listed a few in the reference section.

Which Arduino to use?

There are several variations of the Arduino controller available so which one do you use? It depends on your application. Some have more input pins than others if you need a lot of sensor inputs. For the purposes of this instructable you really can use any Arduino you like as the information presented applies to most every version. Here is a spreadsheet that shows most of the current variations available-
https://spreadsheets.google.com/ccc?key=0AsCUiP6WbJIvcG8xalA3QVdmb3JVT0ptWE9VNC02WEE&hl=en#gid=0

If you are going to use an Arduino Uno or Mega or any Arduino that has built in USB then you can skip to the getting started section.
 

Building a servo board

Since my focus is mainly on costume building I decided to use the Sparkfun Arduino Pro Mini and then build a compact servo application board for it that has multiple servo outputs, analog inputs and digital outputs. I also added a socket for an Adafruit Xbee wireless radio adapter as well as a charging circuit for a single cell LiPo battery to power the controller.

The reasons I really like the Pro Mini are its very small form factor, low cost and low power requirements. It operates on 3.3V, which means it can be powered by a single LiPo cell and that makes it easy when connecting sensors that run on 3.3V.

The latest version servo board has eight servo outputs, four digital outputs and six analog inputs. The servo outputs are also digital outputs- they're just configured to make it really easy to connect hobby servos. The earlier version seen in the photos has six servo outputs. Each servo output has three pins- ground, power and signal. The analog inputs are configured the same way- each input has three pins- ground, power and signal. This configuration makes it super easy to connect individual sensors. The board measures 1.75" x 2.30" so it's pretty small.
 

The board has a circuit for charging the LiPo cell that powers the controller. There is a mini USB port for 5v input power. Simply connect the battery and then plug in a USB cable and the battery will automatically charge. There is a charging indicator- the LED is on when the battery is charging and then it will automatically turn off when the battery is fully charged.
 

The mini USB port will also power the controller, even without a battery connected. The mini USB port is only used as a power source connector while charging or during times when a LiPo battery is not available- there is no data transmission using the mini USB port and you are limited by the amount of power a USB port can provide.
 

Code is uploaded to the controller using a USB to serial adapter (more on this later.) This adapter can also power the controller over USB without the need to connect the battery. This comes in really handy when you're testing code and you want to power the controller without having to connect the LiPo battery.

I'm providing all the necessary EAGLE files so people can modify the design to suit their own needs.

EAGLE can be downloaded here- http://www.cadsoftusa.com/

Step 2: Building the controller

 
Tools and materials

Soldering iron- A good quality soldering iron is a must. I received an Aoyue 2900 soldering station a couple years ago for Christmas and it's been great. You won't believe the difference once you start using a good soldering iron.
http://sra-solder.com/product.php/6363/22


I also use a small tip for soldering small surface mount components-
http://sra-solder.com/product.php/6397/0

Wire cutters/wire strippers- Small flush cutters are the best. If you don't have wire strippers or cutters then these will work well-
http://www.adafruit.com/index.php?main_page=product_info&cPath=8&products_id=152
http://www.adafruit.com/index.php?main_page=product_info&cPath=8&products_id=147

Tweezers- Get some small tweezers to work with surface mount components. Here's an inexpensive set-http://sra-solder.com/product.php/6409/79

Magnifiers- Being able to see what you're working on makes a world of difference.
http://www.adafruit.com/index.php?main_page=product_info&cPath=8&products_id=291

Multimeter- Most any multimeter will work. You don't need to spend big $$$. I personally own a Wavetek Meterman 16XL and it's great. If you don't already own a multimeter and are really getting into hobby electronics then this meter will probably do everything you could ever want-
http://www.adafruit.com/index.php?main_page=product_info&cPath=8&products_id=308


Servo board PCB-
http://batchpcb.com/index.php/Products/47581

Arduino Pro Mini- http://www.sparkfun.com/products/9220

USB mini-B connector- http://www.sparkfun.com/products/587

capacitors- 2 ea 1210 package 1uF SMD ceramic capacitors
http://us.element-14.com/kemet/c1210x105k5ractu/capacitor-ceramic-1uf-50v-x7r-1210/dp/94M5711

resistor- 1ea 1206 package 1K Ohm SMD resistor
http://us.element-14.com/welwyn/wcr1206-1k0fi/resistor-thick-film-1kohm-250mw/dp/98K2656

LED- 1 ea 1206 package SMD LED
http://us.element-14.com/vcc-visual-communications-company/vaol-s12rp4/led-2x1-5mm-red-133mcd-624nm/dp/27R0088

JST connector- 1 ea
http://www.sparkfun.com/products/8612

MAX1555 IC- 1 ea
http://www.sparkfun.com/products/674
http://us.element-14.com/maxim-integrated-products/max1555ezk-t/ic-battery-charger-li-ion-340ma/dp/59J2761?Ntt=MAX1555

Straight break away header pins - 2ea 40 pin row 
These come in really handy so it's always good to get extras to have on hand
http://www.sparkfun.com/products/116

Female break away header pins- 2 ea 40 hole row
These also are super handy to have around
http://www.sparkfun.com/products/115

Single cell LiPo battery- 1ea (you can use any capacity you like.)
http://www.sparkfun.com/products/339

USB mini-B cable- 1 ea
Odds are you've already got one but if you don't here you go-
http://www.sparkfun.com/products/598


Assembling the servo board

The first thing to do is build the charging circuit. I usually start with the smallest components first. I've found the easiest way to solder SMD parts is to get a tiny bit of solder on your soldering tip and touch it to one of the component pads on the PCB. Then hold the component in place using tweezers and heat up the pad and component pin- this allows you to get the part attached to the board so you can check its alignment for the rest of the pads. Then simply solder each of the remaining pads. There is a great series of SMD soldering tutorials here- http://www.sparkfun.com/tutorials/36
 

Begin by soldering on the MAX1555 IC (labeled U1) -this can only go on one way. Next comes the LED- make sure to check the polarity as it is labeled on the PCB (the LED cathode is connected to one end of R1.) Then solder resistor R1 followed by the capacitors C1 and C2. These can be soldered on either direction. Next comes the mini USB connector- this one is a bit tricky as the pins are positioned nearly underneath the connector. Now solder on the JST connector. Make sure to double check your soldering job for these connectors as they receive a fair bit of mechanical stress.
 

Now test your charging circuit. Plug in a USB cable and check the voltage at the JST battery connector. It should read about 4.2-4.3V. Now connect the LiPo battery. If everything is OK the small LED should turn on, indicating the battery is charging. Disconnect the battery.
 

Now solder on the pins to connect the Pro Mini board. This is done by soldering on the break away straight header pins. First insert the long pin ends into the PCB, flip the board over and solder them in place. Double check your solder joints. Now flip the board over and place the Pro Mini board in place on top of the exposed pins and solder all the pins in place. Next solder the remaining straight pins into place in the digital out positions and the 3.3v port along the bottom of the board.
 

To finish the board solder all the female headers in place. The best way I've found to cut the female headers is to remove a pin where you want to make a cut- just yank the pin out the bottom using a pair of pliers. Then take wire cutters and cut through the opening left by the pin. Now take a file (or sandpaper) and smooth out the cut edge.
 

Make sure your board is getting power by plugging a USB cable into the mini USB port on the controller board. The red LED on the Arduino Pro Mini should light up.
 

That's it- your controller is ready to go!

Step 3: Getting started

Picture of Getting started
ArduinoWindow.jpg
ArduinoBoardSelection.jpg
ArduinoSerialConnection.jpg
To upload code to your Arduino servo board you need a USB to serial adapter. I use the Sparkfun FTDI Basic 3.3V breakout. You can also use the Adafruit FTDI friend (make sure to set it to 3.3V.) Either adapter will work great (you do have to solder a connector to the bottom of the Sparkfun adapter- you can use either straight or 90 degree pins.)

I really like these boards because you can see the LEDs light up when they are transmitting. You also need to make sure you have the latest FTDI drivers on your computer (you can get the most current drivers on the product web pages.)

Sparkfun FTDI Basic 3.3V breakout
http://www.sparkfun.com/products/10009

Adafruit FTDI friend
http://www.adafruit.com/index.php?main_page=product_info&cPath=18&products_id=284

You simply plug the FTDI Basic breakout into the programming socket on the controller board and connect it to a computer using a USB mini-B cable. Make sure to line up the GRN and BLK indicators.

If you're using an Arduino with built in USB then you don't need a USB to serial adapter- it's built into the Arduino board. Just connect it to a computer using a USB cable and you're good to go.



Programming environment

Now you need to download the Arduino software which is located here:http://arduino.cc/en/Main/Software

At the time of this writing I am using Arduino 0018. If you want to use the newer Arduino Uno or Mega2560 then you should use the latest release (0021 at this time) as the Uno and Mega2560 use a different type of USB to serial connection that is not supported by previous versions.

I also highly recommend reading the Arduino environment guide here:http://arduino.cc/en/Guide/Environment

The code you will use has several parts:

1. Program description/comments-
This is where you say what the program does

2. Variable declaration section-
This is where you assign input/output pins, etc.

3. Setup section-
This is where you set pins as inputs or outputs, etc.

4. Loop section-
This is the program that will run based on the conditions of your variables and setup sections.

When your program runs it will first define your variables, then execute the setup section once and will then execute the loop section over and over.

So what you do is open the Arduino software, add (or write) your code (called a sketch), verify (compile) your code, connect your Arduino to your computer, select the USB/serial connection, select the type of Arduino you're using then upload your code to the Arduino.

Here's the process-

1. Open Arduino window and add/write code-
Just open the Arduino program and paste the code example you want to use into the window (or write your own code.)

2. Verify-
Hit the verify button to compile your code. It will inform you if there are any errors with your code.

3. Connect board-
Connect the servo board to your computer using the USB to serial adapter- if you are using an Arduino with built in USB then just plug the Arduino directly into your computer.

4. Select connection-
This tells the USB to serial adapter which serial port you are going to use. The one to select is labeled beginning /dev/tty.usbserial so from the top menu go to Tools>Serial Port>/dev/tty.usbserial-(insert port name here)

5. Select board-
This tells the Arduino program which version board you are using. From the top menu go to Tools>Board>Arduino Pro or Pro Mini (3.3V, 8Mhz) w/ ATmega328 if you are using the Pro Mini servo board or choose the correct model Arduino.

6. Upload code-
Hit the upload button to send the code to your Arduino.

That's it!

 

Step 4: Making connections- motors, LEDs and transistors

TransistorBoard.png
TIP120.jpg
LED.jpg
 
Inputs and outputs

Now we need to connect a few devices like servos, sensors and LEDs to our controller. The controller has inputs and outputs. Things like sensors and switches are input devices, while servos, LEDs and motors are output devices. The inputs and outputs are both analog and digital- a digital input is like a switch, so it's either on or off. Analog inputs are variable- it's more like a dimmer switch that gives you a range of values.
 

Digital outputs are similar- if the controller output pin is set HIGH then it's on. If it's set LOW, then it's off. This is great if you want to turn on a motor or LED. If you want to change the brightness of an LED or make a servo motor move then you want to make the controller output pin an analog output. This is done using PWM (pulsewidth modulation.) PWM simply allows the controller to fake an analog voltage output by setting the output pin HIGH and then setting the output pin LOW within a few microseconds or milliseconds of each other. If you pulse the pin HIGH for the same length of time you pulse it LOW you would get an average voltage of half the total voltage so the output pin would give you 1.6V instead of 3.3V. The amount of time the pin stays HIGH is called pulsewidth. The ratio of time for the pin to go from LOW to HIGH to LOW is called duty cycle. If you shorten the amount of time the pin stays HIGH relative to the amount of time it stays LOW you will effectively lower the output pin voltage. It really sounds more complicated than it is but this will come in really handy later on when you want make LEDs dim or make a servo move. Fortunately most of this complex stuff is done for you in the Arduino code libraries but it's still really good to know.
 

Sensors

There are all kinds of sensors- bend sensors, force sensitive resistors, accelerometers, potentiometers, joysticks, etc.

These analog sensors change their output voltage according to how you use them. In the examples we'll use button switches to turn things on and off and we'll use joysticks (potentiometers), bend sensors and accelerometers to make servos move.

When designing an animatronic system for costuming I try to match the type of sensor used with a specific body motion. Think about how the person wearing the costume is going to use it. Bend sensors are great if you want to make a LED dim or servo move by bending your finger. For even more control I can place a small joystick on a fingertip and use that to make a servo move. For a head tracking system that makes servos follow your head movement I use an accelerometer (from a Wii nunchuck) and I use fingertip switches to trigger sound effects. You'll see how these work in the examples.

Sparkfun has a good size momentary push button switch that is breadboard friendly-
http://www.sparkfun.com/products/9190
Here's the smaller version-
http://www.sparkfun.com/products/97
 

All of the sensors we'll use are connected to the Arduino input pins. A potentiometer is a device commonly used in an application like a stereo volume knob- it's a type of variable resistor. If you supply the potentiometer with 3.3V when you turn the knob the output voltage will range from 0 to 3.3V. A joystick is simply two potentiometers in a common housing- one for the X axis and one for the Y axis.

Sparkfun has a 10K potentiometer-
http://www.sparkfun.com/products/9939

They also have a couple of small joysticks-
http://www.sparkfun.com/products/9032
http://www.sparkfun.com/products/9426

A bend sensor is a resistor that changes its resistance value according to how much you bend it. By adding another resistor and creating a voltage divider, we can change the output voltage of the bend sensor to match the degree of bend. The only real drawback to bend sensors is that they don't have the wide range that a potentiometer has.

Sparkfun sells a bend sensor here-
http://www.sparkfun.com/products/8606

Accelerometers work by sensing a change in acceleration and then they alter their output relative to the change in acceleration. When you tilt an accelerometer it measures acceleration due to gravity- the more you tilt it the greater the change in output. Accelerometers are commonly used in video game controllers and cell phones.

A Wii nunchuck has a 3 axis accelerometer, joystick and two pushbuttons for $20.

Motors

Servos

Hobby servos are small geared motors that have a circuit board and potentiometer to control their rotation. This allows them to be able to move to an exact position relative to your input sensor signal. Most servos can move nearly 180 degrees and some can even do multiple rotations as well as continuous rotation. Servos have three wires- ground, power and signal. The signal wire (usually yellow or white) is connected to the Arduino output pin. The power and ground wires are connected to a separate power source, usually ranging anywhere from 4.8V to 6V. The reason for connecting servos to their own power supply is that motors generate a fair bit of electrical noise, which can cause glitches or a stuttering effect in their movement.
 

If you have an input sensor that generates an input voltage from 0-3.3V the Arduino takes that analog voltage and assigns it a value from 0-1023 using an analog to digital converter (ADC.) The code on the Arduino then tells the servo how far to move based upon the converted value. So if your sensor outputs 1.65V then you would get a reading of 511 and your servo would move half of its rotation. Many Arduino boards operate on 5V so the same sensor at the same position would read 2.5V and the servo would still rotate half way. A continuous rotation servo would rotate in one direction, stop as the sensor gave a 1.65V reading and then reverse direction as you caused to sensor to raise the input voltage.
 

Controlling a servo is done by PWM. You send a send a pulse to the servo on the servo signal line every 20 milliseconds. The pulsewidth tells the servo what position to move to. Most servos operate within a 1 to 2 millisecond pulse range so a 1 millisecond pulse tells the servo to move to the 0 degree position and a 2 millisecond pulse tells the servo to move to the 180 degree position. Any pulse between 1 and 2 milliseconds tells the servo to move to a position that is proportionate between 0 and 180 degrees.

I get all my servos here-
http://www.servocity.com
 

DC motors
 

Unlike most servo motors DC motors are best used when you need continuous rotation, especially when you want high RPM. Since DC motors can draw a fair amount of power they are connected to the Arduino output pin using a transistor or a PWM speed controller.

Pololu sells a large variety of small DC motors-
http://www.pololu.com/catalog/category/22
 

Stepper motors
 

I don't usually use stepper motors in my animatronic projects (at least not yet!) but I felt they are worth mentioning. Stepper motors allow for precise positioning as well as continuous rotation and speed control. The drawback to them is that they require a fair bit of electrical power and they're usually significantly larger and heavier than a servo of equal torque rating. Small stepper motors can be salvaged from old printers and scanners. Unlike DC motors stepper motors have multiple individual coils inside that must be activated in a proper sequence in order to get the motor to move. The Arduino controller is able to drive stepper motors using a specific driver chip or transistor array that is capable of energizing each individual coil in the motor. For more information about steppers have a look in the reference section.
 

LEDs
 

Small LEDs are pretty simple to connect to the Arduino- just remember to use a resistor between the Arduino output pin and the resistor cathode to limit the current flow. You can put a resistor on either the anode or cathode of the LED- either way will work. Most of the small 3.3v LEDs will have a forward current of around 20mA so a resistor value around 100 Ohms works pretty well. For accurate resistor value calculations have a look here-
http://led.linear1.org/1led.wiz

For my Iron Man repulsor I made a small 2" diameter LED board that has 24 PLCC-2 LEDs. You can get the bare PCB here-
http://www.batchpcb.com/index.php/Products/41872

The board uses 24 1206 package SMD 100 Ohm resistors-
http://us.element-14.com/vishay-dale/crcw1206100rjnea/resistor-thick-film-100ohm-250mw/dp/59M6948

I frequently buy PLCC-2 super bright LEDs on eBay at good prices-
http://stores.ebay.com/bestshop2008hk

 

High power Luxeon LEDs have a much higher current rating and will work best using some type of constant current source to drive them (there are several instructables on this.) A 1 Watt Luxeon LED will have a forward current of 350mA so you cannot connect it directly to an Arduino output pin. Much like a DC motor you will need to connect it to the output pin using a transistor.

Sparkfun sells Luxeon LEDs and a constant current driver-
http://www.sparkfun.com/search/results?term=Luxeon&what=products
http://www.sparkfun.com/products/9642
 

Transistors
 

A transistor is basically just an electronic switch. Each Arduino output pin is limited to 40mA output current so we'll use a particular type of transistor known as an NPN Darlington transistor to turn on high current devices. These transistors have three pins- the collector, emitter and base. The base pin is connected to the Arduino output pin using a 1K Ohm resistor. The collector pin is attached to the high power device and the emitter pin is connected to ground. When the Arduino output pin is set HIGH the transistor turns on and allows electricity to complete a circuit.

For applications that do not have power requirements over 1 Amp I designed a small transistor board that connects to digital out pins 10-13 using ribbon cable and two eight pin IDC connectors. This uses four SOT-23 package SMD transistors and four 1206 package 1k Ohm SMD resistors. The board is really easy to solder.

Transistor board PCB-
http://batchpcb.com/index.php/Products/41936

SOT-23 NPN Darlington transistors 4 ea-
http://us.element-14.com/fairchild-semiconductor/mmbt6427/bipolar-transistor-npn-40v/dp/58K1891

1206 SMD 1K Ohm resistors 4 ea-
http://us.element-14.com/yageo/rc1206jr-071kl/resistor-thick-film-1kohm-250mw/dp/68R0298

2x4 pin IDC connector 2ea-
http://www.surplusgizmos.com/8-Pin-2x4-IDC-Ribbon-Cable-COnnector_p_1879.html

For loads up to 5A I use a TIP 120 transistor in the TO-220 package. These are great for small DC motors and servos. Use a 1K Ohm resistor to connect the transistor base pin to the Arduino output pin.

I usually buy TIP 120 transistors from my local Radio Shack. They're very easy to get online as well.
 

Power supply
 

To power the Arduino servo board and servos you need two separate power sources- one single cell LiPo battery for the controller and a small 4.8V- 6V battery pack (4AA batteries work just fine) to power servos. The servo board has an additional socket that provides power from the LiPo cell to power low voltage devices like LEDs.

Step 5: Now let's have some fun!

Picture of Now let's have some fun!
Example1Arduino_bb.jpg
Example 1- LEDs
 
This is really simple- we're going to make two LEDs blink and another LED fade. The code will run over and over as soon as you apply power.

It's really easy to set up circuits like this using a breadboard. With each example I'll show how to wire everything up using either the servo board or an Arduino.

Copy and paste this sketch into your Arduino window-

/*
 * Example 1
 * LED Control
 * This example will blink two LEDs and then fade another LED
 * Honus 2010
 * Fading code created 1 Nov 2008 by David A. Mellis, modified 17 June 2009 by Tom Igoe
*/
  
 
   int ledPin1 = 13;  // control pin for LED 
   int ledPin2 = 12;
   int ledPin3 = 11;
  
 
 
   void setup() {
   pinMode(ledPin1, OUTPUT);  // sets the LED pin as output
   pinMode(ledPin2, OUTPUT);
   digitalWrite(ledPin1, LOW);  // sets the LED pin LOW (turns it off)
   digitalWrite(ledPin2, LOW);
  }
 
   void loop()
  {
 
   digitalWrite(ledPin1, HIGH);   // sets the LED pin HIGH (turns it on)
   delay(500);                    // waits 500 milliseconds
   digitalWrite(ledPin2, HIGH);
   delay(500);
   digitalWrite(ledPin1, LOW);    // sets the LED pin LOW (turns it off)
   delay(500);
   digitalWrite(ledPin2, LOW);
   delay(500);
 
  
   // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }
  delay (2000); // wait two seconds 
  }
 
 



Step 6: Using buttons

Picture of Using buttons
Example2Arduino_bb.jpg
Example 2- Using a button input

This is just like the previous example but now the code runs only once after pushing a button. The push button uses a pull down resistor so when the button is pushed the input pin reads HIGH, otherwise it always reads LOW.

Copy and paste this sketch into your Arduino window-

/*
* Example 2
* LED Control using button input
* This example will blink two LEDs and fade another LED when a button is pressed and released
* Honus 2010
* Modified from Adafruit alternating switch code, http://www.adafruit.com
*/
 
 int ledPin1 = 13;  // control pin for LED 
 int ledPin2 = 12;
 int ledPin3 = 11;

int buttonPin = 14; // button is connected to pin 14 (analog in pin 0)
int val; // variable for reading the pin status
int buttonState; // variable to hold the last button state

void setup() {
  pinMode(buttonPin, INPUT);  // set the button pin as input

  Serial.begin(9600);  // set up serial communication at 9600bps
  buttonState = digitalRead(buttonPin); // read the initial state
 
   pinMode(ledPin1, OUTPUT);  // sets the LED pin as output
   pinMode(ledPin2, OUTPUT);
  
}


void loop(){
  val = digitalRead(buttonPin);  // read input value and store it in val

  if (val != buttonState) {  // the button state has changed!
    if (val == LOW) {  // check if the button is pressed
      Serial.println("button pressed");
     
   digitalWrite(ledPin1, HIGH);  // sets the LED pin HIGH (turns it on)
   delay(500);                    // waits 500 milliseconds
   digitalWrite(ledPin2, HIGH);
   delay(500);
   digitalWrite(ledPin1, LOW); // sets the LED pin LOW (turns it off)
   delay(500);
   digitalWrite(ledPin2, LOW);
   delay(500);
 
  
   // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }
    } else {  // the button is -not- pressed...
      Serial.println("button released");
       digitalWrite(ledPin1, LOW);  // turn the LED off
       digitalWrite(ledPin2, LOW);
    }
  }

  buttonState = val;  // save the new state in our variable
}

Step 7: Adding a servo

Picture of Adding a servo
Example3Arduino_bb.jpg
Example 3- Adding a servo controlled by another button

Building on the previous example now we'll add a servo that is tied to a second push button. This uses the Arduino Servo library to control the servo position. By changing the value in parentheses after the servo1.write code you can control how far the servo moves.

Copy and paste this sketch into your Arduino window-

/*
 * Example 3
 * This example will blink two LEDs and then fade another LED when button1 is pressed and released
 * and a servo will move after button2 is pressed and released
 * Honus 2010
 * Modified from Adafruit alternating switch code, http://www.adafruit.com
*/
 

#include  "Servo.h"  // include the servo library

Servo servo1; // creates an instance of the servo object to control a servo

int servoPin1 = 9; // control pin for servo
int ledPin1 = 8;  // control pin for LED 
int ledPin2 = 7;
int ledPin3 = 11;

int buttonPin1 = 14;  // button is connected to pin 14 (analog 0 pin)
int buttonPin2 = 15;  // button is connected to pin 15 (analog 1 pin)
int val1;             // variable for reading the pin status
int val2;
int buttonState1;     // variable to hold the last button state
int buttonState2;              

void setup() {
 
  servo1.attach(servoPin1);   // attaches the servo on pin 9 to the servo object
  pinMode(buttonPin1, INPUT);  // set the button pin as input
  pinMode(buttonPin2, INPUT);

 
  buttonState1 = digitalRead(buttonPin1);   // read the initial state
  buttonState2 = digitalRead(buttonPin2);   // read the initial state
 
   pinMode(ledPin1, OUTPUT);  // sets the LED pin as output
   pinMode(ledPin2, OUTPUT);
  
}


void loop(){
  servo1.write(20);
  val1 = digitalRead(buttonPin1);  // read input value and store it in val
 

  if (val1 != buttonState1) {  // the button state has changed!
    if (val1 == LOW) {  // check if the button is pressed
      Serial.println("button just pressed");
     
   digitalWrite(ledPin1, HIGH);   // sets the LED pin HIGH (turns it on)
   delay(500);                    // wait 500 milliseconds
   digitalWrite(ledPin2, HIGH);
   delay(500);
   digitalWrite(ledPin1, LOW);    // sets the LED pin LOW (turns it off)
   delay(500);
   digitalWrite(ledPin2, LOW);
   delay(500);
 
  
   // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }
    } else { // the button is -not- pressed...
     
       digitalWrite(ledPin1, LOW);  // turn off the LED
       digitalWrite(ledPin2, LOW);
    }
  }
 
   val2 = digitalRead(buttonPin2);      // read input value and store it in val 2

  if (val2 != buttonState2) {          // the button state has changed!
    if (val2 == LOW) {                // check if the button is pressed
     
     
   servo1.write(160);  // rotate the servo to 160 degrees
   delay(3000);   // wait 3 seconds
   servo1.write(20);  // rotate to 20 degrees
 
    } else {                         // the button is -not- pressed...
   
      servo1.write(20);
    }
  }
 
  buttonState1 = val1;                 // save the new state in our variable
  buttonState2 = val2;                
}

Step 8: Sound effects and bend sensors

Example 4- adding sound and using a bend sensor to make an Iron Man hand repulsor

The bend sensor in this example is used as a trigger- once its output value reaches a certain level it causes the Arduino to run the specified code. You can change the threshold value to alter the point at which the sensor acts as a trigger. If you open the Arduino serial monitor window while the servo board is connected to your computer you can see when the bend sensor triggers. The bend sensor is set up using a voltage divider to provide an analog input value on input pin 1.

This example uses the Adafruit Wave Shield to provide sound effects. The instructions for building and setting up the Wave Shield can be found on the Wave Shield web page at http://www.ladyada.net/make/waveshield/

There are several code examples on the Wave Shield page for playing back audio files. The example I used is the play6_hc.pde example located at http://www.ladyada.net/make/waveshield/libraryhcplay6.html

Just download the sound file to a SD memory card and place it in your Wave Shield and you're good to go.

For the wiring schematic I did it two ways. The first version uses a small surface mount transistor board to activate the LED board and the Wave Shield.  The second version uses two TIP 120 transistors instead- they are functionally identical. The big difference is the TIP 120 transistors can handle much larger current loads than the small surface mount transistors- but the TIP 120s take up a lot more space.

The transistors are needed because the Wave Shield needs a switch to tell it when to play the audio file (the transistor grounds the Wave Shield input pin when activated) and multiple LEDs use far more current than a single Arduino output pin can provide.

When the bend sensor is bent far enough the LEDs will fade, the sound file will play and then a servo will move. The servo would be used to open a forearm missile compartment.


For more Iron Man costuming fun check out the SIWDAT site-
http://www.siwdat.com/index.html

Copy and paste this sketch into your Arduino window-

/*
* Example 4
* Bend Sensor/Wave shield
* This example uses a bend sensor as a trigger to fade a LED with sound effect
* using a Wave shield and then activate a servo
* Honus 2010
* Modified from Knock Sensor code created 25 Mar 2007 by David Cuartielles
* and modified 4 Sep 2010 by Tom Igoe
*/

#include "Servo.h"  // include the servo library

 Servo servo1; // creates an instance of the servo object to control a servo

  
// these constants won't change:
    const int servoPin1 = 9; // control pin for servo
    const int triggerSensor = 1; // the sensor is connected to analog pin 1
    const int threshold = 400;  // threshold value to decide when the sensor input triggers
    const int ledPin = 11;
    int soundPin1 = 10;  // control pin for sound board
  
   // these variables will change:
    int sensorReading = 0;  // variable to store the value read from the sensor pin
    int ledState = LOW;  // variable used to store the last LED status, to toggle the light

  void setup() {
   Serial.begin(9600);       // use the serial port
   servo1.attach(servoPin1);   // attaches the servo on pin 9 to the servo object
   pinMode(soundPin1, OUTPUT);  // sets the sound pin as output
      digitalWrite(soundPin1, LOW);
 
  }
 
   void loop()  {
     servo1.write(20); // move the servo to 20 degree position
    
    // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(triggerSensor);   
 
  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
   
   digitalWrite(soundPin1, HIGH); // turn the sound on
   delay(10); // wait ten milliseconds
   digitalWrite(soundPin1, LOW); // turn the sound off
  
    // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);                           
  }

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);        
    // wait for 30 milliseconds to see the dimming effect   
    delay(40);
    // send the string "trigger!" back to the computer, followed by newline
    Serial.println("trigger!");         
  }
 
  servo1.write(160);  // move the servo to 160 degree position
   delay(3000);   // wait 3 seconds
   servo1.write(20);  // move the servo to 20 degree position
  }
  
  delay (3000);  //  three second delay to avoid overloading the serial port buffer
  }
 
 

Step 9: Controlling servos

Picture of Controlling servos
Example5Arduino.jpg

Example 5- controlling a servo using analog input

These two examples show how easy it is to control servos using an analog input. You can use any analog input device you want- I'll use a 10k Ohm potentiometer for the example wiring diagram. As you turn the pot (and change its value) the servo moves proportionally.

The second code example simply extends the first example to control six servos from six inputs. This kind of control comes in really handy if you want to control several servos using bend sensors attached to a glove. This would work really well for controlling an animatronic mask.

/*
* Example 5
* Servo Control
* This example uses a servos and analog input to move the servo according to the sensor input value
* Honus 2010
*/

 #include "Servo.h"  // include the servo library

 Servo servo1;       // creates an instance of the servo object to control a servo

 int analogPin = 0;      // the analog pin that the sensor is on
 int analogValue = 0;    // the value returned from the analog sensor

 int servoPin = 4;       // Control pin for servo motor
 void setup() {
   servo1.attach(servoPin);  // attaches the servo on pin 9 to the servo object
 }

 void loop()
 {
   analogValue = analogRead(analogPin);                 // read the analog input (value between 0 and 1023)
   analogValue = map(analogValue, 0, 1023, 0, 179);     // map the analog value (0 - 1023) to the angle of the servo (0 - 179)
   servo1.write(analogValue);                       // write the new mapped analog value to set the position of the servo
   delay(15);                                           // waits for the servo to get there
 }
 

Example 5a- Controlling 6 servos using multiple inputs

/*
* Example 5a
* Servo Control6
* This example uses 6 servos and analog inputs to move the servos according to the sensor input values
* Honus 2010
*/

 #include       // include the servo library

 Servo servoMotor1;       // creates an instance of the servo object to control a servo
 Servo servoMotor2;
 Servo servoMotor3;
 Servo servoMotor4;
 Servo servoMotor5;
 Servo servoMotor6;

 int analogPin1 = 0;      // the analog pin that the sensor is on
 int analogPin2 = 1;
 int analogPin3 = 2;
 int analogPin4 = 3;
 int analogPin5 = 4;
 int analogPin6 = 5;
 
 int analogValue1 = 0;    // the value returned from the analog sensor
 int analogValue2 = 0;
 int analogValue3 = 0;
 int analogValue4 = 0;
 int analogValue5 = 0;
 int analogValue6 = 0;

 int servoPin1 = 4;       // Control pin for servo motor
 int servoPin2 = 5;
 int servoPin3 = 6;
 int servoPin4 = 7;
 int servoPin5 = 8;
 int servoPin6 = 9;

 void setup() {
   servoMotor1.attach(servoPin1);  // attaches the servo on pin 4 to the servo object
   servoMotor2.attach(servoPin2);  // attaches the servo on pin 5 to the servo object
   servoMotor3.attach(servoPin3);  // attaches the servo on pin 6 to the servo object
   servoMotor4.attach(servoPin4);  // attaches the servo on pin 7 to the servo object
   servoMotor5.attach(servoPin5);  // attaches the servo on pin 8 to the servo object
   servoMotor6.attach(servoPin6);  // attaches the servo on pin 9 to the servo object
 }

 void loop()
 {
   analogValue1 = analogRead(analogPin1);                 // read the analog input (value between 0 and 1023)
   analogValue1 = map(analogValue1, 0, 1023, 0, 179);     // map the analog value (0 - 1023) to the angle of the servo (0 - 179)
   servoMotor1.write(analogValue1);                       // write the new mapped analog value to set the position of the servo
  
   analogValue2 = analogRead(analogPin2);                
   analogValue2 = map(analogValue2, 0, 1023, 0, 179);    
   servoMotor2.write(analogValue2);                      
  
   analogValue3 = analogRead(analogPin3);                
   analogValue3 = map(analogValue3, 0, 1023, 0, 179);    
   servoMotor3.write(analogValue3);                      
  
   analogValue4 = analogRead(analogPin4);                
   analogValue4 = map(analogValue4, 0, 1023, 0, 179);    
   servoMotor4.write(analogValue4);                      
  
   analogValue5 = analogRead(analogPin5);                
   analogValue5 = map(analogValue5, 0, 1023, 0, 179);    
   servoMotor5.write(analogValue5);                      
  
   analogValue6 = analogRead(analogPin6);                
   analogValue6 = map(analogValue6, 0, 1023, 0, 179);    
   servoMotor6.write(analogValue6);                      
  
   delay(15);                                             // waits for the servo to get there
 }


Step 10: Nunchuck control

Picture of Nunchuck control
Example6Arduino.jpg
Example 6- Using a Wii nunchuck as an input device

I wrote this bit of code back in 2007 to use a Wii nunchuck as an input device for an animatronic Predator cannon (see example 7.) The Wii nunchuck communicates to an Arduino over four wires (power, ground, data and clock) using an I²C interface (Inter-Integrated Circuit aka two-wire interface or TWI.)

The Wii nunchuck has a three axis accelerometer, joystick and two push buttons- for $20 it's an awesome input device for Arduino projects. The code presented here is a further modification of the code by Tod Kurt that was presented in his Bionic Arduino class- I simply extended it to control everything but the accelerometer Z axis, which I found I rarely used.

Using this code you can control four servos using the accelerometer and joystick functions and use the two push buttons to turn on LEDs (or transistors or even run a bit of code.)


/*
 * Example 6
 * Nunchuck control for four servos and two button inputs
 * Honus 2007
 * This allows the use of a Wii nunchuck as an input device and is modified/extended from the original code
 * by Tod E. Kurt and Windmeadow Labs
 *2007 Tod E. Kurt, http://todbot.com/blog/
 *The Wii Nunchuck reading code is taken from Windmeadow Labs, http://www.windmeadow.com/node/42
 */

#include "Wire.h" 

int ledPin1 = 13;       // Control pin for LED 1
int ledPin2 = 12;       // Control pin for LED 2
int servoPin1 = 9;      // Control pin for servo motor
int servoPin2 = 8;      // Control pin for servo motor
int servoPin3 = 7;      // Control pin for servo motor
int servoPin4 = 6;      // Control pin for servo motor

int pulseWidth1 = 0;    // Amount to pulse the servo 1
int pulseWidth2 = 0;    // Amount to pulse the servo 2
int pulseWidth3 = 0;    // Amount to pulse the servo 3
int pulseWidth4 = 0;    // Amount to pulse the servo 4

int refreshTime = 20;  // the time in millisecs needed in between pulses

long lastPulse1;
long lastPulse2;
long lastPulse3;
long lastPulse4;

int minPulse = 700;   // minimum pulse width
int loop_cnt=0;

void setup()
{
  Serial.begin(19200);
  pinMode(servoPin1, OUTPUT);  // Set servo pin as an output pin
  pinMode(servoPin2, OUTPUT);  // Set servo pin as an output pin
  pinMode(servoPin3, OUTPUT);  // Set servo pin as an output pin
  pinMode(servoPin4, OUTPUT);  // Set servo pin as an output pin
 
  pulseWidth1 = minPulse;      // Set the motor position to the minimum
  pulseWidth2 = minPulse;      // Set the motor position to the minimum
  pulseWidth3 = minPulse;      // Set the motor position to the minimum
  pulseWidth4 = minPulse;      // Set the motor position to the minimum

  nunchuck_init(); // send the initilization handshake
  Serial.print("NunchuckServo ready\n");
}

void loop()
{
  checkNunchuck1();
  updateServo1();   // update servo 1 position
  checkNunchuck2();
  updateServo2();   // update servo 2 position
  checkNunchuck3();
  updateServo3();   // update servo 3 position
  checkNunchuck4();
  updateServo4();   // update servo 4 position

     if( nunchuck_zbutton() )      // light the LED if z button is pressed
    digitalWrite(ledPin1, HIGH);
  else
    digitalWrite(ledPin1,LOW);
   
     if( nunchuck_cbutton() )      // light the LED if c button is pressed
    digitalWrite(ledPin2, HIGH);
  else
    digitalWrite(ledPin2,LOW);

  delay(1);        // this is here to give a known time per loop
}


void checkNunchuck1()
{
  if( loop_cnt > 100 ) {  // loop()s is every 1msec, this is every 100msec
   
    nunchuck_get_data();
    nunchuck_print_data();

    float tilt = nunchuck_accelx();    // x-axis, in this case ranges from ~70 - ~185
    tilt = (tilt - 70) * 1.5;        // convert to angle in degrees, roughly 
    pulseWidth1 = (tilt * 9) + minPulse; // convert angle to microseconds
   
    loop_cnt = 0;  // reset for
  }
  loop_cnt++;
 
}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo1()
{
  // pulse the servo again if rhe refresh time (20 ms) have passed:
  if (millis() - lastPulse1 >= refreshTime) {
    digitalWrite(servoPin1, HIGH);   // Turn the motor on
    delayMicroseconds(pulseWidth1);   // Length of the pulse sets the motor position
    digitalWrite(servoPin1, LOW);    // Turn the motor off
    lastPulse1 = millis();            // save the time of the last pulse
  }
}

void checkNunchuck2()
{
  if( loop_cnt > 100 ) {  // loop()s is every 1msec, this is every 100msec
   
    nunchuck_get_data();
    nunchuck_print_data();

    float tilt = nunchuck_accely();    // y-axis, in this case ranges from ~70 - ~185
    tilt = (tilt - 70) * 1.5;        // convert to angle in degrees, roughly 
    pulseWidth2 = (tilt * 9) + minPulse; // convert angle to microseconds
   
    loop_cnt = 0;  // reset for
  }
  loop_cnt++;
 
}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo2()
{
  // pulse the servo again if rhe refresh time (20 ms) have passed:
  if (millis() - lastPulse2 >= refreshTime) {
    digitalWrite(servoPin2, HIGH);   // Turn the motor on
    delayMicroseconds(pulseWidth2);   // Length of the pulse sets the motor position
    digitalWrite(servoPin2, LOW);    // Turn the motor off
    lastPulse2 = millis();            // save the time of the last pulse
  }
}

void checkNunchuck3()
{
  if( loop_cnt > 100 ) {  // loop()s is every 1msec, this is every 100msec
   
    nunchuck_get_data();
    nunchuck_print_data();

    float tilt = nunchuck_joyx();    // x-axis, in this case ranges from ~70 - ~185
    tilt = (tilt - 70) * 1.5;        // convert to angle in degrees, roughly 
    pulseWidth3 = (tilt * 9) + minPulse; // convert angle to microseconds
   
    loop_cnt = 0;  // reset for
  }
  loop_cnt++;
 
}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo3()
{
  // pulse the servo again if rhe refresh time (20 ms) have passed:
  if (millis() - lastPulse3 >= refreshTime) {
    digitalWrite(servoPin3, HIGH);   // Turn the motor on
    delayMicroseconds(pulseWidth3);   // Length of the pulse sets the motor position
    digitalWrite(servoPin3, LOW);    // Turn the motor off
    lastPulse3 = millis();            // save the time of the last pulse
  }
}

void checkNunchuck4()
{
  if( loop_cnt > 100 ) {  // loop()s is every 1msec, this is every 100msec
   
    nunchuck_get_data();
    nunchuck_print_data();

    float tilt = nunchuck_joyy();    // y-axis, in this case ranges from ~70 - ~185
    tilt = (tilt - 70) * 1.5;        // convert to angle in degrees, roughly 
    pulseWidth4 = (tilt * 9) + minPulse; // convert angle to microseconds
   
    loop_cnt = 0;  // reset for
  }
  loop_cnt++;
 
}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo4()
{
  // pulse the servo again if rhe refresh time (20 ms) have passed:
  if (millis() - lastPulse4 >= refreshTime) {
    digitalWrite(servoPin4, HIGH);   // Turn the motor on
    delayMicroseconds(pulseWidth4);   // Length of the pulse sets the motor position
    digitalWrite(servoPin4, LOW);    // Turn the motor off
    lastPulse4 = millis();            // save the time of the last pulse
  }
}


//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6];   // array to store nunchuck data,


// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
  Wire.begin();                    // join i2c bus as master
  Wire.beginTransmission(0x52);    // transmit to device 0x52
  Wire.send(0x40);        // sends memory address
  Wire.send(0x00);        // sends sent a zero. 
  Wire.endTransmission();    // stop transmitting
}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
  Wire.beginTransmission(0x52);    // transmit to device 0x52
  Wire.send(0x00);        // sends one byte
  Wire.endTransmission();    // stop transmitting
}

// Receive data back from the nunchuck,
// returns 1 on successful read. returns 0 on failure
int nunchuck_get_data()
{
  int cnt=0;
  Wire.requestFrom (0x52, 6);    // request data from nunchuck
  while (Wire.available ()) {
    // receive byte as an integer
    nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
    cnt++;
  }
  nunchuck_send_request();  // send request for next data payload
  // If we recieved the 6 bytes, then go print them
  if (cnt >= 5) {
    return 1;   // success
  }
  return 0; //failure
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits.  That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
  static int i=0;
  int joy_x_axis = nunchuck_buf[0];
  int joy_y_axis = nunchuck_buf[1];
  int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
  int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
  int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

  int z_button = 0;
  int c_button = 0;

  // byte nunchuck_buf[5] contains bits for z and c buttons
  // it also contains the least significant bits for the accelerometer data
  // so we have to check each bit of byte outbuf[5]
  if ((nunchuck_buf[5] >> 0) & 1)
    z_button = 1;
  if ((nunchuck_buf[5] >> 1) & 1)
    c_button = 1;

  if ((nunchuck_buf[5] >> 2) & 1)
    accel_x_axis += 2;
  if ((nunchuck_buf[5] >> 3) & 1)
    accel_x_axis += 1;

  if ((nunchuck_buf[5] >> 4) & 1)
    accel_y_axis += 2;
  if ((nunchuck_buf[5] >> 5) & 1)
    accel_y_axis += 1;

  if ((nunchuck_buf[5] >> 6) & 1)
    accel_z_axis += 2;
  if ((nunchuck_buf[5] >> 7) & 1)
    accel_z_axis += 1;

  Serial.print(i,DEC);
  Serial.print("\t");

  Serial.print("joy:");
  Serial.print(joy_x_axis,DEC);
  Serial.print(",");
  Serial.print(joy_y_axis, DEC);
  Serial.print("  \t");

  Serial.print("acc:");
  Serial.print(accel_x_axis, DEC);
  Serial.print(",");
  Serial.print(accel_y_axis, DEC);
  Serial.print(",");
  Serial.print(accel_z_axis, DEC);
  Serial.print("\t");

  Serial.print("but:");
  Serial.print(z_button, DEC);
  Serial.print(",");
  Serial.print(c_button, DEC);

  Serial.print("\r\n");  // newline
  i++;
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
  x = (x ^ 0x17) + 0x17;
  return x;
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_zbutton()
{
   return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1;  // voodoo
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_cbutton()
{
   return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1;  // voodoo
}

// returns value of x-axis joystick
int nunchuck_joyx()
{
  return nunchuck_buf[0];
}

// returns value of y-axis joystick
int nunchuck_joyy()
{
  return nunchuck_buf[1];
}

// returns value of x-axis accelerometer
int nunchuck_accelx()
{
  return nunchuck_buf[2];   // FIXME: this leaves out 2-bits of the data
}

// returns value of y-axis accelerometer
int nunchuck_accely()
{
  return nunchuck_buf[3];   // FIXME: this leaves out 2-bits of the data
}

// returns value of z-axis accelerometer
int nunchuck_accelz()
{
  return nunchuck_buf[4];   // FIXME: this leaves out 2-bits of the data
}


Step 11: Predator cannon

Picture of Predator cannon
Example 7- Predator cannon

Using a modified Wii nunchuck board we can make a "head tracking" system to control an animatronic Predator cannon. This system was designed to look like the cannon mechanism in the first Predator movie.

The nunchuck board is removed from its case, the joystick is removed and the board is placed level in the top of the Predator Bio helmet. The wires are extended for the buttons so they can be used as fingertip buttons to activate the cannon and trigger the firing sequence.

To remove the circuit board from the Wii nunchuck case you'll need a tri-wing screwdriver-
http://www.play-asia.com/paOS-13-71-1e-49-en-70-1fe.html

The sound effect is handled just like the Iron Man repulsor in example 4 using the Adafruit Wave Shield. Since the Wave Shield code used can support six individual sounds you can add five other Predator sounds and activate them using fingertip switches- neat!

There is one servo that is geared 4:1 that raises the cannon arm- in the code you can see this as the servo rotating 180 degrees, thereby raising the cannon arm 45 degrees. The other two servos aim the cannon using the accelerometer inputs. There are transistors that turn on the aiming servos and laser sight when one button is pressed. If the aiming servos were always on then the cannon would rotate even when it was in the lowered position, so they need a way of being turned off when the cannon is lowered.

So push one one button and the cannon raises up, the aiming servos turn on and the laser sight turns on. Push the second button and the cannon fires- two transistors turn on the cannon LED and activate the firing sound. Three red LEDs can be used in place of the laser sight. The cannon LED can be anything from several small LEDs to a high power Luxeon LED. When using a high power Luxeon LED be sure to use a constant current driver to power it.

Servos can draw a fair bit of power so I use a TIP 120 transistor to turn on the aiming servos.

The prototype cannon mechanism was built using Delrin plastic scraps and timing belts and gears from old desktop printers and photocopiers I found in the trash. When I build the final version for the Predator costume it will probably be entirely gear driven to make it more compact and cleaner.



For Predator costuming info check out http://www.thehunterslair.com

Those individuals interested in obtaining a resin cannon casting should contact my friend Carl here- http://www.accurizedhunterparts.com/

Carl's work is absolutely brilliant- check out the photos below of the Predator backpack clay sculpt that he created for this project. That's a lot of clay! When contacting Carl please be patient as he's extremely busy and he has a large backlog of work.


Here's the code-


/*
 * Example 7
 * Predator Cannon
 * This uses a modified Wii nunchuck as a head tracking input device to control an animatronic Predator cannon
 * Adafruit Wave shield is used for sound effects
 * Honus 2007, updated 2010
 * Wii nunchuck reading code modified/extended from nunchuck code by Tod E. Kurt and Windmeadow Labs
 * 2007 Tod E. Kurt, http://todbot.com/blog/
 * The Wii Nunchuck reading code is taken from Windmeadow Labs, http://www.windmeadow.com/node/42
*/

 
#include  "Wire.h" // include the Wire library
#include   "Servo.h" // include the servo library

Servo servo3;  // creates an instance of the servo object to control a servo

int controlPin1 = 6; // Control pin for sound effects board using z button
int transistorPin1 = 13; // Control pin for LED using z button
int transistorPin2 = 12; // Control pin for laser sight using c button
int transistorPin3 = 11; // Control pin for servo 1 using c button
int transistorPin4 = 10; // Control pin for servo 2 using c button
int servoPin1 = 7; // Control pin for servo 1 using accelerometer x axis
int servoPin2 = 8; // Control pin for servo 2 using accelerometer y axis
int servoPin3 = 9;  // control pin for arm servo

int pulseWidth1 = 0; // Amount to pulse the servo 1
int pulseWidth2 = 0; // Amount to pulse the servo 2


int refreshTime = 20; // the time in millisecs needed in between servo pulses
long lastPulse1;
long lastPulse2;

int minPulse = 700; // minimum servo pulse width
int loop_cnt=0;

boolean button_down = false;
unsigned long start;


void setup()
{
Serial.begin(19200);

servo3.attach(servoPin3);  // attaches the servo on pin 9 to the servo object
 
pinMode(controlPin1, OUTPUT); // Set control pin 1 as output
pinMode(transistorPin1, OUTPUT); // Set transistor pin 1 as output
pinMode(transistorPin2, OUTPUT); // Set transistor pin 2 as output
pinMode(transistorPin3, OUTPUT); // Set transistor pin 3 as output
pinMode(transistorPin4, OUTPUT); // Set transistor pin 4 as output
pinMode(servoPin1, OUTPUT); // Set servo pin 1 as output
pinMode(servoPin2, OUTPUT); // Set servo pin 2 as output

pulseWidth1 = minPulse; // Set the servo position to the minimum
pulseWidth2 = minPulse; // Set the servo position to the minimum

nunchuck_init(); // send the initilization handshake
Serial.print("NunchuckServo ready\n");
}

void loop()
{
checkNunchuck1();
updateServo1(); // update servo 1 position
checkNunchuck2();
updateServo2(); // update servo 2 position


if( nunchuck_cbutton() ) {
digitalWrite(transistorPin2, HIGH); // turn on transistor pin 2 if c button is pressed
digitalWrite(transistorPin3, HIGH); // turn on transistor pin 3 if c button is pressed
digitalWrite(transistorPin4, HIGH); // turn on transistor pin 4 if c button is pressed

servo3.write(180);
}
else {
digitalWrite(transistorPin2, LOW);
digitalWrite(transistorPin3, LOW);
digitalWrite(transistorPin4, LOW);
servo3.write(0);
}

if ( nunchuck_zbutton() )
{
if (!button_down) // if button was just pressed do this
{
digitalWrite(controlPin1, HIGH);
button_down = true;
start = millis();
}
else if (millis() - start > 1200)  // if timer has elapsed do this
{
digitalWrite(transistorPin1, HIGH);
}
}
else // if button is up do this
{
button_down = false;
digitalWrite(controlPin1, LOW);
digitalWrite(transistorPin1, LOW);
}


delay(1); // this is here to give a known time per loop
}


void checkNunchuck1()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float tilt = nunchuck_accelx(); // x-axis, in this case ranges from ~70 - ~185
tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth1 = (tilt * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo1()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse1 >= refreshTime) {
digitalWrite(servoPin1, HIGH); // Turn the servo on
delayMicroseconds(pulseWidth1); // Length of the pulse sets the servo position
digitalWrite(servoPin1, LOW); // Turn the servo off
lastPulse1 = millis(); // save the time of the last pulse
}
}

void checkNunchuck2()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float tilt = nunchuck_accely(); // y-axis, in this case ranges from ~70 - ~185
tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth2 = (tilt * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo2()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse2 >= refreshTime) {
digitalWrite(servoPin2, HIGH);  // Turn the servo on
delayMicroseconds(pulseWidth2); // Length of the pulse sets the servo position
digitalWrite(servoPin2, LOW); // Turn the servo off
lastPulse2 = millis(); // save the time of the last pulse
}
}

//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6]; // array to store nunchuck data,

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x40); // sends memory address
Wire.send(0x00); // sends sent a zero.
Wire.endTransmission(); // stop transmitting
}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}

// Receive data back from the nunchuck,
// returns 1 on successful read. returns 0 on failure
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we recieved the 6 bytes, then go print them
if (cnt >= 5) {
return 1; // success
}
return 0; //failure
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits. That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
static int i=0;
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

int z_button = 0;
int c_button = 0;

// byte nunchuck_buf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if ((nunchuck_buf[5] >> 0) & 1)
z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1)
c_button = 1;

if ((nunchuck_buf[5] >> 2) & 1)
accel_x_axis += 2;
if ((nunchuck_buf[5] >> 3) & 1)
accel_x_axis += 1;

if ((nunchuck_buf[5] >> 4) & 1)
accel_y_axis += 2;
if ((nunchuck_buf[5] >> 5) & 1)
accel_y_axis += 1;

if ((nunchuck_buf[5] >> 6) & 1)
accel_z_axis += 2;
if ((nunchuck_buf[5] >> 7) & 1)
accel_z_axis += 1;

Serial.print(i,DEC);
Serial.print("\t");

Serial.print("joy:");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(" \t");

Serial.print("acc:");
Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print("\t");

Serial.print("but:");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);

Serial.print("\r\n"); // newline
i++;
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_zbutton()
{
return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1; // voodoo
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_cbutton()
{
return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1; // voodoo
}

// returns value of x-axis joystick
int nunchuck_joyx()
{
return nunchuck_buf[0];
}

// returns value of y-axis joystick
int nunchuck_joyy()
{
return nunchuck_buf[1];
}

// returns value of x-axis accelerometer
int nunchuck_accelx()
{
return nunchuck_buf[2]; // FIXME: this leaves out 2-bits of the data
}

// returns value of y-axis accelerometer
int nunchuck_accely()
{
return nunchuck_buf[3]; // FIXME: this leaves out 2-bits of the data
}

// returns value of z-axis accelerometer
int nunchuck_accelz()
{
return nunchuck_buf[4]; // FIXME: this leaves out 2-bits of the data
}

Step 12: War Machine cannon

Picture of War Machine cannon
Example 8- War Machine cannon

You want to be the War Machine? This example is based on the Predator cannon but uses a motor connected to a transistor to spin the cannon barrels. When you push the fire button the motor turns on. There is a 1N4004 diode to prevent back voltage from the motor damaging the controller output pin.

A War Machine cannon is substantially larger than a Predator cannon and would require larger, more powerful servos so I have individual TIP 120 transistors shown on the wiring diagram.

For mounting the cannon Servocity sells pan/tilt mechanisms that would be perfect for this application-
http://www.servocity.com/html/spt200_pan___tilt_system.html


/*
 * Example 8
 * Iron Man War Machine Cannon
 * This uses a modified Wii nunchuck as a head tracking input device to control an animatronic Iron Man War Machine cannon
 * Adafruit Wave shield is used for sound effects
 * Honus 2010
 * Wii nunchuck reading code modified/extended from nunchuck code by Tod E. Kurt and Windmeadow Labs
 * 2007 Tod E. Kurt, http://todbot.com/blog/
 * The Wii Nunchuck reading code is taken from Windmeadow Labs, http://www.windmeadow.com/node/42
*/

 #include "Wire.h"  // include the Wire library

int controlPin1 = 7; // Control pin for sound effects board using z button 
int transistorPin1 = 13; // Control pin for cannon LED using z button 
int transistorPin2 = 12; // Control pin for servo 1 using c button
int transistorPin3 = 11; // Control pin for servo 2 using c button
int transistorPin4 = 10; // Control pin for cannon motor using z button
int servoPin1 = 9; // Control pin for servo 1 using accelerometer x axis
int servoPin2 = 8; // Control pin for servo 2 using accelerometer y axis

int pulseWidth1 = 0; // Amount to pulse the servo 1
int pulseWidth2 = 0; // Amount to pulse the servo 2


int refreshTime = 20; // the time in millisecs needed in between servo pulses
long lastPulse1;
long lastPulse2;

int minPulse = 700; // minimum servo pulse width
int loop_cnt=0;

boolean button_down = false;
unsigned long start;


void setup()
{
Serial.begin(19200);
 
pinMode(controlPin1, OUTPUT); // Set control pin 1 as output
pinMode(transistorPin1, OUTPUT); // Set transistor pin 1 as output
pinMode(transistorPin2, OUTPUT); // Set transistor pin 2 as output
pinMode(transistorPin3, OUTPUT); // Set transistor pin 3 as output
pinMode(transistorPin4, OUTPUT); // Set transistor pin 4 as output
pinMode(servoPin1, OUTPUT); // Set servo pin 1 as output
pinMode(servoPin2, OUTPUT); // Set servo pin 2 as output

pulseWidth1 = minPulse; // Set the servo position to the minimum
pulseWidth2 = minPulse; // Set the servo position to the minimum

nunchuck_init(); // send the initilization handshake
Serial.print("NunchuckServo ready\n");
}

void loop()
{
checkNunchuck1();
updateServo1(); // update servo 1 position
checkNunchuck2();
updateServo2(); // update servo 2 position


if( nunchuck_cbutton() ) {
digitalWrite(transistorPin2, HIGH); // turn on transistor pin 2 if c button is pressed
digitalWrite(transistorPin3, HIGH); // turn on transistor pin 3 if c button is pressed
}
else {
digitalWrite(transistorPin2, LOW); // turn off transistor pin 2
digitalWrite(transistorPin3, LOW);
}

if ( nunchuck_zbutton() )
{
if (!button_down) // if button was just pressed do this
{
digitalWrite(controlPin1, HIGH); // turn on sound effect
button_down = true;
start = millis();
}
else if (millis() - start > 1200)  // if timer has elapsed do this
{
digitalWrite(transistorPin1, HIGH); // turn on cannon LED
digitalWrite(transistorPin4, HIGH); // turn on cannon motor
}
}
else // if button is up do this
{
button_down = false;
digitalWrite(controlPin1, LOW); // turn off sound effect
digitalWrite(transistorPin1, LOW); // turn off cannon LED
digitalWrite(transistorPin4, LOW); // turn off cannon motor
}


delay(1); // this is here to give a known time per loop
}


void checkNunchuck1()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float tilt = nunchuck_accelx(); // x-axis, in this case ranges from ~70 - ~185
tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth1 = (tilt * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo1()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse1 >= refreshTime) {
digitalWrite(servoPin1, HIGH); // Turn the servo on
delayMicroseconds(pulseWidth1); // Length of the pulse sets the servo position
digitalWrite(servoPin1, LOW); // Turn the servo off
lastPulse1 = millis(); // save the time of the last pulse
}
}

void checkNunchuck2()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

float tilt = nunchuck_accely(); // y-axis, in this case ranges from ~70 - ~185
tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly
pulseWidth2 = (tilt * 9) + minPulse; // convert angle to microseconds

loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo2()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse2 >= refreshTime) {
digitalWrite(servoPin2, HIGH);  // Turn the servo on
delayMicroseconds(pulseWidth2); // Length of the pulse sets the servo position
digitalWrite(servoPin2, LOW); // Turn the servo off
lastPulse2 = millis(); // save the time of the last pulse
}
}

//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6]; // array to store nunchuck data,

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x40); // sends memory address
Wire.send(0x00); // sends sent a zero.
Wire.endTransmission(); // stop transmitting
}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}

// Receive data back from the nunchuck,
// returns 1 on successful read. returns 0 on failure
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we recieved the 6 bytes, then go print them
if (cnt >= 5) {
return 1; // success
}
return 0; //failure
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits. That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
static int i=0;
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

int z_button = 0;
int c_button = 0;

// byte nunchuck_buf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if ((nunchuck_buf[5] >> 0) & 1)
z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1)
c_button = 1;

if ((nunchuck_buf[5] >> 2) & 1)
accel_x_axis += 2;
if ((nunchuck_buf[5] >> 3) & 1)
accel_x_axis += 1;

if ((nunchuck_buf[5] >> 4) & 1)
accel_y_axis += 2;
if ((nunchuck_buf[5] >> 5) & 1)
accel_y_axis += 1;

if ((nunchuck_buf[5] >> 6) & 1)
accel_z_axis += 2;
if ((nunchuck_buf[5] >> 7) & 1)
accel_z_axis += 1;

Serial.print(i,DEC);
Serial.print("\t");

Serial.print("joy:");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(" \t");

Serial.print("acc:");
Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print("\t");

Serial.print("but:");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);

Serial.print("\r\n"); // newline
i++;
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_zbutton()
{
return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1; // voodoo
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_cbutton()
{
return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1; // voodoo
}

// returns value of x-axis joystick
int nunchuck_joyx()
{
return nunchuck_buf[0];
}

// returns value of y-axis joystick
int nunchuck_joyy()
{
return nunchuck_buf[1];
}

// returns value of x-axis accelerometer
int nunchuck_accelx()
{
return nunchuck_buf[2]; // FIXME: this leaves out 2-bits of the data
}

// returns value of y-axis accelerometer
int nunchuck_accely()
{
return nunchuck_buf[3]; // FIXME: this leaves out 2-bits of the data
}

// returns value of z-axis accelerometer
int nunchuck_accelz()
{
return nunchuck_buf[4]; // FIXME: this leaves out 2-bits of the data
}

Step 13: Going wireless with XBee


Example 9- Wireless XBee radios

This allows you to use the Nunchuck control but does it by setting up one controller as a transmitter and another controller as the receiver. I use the Adafruit XBee wireless adapter because it's super easy to use and can work on both 3V and 5V so it's great for most any Arduino wireless project. The servo board is set up for point to point communication and the XBee adapter plugs directly into a socket at the top of the board. This setup would really well for controlling haunted house attractions.

You can get the XBee adapter and radios here-
http://www.adafruit.com/index.php?main_page=product_info&cPath=29&products_id=126

There is a complete XBee tutorial for building the XBee adapter and configuring it here-
http://www.ladyada.net/make/xbee/

Unlike the previous nuchuck control code, this code uses a new nunchuck library that cleans up the code considerably. It is called nunchuck_funcs.h
You can get it here-
http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/comment-page-3/

Simply place the nunchuck_funcs.h library into your Arduino libraries folder and you're good to go.

The wiring for this is exactly like the wiring for example 6 except the nunchuck is connected to the transmitter and the servos and LEDs are connected to the receiver.

Note- you cannot connect the USB to serial adapter while the XBee adapter is plugged into its socket as they use the same data transmission lines. You must program the controller first and then plug in the XBee adapter. If you need to be able to monitor the serial port while using the XBee you can use a couple of wires to connect the XBee RX and TX to digital out pins 2 and 3 as shown in the Adafruit point-to-point tutorial.


Here's the code for the transmitter-

/*
 * Example 9a
 * Nunchuck XBee transmitter
 * This code uses the nunchuck functions library and an XBee radio (w/ Adafruit XBee adapter)
 * to make a Wii nunchuck a wireless input device
 * Honus 2010
 * Nunchuck functions library from Tod E. Kurt, http://todbot.com/blog
*/


#include "Wire.h" // include the Wire library
#include "nunchuck_funcs.h" // include the nunchuck functions library

int loop_cnt=0;

byte accx,accy,zbut,cbut,joyy,joyx;
int ledPin = 13;

void setup()
{
    Serial.begin(9600);
    nunchuck_setpowerpins();
    nunchuck_init(); // send the initilization handshake
    pinMode(ledPin, OUTPUT);
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // set the LED on  

    if( loop_cnt > 100 ) { // every 100 msecs get new data
        loop_cnt = 0;

        nunchuck_get_data();

        accx  = nunchuck_accelx(); // ranges from approx 70 - 182
        accy  = nunchuck_accely(); // ranges from approx 65 - 173
        zbut = nunchuck_zbutton();
        cbut = nunchuck_cbutton();
        joyx = nunchuck_joyx();
        joyy = nunchuck_joyy();

        Serial.print("joyx:");
        Serial.print((byte)joyx,DEC);
        Serial.print("joyy:");
        Serial.print((byte)joyy,DEC);
        Serial.print("accx:");
        Serial.print((byte)accx,DEC);
        Serial.print("accy:");
        Serial.print((byte)accy,DEC);
        Serial.print("\tzbut:");
        Serial.print((byte)zbut,DEC);
        Serial.print("\tcbut:");
        Serial.println((byte)cbut,DEC);
    }
    loop_cnt++;
    delay(1);
}


Here's the code for the receiver-

/*
 * Example 9b
 * Nunchuck XBee receiver
 * This code receives input from a Wii nunchuck using an XBee radio (w/ Adafruit XBee adapter)
 * and controls four servos and two digital pins to turn on LEDs
 * Honus 2010
*/


#include "Servo.h" // include the Servo library

int joyx,joyy = 135;
int accx,accy = 135;
int zbut,cbut = 0;
int ledPin1 = 13;
int ledPin2 = 12;
int lightvalue1 = 255;
int lightvalue2 = 255;
char nunchuckData;
int val = 0;
int tempval = 0;
int servo1Pos;
int servo2Pos;
int servo3Pos;
int servo4Pos;
int buttonState1 = 0;
int buttonState2 = 0;
int lightMode1 = 0;
int lightMode2 = 0;

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

int servoPin1 = 9;
int servoPin2 = 8;
int servoPin3 = 7;
int servoPin4 = 6;


void setup()
{
//  Serial.begin(9600);
//  Serial.print("Nunchuck ready\n");
    Serial.begin(9600);

    servo1.attach(servoPin1);
    servo2.attach(servoPin2);
    servo3.attach(servoPin3);
    servo4.attach(servoPin4);
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
}

void loop() {
 
  if (accy > 125) {
    servo1Pos = 90-(accy-125);
    if (servo2Pos < 45)
      servo1Pos = 45;
    servo1.write(servo1Pos);
  }
  if (accy < 125) {
    servo1Pos = 90+(125-accy);
    if (servo1Pos > 135)
      servo1Pos = 135;
    servo1.write(servo1Pos);
  }
 
 
  if (accx > 125) {
    servo2Pos = 90-(accx-125);
    if (servo2Pos < 45)
      servo2Pos = 45;
    servo2.write(servo2Pos);
  }
  if (accx < 125) {
    servo2Pos = 90+(125-accx);
    if (servo2Pos > 135)
      servo2Pos = 135;
    servo2.write(servo2Pos);
  }
 
   if (joyy > 125) {
    servo3Pos = 90-(joyy-125);
    if (servo3Pos < 45)
      servo3Pos = 45;
    servo3.write(servo3Pos);
  }
   if (joyy < 125) {
    servo3Pos = 90+(125-joyy);
    if (servo3Pos > 135)
      servo3Pos = 135;
    servo3.write(servo3Pos);
  }
 
 
  if (joyx > 125) {
    servo4Pos = 90-(joyx-125);
    if (servo4Pos < 45)
      servo4Pos = 45;
    servo4.write(servo4Pos);
  }
  if (joyx < 125) {
    servo4Pos = 90+(125-joyx);
    if (servo4Pos > 135)
      servo4Pos = 135;
    servo4.write(servo4Pos);
  }
 
  if (cbut != buttonState1) {         // the button state has changed!
    if (cbut == 1) {                  // check if the button is pressed
      if (lightMode1 == 0) {          // light is off
        lightMode1 = 1;               // light is on!
        digitalWrite(ledPin1, HIGH);
      } else {
        lightMode1 = 0;               // light is on!
        digitalWrite(ledPin1, LOW);
      }
    }
  }
 
  if (zbut != buttonState2) {         // the button state has changed!
    if (zbut == 1) {                  // check if the button is pressed
      if (lightMode2 == 0) {          // light is off
        lightMode2 = 1;               // light is on!
        digitalWrite(ledPin2, HIGH);
      } else {
        lightMode2 = 0;               // light is on!
        digitalWrite(ledPin2, LOW);
      }
    }
  }
  buttonState1 = cbut;               // save the new state in our variable
  buttonState2 = zbut;               // save the new state in our variable
 
 
 
  while(Serial.available()) {
    tempval = Serial.read();
    if (tempval=='x')    {
     nunchuckData='x';
     val=0;
    }
    else if (tempval=='y')    {
      nunchuckData='y';
      val=0;
    }
    else if (tempval=='X')    {
      nunchuckData='X';
      val=0;
    }
    else if (tempval=='Y')    {
      nunchuckData='Y';
      val=0;
    }
    else if (tempval=='Z')    {
      nunchuckData='Z';
      val=0;
    }
    else if (tempval=='C')    {
      nunchuckData='C';
      val=0;
    }
    else if (tempval >='0' && tempval <= '9')  {
      val=val * 10;
      val=val + (tempval - '0');

      if (nunchuckData=='x'){
        joyx=val;
      }
      else if (nunchuckData=='y'){
        joyy=val;
      }
      else if (nunchuckData=='X'){
        accx=val;
      }
      else if (nunchuckData=='Y'){
        accy=val;
      }
      else if (nunchuckData=='Z'){
        zbut=val;
      }
      else if (nunchuckData=='C'){
        cbut=val;
      }
    }
  }  //end of input in serial buffer
}

Step 14: Resources

So that's it for now- I'll be adding more code examples and mechanisms as time goes on.

Here's some additional material to check out:

Animatronics-
Here's an awesome show reel that displays the capabilities of animatronics-
http://www.johnnolanfilms.com/animatronics/showreel-flash-2010.php

Electronics classes-

Once you're comfortable with Arduino and you want to move into a greater understanding of electronics and circuits have a look at Contextual Electronics. Chris Gammell (of the Amp Hour podcast) created Contextual Electronics as a site dedicated to teaching electronics in an easy-to-understand way with lots of hands-on interaction. Highly recommended!

http://www.contextualelectronics.com

Soldering tutorials-
This is the first in a great series of SMD soldering tutorials-
http://www.sparkfun.com/tutorials/36

Basic soldering skills-
http://www.sparkfun.com/tutorials/106

Arduino tutorials-
http://www.ladyada.net/learn/arduino/index.html

http://www.arduino.cc/playground/

Using Eagle to make PCBs-
http://www.sparkfun.com/tutorials/108

Books-

MAKE: Electronics- If you're just getting into electronics or need a refresher this is a great book
http://www.amazon.com/MAKE-Electronics-Learning-Through-Discovery/dp/0596153740/ref=sr_1_1?s=books&ie=UTF8&qid=1291095250&sr=1-1

Making Things Talk- everything you ever wanted to know about Arduino and communication techniques
http://www.amazon.com/Making-Things-Talk-Practical-Connecting/dp/0596510519/ref=sr_1_1?ie=UTF8&s=books&qid=1291014224&sr=1-1

Practical Arduino- A great book with awesome Arduino projects
http://www.amazon.com/Practical-Arduino-Projects-Hardware-Technology/dp/1430224770/ref=sr_1_2?ie=UTF8&s=books&qid=1250109738&sr=8-2

Physical Computing- It's not Arduino specific as it predates it but it's THE book to have regarding physical computing; everything from servos and stepper motors to LEDs and sensors- it's all in there
http://www.amazon.com/Physical-Computing-Sensing-Controlling-Computers/dp/159200346X/ref=sr_1_1?s=books&ie=UTF8&qid=1291014345&sr=1-1

Making Things Move- Looks like a great book for learning how to design all kinds of mechanisms.
http://www.makingthingsmove.com/
http://www.amazon.com/dp/0071741674?tag=makingthingsm-20&camp=14573&creative=327641&linkCode=as1&creativeASIN=0071741674&adid=1RG5X8SW1YZDQ0MMAXDR&

No Strings Attached- A great book about the Jim Henson Creature shop
http://www.amazon.com/No-Strings-Attached-Hensons-Creature/dp/185227669X/ref=sr_1_2?s=books&ie=UTF8&qid=1291014513&sr=1-2

The Winston Effect- Amazing photos and information about all kinds of animatronic creations
http://www.amazon.com/Winston-Effect-History-Stan-Studio/dp/1845761502/ref=sr_1_1?ie=UTF8&s=books&qid=1291014636&sr=1-1

Step 15: FAQs


Frequently asked questions-

Do you offer a servo board kit?
Nope- at least not yet. I might be coaxed into making a fully assembled board though...just message me if you want one.

Will you do custom work?
On occasion- message me to discuss your project.

I need help with my own code/project- is there a forum for help?
The Arduino forum is the place to go-
http://arduino.cc/cgi-bin/yabb2/YaBB.pl


The Predator setup isn't really a true head tracking system- why?
When I first started looking at this I had just envisioned a simple system that was controlled using bend sensors on your fingers and it wouldn't be able to look up and down. That really was a bit cumbersome to operate and wasn't very natural.

Next I looked at keeping the bend sensor that would raise the cannon, but I figured out a system that had a cable mounted under the mask that turned a pulley/spring loaded potentiometer (mounted under the cannon mechanism) that would allow the cannon to follow your head rotation. It still wasn't able to look up/down. Now I got a natural (and smooth) rotation but fixing/routing the cable was difficult and cumbersome. Mask removal could also be a real problem.

Then I started looking at different kinds of sensors. Gyroscopic, compass and accelerometers. Combo boards, IMUs (inertial measurement units), etc. I have a friend that is a data acquisition engineer as well as a friend that is a programmer and I spoke to several electrical engineers for help. Compasses are affected by tilt, so you have to compensate for that and then they don't work when you rotate your whole body vs. just your head, so dual compasses would be necessary and you would have to write code to differentiate between the two.

The problem with gyros is that you need two of them, preferably with an accelerometer to account for drift as well as front/rear tilt (pitch). One gyro really won't work well because it will respond to whole body rotation as well as just head rotation, so you would need one IMU at the head and another at the cannon base and then you have to write some code to differentiate between the two. Gyros really only sense change in angular velocity so its output only changes with respect to movement and it will reset itself once you stop rotating your body- the cannon will quickly become out of sync with your movements. That's why to really do it right you need a multiple DOF (degree of freedom) IMU and you need two of them for true head tracking. Most of the systems I've seen that people post online as a head tracking system for R/C or video control that use these types of sensors have pretty poor yaw control and I think this is why. And they don't even have to deal with the body vs. head rotation issue as they can sit in a chair- not an option for costuming.

There are IMUs and digital compasses available now that have on board processing and are programmed to account for drift and tilt so some of the hard work is done for you but you would still have to factor in the difference output of two of them and then generate your necessary servo movement values from that. It can be done but it's pretty darn expensive.

Most of the solutions I found were pretty complex in terms of programming requiring sophisticated algorithms and/or extremely expensive on the hardware side. There are also pretty severe space restrictions for fitting sensors inside the Predator Bio helmet as some of the IMUs available are pretty large physically. 

Then I found that I could modify the sensor board out of a Wii nunchuck controller and interface it with a microcontroller over its I²C bus. This provided me with an inexpensive and reliable multi axis accelerometer and two finger pushbuttons with an easy to use interface. I ended up writing code that would allow me to access all of the nunchuck's functions- the accelerometer outputs, the joystick and the two pushbuttons.

When it was all said and done the rotation was still a bit of a problem as the accelerometer only really gives you a stable output with respect to gravity so you have to tilt it to get the rotation. What I found was that if I mounted it as level as possible in Predator helmet it really didn't need much tilt at all to get a stable rotation. The beauty of this system is that there are only only two finger buttons to control everything- it's also pretty easy for me to modify the code. I haven't yet taken apart a Wii Motion Plus to combine it with a nunchuck to create an inexpensive IMU but I'll post the results when I do.

What I did was to basically fake it by strictly using the accelerometer inputs- when looking sideways you just need to tilt your head to the side like a bird for yaw (rotation) control. The accelerometer reads the tilt and moves everything accordingly- the pitch function is normal. It does take a bit of getting used to but after a while it becomes more natural and it's very convincing.

For costuming all you need to do is provide the illusion. When I started the project with a friend three years ago (he's sculpting the Pedator backpack) we wanted something that anyone could build from readily available building blocks to add some cool animatronics to their Predator costume without spending a ton of cash.

Whew...

I want to power my project and I only want to use one battery to supply different voltages- what do I do?
I would use a switching step down voltage regulator like this one-
http://www.pololu.com/catalog/product/2110
It's far more efficient than using a traditional voltage regulator, especially if you need to use something like a 12V battery and drop it down to 5V for servo power.  If you need to drop 5V to 3.3V then a traditional voltage regulator is fine. Just don't plug it into the JST connector on the controller board and then plug in a USB cable into the USB mini-B port for the charging circuit- that would be bad.






1-40 of 105Next »

HI, you mentioned possibly building and assembling an Arduino animatronics board at a price. I'm not sure if this is something i could successfully build on my own, but I would be interested in building an adruino board with an Xbee chip that would power my repulsors and Unibeam with sound, helmet opening/closing with eyes lit up flickering when closed, and mini gun movement (spinning and movement tracking for my War Machine costume, I would be really interested in getting some pricing on what it would cost to build. If that is something you may have time or be interested in building, please let me know. Sincerely, ~greg my email is thegovernor08@yahoo.com

And thanks again for all of the helpful information.

Honus,

Absolutely amazing work and I want to thank you very much for all the effort that has gone into this as well as taking and answering questions and comments!
I am just getting started with arduino and hope you can help me if at all possible. I'm planning a project for Halloween that includes a "Nullifier Ray" attached to the ceiling. I would like to have the body of the ray drop (tilt) down from level with the ceiling, and swing (pan) to the right to point at an object on a table. Then, I'd like the barrel to begin to spin and ultimately activate several super bright LEDs to simulate a "blast" from the ray. Sound would be great but isn't necessary.
Does this sound possible for a beginner such as myself and if so, would it be possible for you to help me work parts of your code to make it happen?
Thank you for any advice or help you can provide. I'm overwhelmed by all the information in this instructable!
Honus (author)  The Tinkerers Apprentice2 months ago
Thanks! Of course your project is possible to do and I'm happy to help. Just work up a drawing or schematic with the specifics of what you want it to do and message me. The important things you need to figure out is the range of movement you need, how heavy it will be and how you want to power and activate it.
Partybot5 months ago

Thank you for all the time you out into this, especially the purchase links. I'll be sure to share projects that result from the info.

TryChick6 months ago

Honus,

I'm wondering if I need a voltage regulator with the Pro Mini. Reading on the Arduino website, it says:

"The Arduino Pro Mini can be powered with an FTDI cable or breakout board
connected to its six pin header, or with a regulated 3.3V or 5V supply
(depending on the model) on the Vcc pin. There is a voltage regulator on
board so it can accept voltage up to 12VDC. If you're supplying
unregulated power to the board, be sure to connect to the "RAW" pin on
not VCC."

I'm trying to figure out how to connect a G4 LED light which is rated to 9-15V DC to the Pro Mini to use in my IM gloves with a flex sensor to turn them on and off. I'm testing with my mega 2560 and have the flex sensor figured out but am trying to figure out how I am supposed to connect the light and the flex sensor and the battery to the pro mini. It sounds like I should be able to use an E23A battery which is 12 volts, but I don't want to fry the board, and have no idea how to wire all of these together as I'm just getting started with the electronics stuff. Any hints?

Honus (author)  TryChick6 months ago
There's a few different ways you can do this. You could use a 7805 voltage regulator to drop the voltage from your battery to 5V to power the ProMini and connect it to the VCC pin ( assuming you have the 5V version ProMini ) if you're worried about frying it. Some batteries are rated at maybe 12V but at full charge they can overshoot this by a fair amount.

Then you can also connect your 12V battery to your LED light using a transistor to turn it on and off- the ProMini will not be able to provide enough current to drive it so it cannot be directly connected to an output pin. You can use something like a TIP120 transistor to turn the LED on and off.

Just let me know if you need a wiring diagram! It's pretty simple to do. :)
TryChick Honus6 months ago

Hmm. Well, I bought 4 of the 3.3 volt Pro Minis to use in various parts of the suit, but may be able to return them to SparkFun as they haven't been opened. I got them because I figured fewer batteries to power the boards would save space. Would you recommend doing that or is there a workaround? And a diagram would be awesome! Can't tell you how many times I've poured over your tutorial and am just amazed at what you've done.

Honus (author)  TryChick6 months ago

You can still use the 3.3V ProMinis- just connect the power out from the regulator to the RAW input. I do this all the time since I run servos with a ProMini from single power source. I'll get you a wiring diagram asap.

TryChick Honus6 months ago

Cool. Thanks Honus.

Honus (author)  TryChick6 months ago

Here you go. Just let me know if this doesn't make sense!

LEDdiagram.jpg
TryChick Honus6 months ago

Thanks Honus. You are awesome! It totally makes sense.

TryChick TryChick6 months ago

Thanks to you I got the sensor, G4 light, and pro mini all working off that little 12V A23 battery. Thank you! Thank you! I had issues with the board not wanting to talk to my laptop to upload my sketch, and realized it was the cable of all things. The first 2 I tried wouldn't allow an upload, the third and 4th ones did. Did my first through-hole soldering to get wires hooked up.

DSC_8667.jpegDSC_8666.jpeg
Honus (author)  TryChick6 months ago

Awesome! So happy you got it to work! :)

Stefan-Xp9 months ago

Wow awesome Instructable! very nice Project!

Do you have a Video of it working in final state? :-)

vlg Stefan

Honus (author)  Stefan-Xp9 months ago

Thanks- glad you like it!

Video of what in it's final state?

Stefan-Xp Honus9 months ago

I meant the Predator Gun and Helmet with painting and Costume ;)

Honus (author)  Stefan-Xp9 months ago
Stefan-Xp Honus9 months ago

Cool! Thank you!

bitbyte691 year ago
Wondering if there is another place to buy your PCB?
Honus (author)  bitbyte691 year ago
You can upload the board files to several different PCB manufacturers and have them made. I haven't made any more of them as I'm going to make a simpler version of the board- I've found I rarely use the rechargeable LiPo and I'd like it to be a bit smaller to make it easier to fit in my projects.
TryChick Honus10 months ago
Honus,
If you aren't using the LiPos any more, what are you using?
Honus (author)  TryChick10 months ago
I've been using NiMh cells to power everything. Much more durable inside costumes. The biggest problem with using LiPo cells (especially when using multiple cells, like 2s packs) is regulating them in regards to low voltage cutoff since RC packs don't usually have any type of protection circuitry. There are also severe shipping restrictions on LiPo packs so if you have to ship a costume somewhere it's a real pain.

Unless you have a specific application where you need the energy density of LiPo cells due to weight and/or space restrictions they're just not worth the hassle in my opinion.
Raphango1 year ago
Great!
Favorited!
StrangeDos1 year ago
Thanks for this great instructable!

I'm planning a very similar thing as the Predator shoulder cannon and have one question:

I'm not much of a Wii gamer so I don't know exactly how a nunchuck behaves. But wouldn't the motion sensor still also be triggered when you move and walk around and not only when you turn your head? How did you make the cannon only follow your heads movement no matter where your whole body moves and turns to?
Honus (author)  StrangeDos1 year ago
Thanks- glad you like it!

The sensor from the nunchuck is an accelerometer and it's mounted in the helmet so it only senses when the helmet moves (with respect to gravity.) It only senses when the helmet tilts ( X and Y axis ) so you can walk around all you want without it being affecting. Also have a look at the FAQ section- I explain a bit more there.
I looked at the FAQ first, but didn't understand it all. My first idea before reading your instructable was actually using two gyros (one on the head and one in the cannons base) like you described but that seemed very complicated to me. I think I'll try it with your method and experiment a bit :).

I don't want to use a Nunchuk since there are some affordable accelerometer modules out there like this one:
http://www.ebay.de/itm/ADXL345-3-axis-Digital-Tilt-Sensors-Acceleration-Module-For-Arduino-/181185887400?pt=Bauteile&hash=item2a2f853ca8

Or would it be advisable to get one with a gyro like this?
http://www.ebay.de/itm/MPU-6050-3-Axis-Gyro-Gyroscope-Accelerometer-Sensor-Module-for-Arduino-/181018466904?pt=Bauteile&hash=item2a258a9a58
Honus (author)  StrangeDos1 year ago
Pretty much any of the Analog Devices ADXL accelerometers would work. I really don't see the need for a gyro in this application but if you want to incorporate one to try and improve the rotation performance then I say go for it! :)
Snarkticon1 year ago
What would it take to adapt this setup to be used in your Horus helmet rig? I just ordered an arduino board to get started and would love to be able to track my own head movements to the bird's head.
Honus (author)  Snarkticon1 year ago
I've had a few people ask about this. The problem is that you can't really move your head that much while wearing the Horus helmet. The great bit with the Horus helmet is that your head stays still and ONLY the bird head moves. The lower part of the Horus helmet really does not move- the movie helmets only had a few degrees of rotation between the lower part of the helmet and the neck collar.
hi um i was wondering about animatronics and what i would need to go to college for in order to buld,design,and program animatronics and i noticed what you made was cool. so do you have any tips on what schools to go to or what programs to take?
Honus (author)  MechAtronicsMan1 year ago
I would look at mechanical engineering, robotics, 3D design/CAD, electronics and classes that involve physical computing. Animatronics covers a wide variety of disciplines- molding, casting, fabrication, mechanics, hydraulics, pneumatics, electronics, programming, etc. There's a lot of problem solving that involves thinking about how you want things to move and then making mechanisms that fit within a limited volume.

There are classes and workshops for Arduino to get your feet wet in the electronics area and Stan Winston School has videos you can watch that cover all aspects of creature fabrication. They specifically have a couple of videos by Rick Lazzarini of The Character Shop that covers radio control animatronics. Check it out here- http://www.stanwinstonschool.com

Rick Lazzarini also teaches people here- http://www.animatronicsinstitute.com/

If you have any other questions just let me know!
Thanks so much...all of this makes alot of sense...I know what I want but no idea how to get there and have never done anything like this before. Sadly I have not even found anything prebuilt out there that does what I want either (my 2nd resort is always to cannablize anything premade).
I think it would be amazing if the eyes lit up when the sound effect when off...you are going to have to email me or else this post will get very long, but a list of parts would be a fantastic start. As far as sounds I would love a Wolf howl and growl/snarl too but I may be well overstepping my novice skills
Honus (author)  spyderskiss1 year ago
It's definitely possible to do everything you want. :) just message me your email and I'll help you put it together.
Email me at spyderskiss@gmail.com
I found an online dealer who had the led lights prewired to 9voltr cap with switch so I have them but will still need help on the sound and synching the eyes up to the sound. I am very tempted to just order an animated halloween prop that seems to have most of what I want..but would need to disassemble the whole thing and cannabalized the animatronics. (lunging cemetary dog prop)
email me anytime with the list @ spyderskiss@gmail.com.
Thanks again for the help. I can't wait ti get started.
That would be so great. Any suggestions on where I could pick up the parts I would need? Then if you can show me how to wire it up I would be so grateful. I am just totally lost when it comes to this type of thing.
Honus (author)  spyderskiss1 year ago
Adafruit is one of my favorite companies- they have Arduinos, battery holders, LEDs, etc. I can definitely help you wire it up. :)
If I get a chance in the next day or two I'll make a parts list for you- basically you want an Arduino Uno, Wave Shield, 9V battery/holder, a couple LEDs and a couple fingertip switches to activate your sounds.

What I do is write a list of what I want my costume to do and then make a plan from there. So How many sounds do you want? Do you want the eyes to light up with the sound or independent of the sound? That kind of thing. Make sense?
i really want to make my werewolf costume either growl or howl this year but i am really unsure how to do any of this> i did thought i could simply get some little led lights to put behind the eyes to make the glow but again pure beginner>
Honus (author)  spyderskiss1 year ago
That's pretty easy to do. You can use a WaveShield from Adafruit for the sound. Use a fingertip button to activate it. You can even have multiple sounds. Putting LEDs in the eyes is easy- I can show you to wire it all up.
okay. I know nothing about boards but I would love to have one with sound and simply to light up my costumes eyes. Is this really idiot and budget friendly to do? I could really use some advice from other costumers.
1-40 of 105Next »