Arduino controlled animatronic wooden head (reading lamp) usnig arduino

This head is a reading lamp which can be adjusted for direction of lighting, and dimmed as required.

This Instructable combines Arduino programming, some simple electronics, carving with hand and power tools, mechanical control and a bit of woodwork. Apart from the Arduino and a few components it is mostly made from reclaimed materials.

I am rather pleased with it.

What’s in this instructable

I have included the main circuit and controlling Arduino programme (the sketch), and issues that arose, but I have also tried as much detail of the other (physical) making processes involved, so hopefully some of that stuff may be useful if you are building something in a  similar way.

rduino controlled animatronic wooden head

This project includes:

  • the Arduino details, such as type of board, file type, the full Arduino sketch that controls the head, etc., and acknowledgement of included code such as the servo.h library.
  • how the eyeballs and sockets were developed using prototypes, their construction from roll-on deodorants and the mechanism that controls them
  • how the wooden head was developed using crude rapid-prototyping in polystyrene laminate sheets and how they were then used as templates to transfer the 3-d design to MDF boards and create the final casing
  • the carving methods using hand and domestic power tools
  • some discussion of the use of domestic materials such as garden wire and recycled objects to save on costs
  • testing various LEDs for eyeball lamps and overcoming the power limitations of Arduino outputs using a simple transistor amplifier circuit
  • more detailed discussion of the Arduino code and how it works to manipulate and translate analog inputs to the positioning servos and eyeball lamps
  • details of the construction of the wooden base unit and controls, some simple boxmaking and woodturning without a lathe
  • how a plastic power supply was converted into a wooden supply
  • handy tips that might be worth considering in similar projects

There is also a lot of further information about this and other things on my blog: “Making weird stuff

Step 1: Arduino topics covered in this Instructable (inc. the Arduino Sketch)

I have tried to include the nitty-gritty issues that arose in practice. This project addressed two main Arduino challenges:

  • Servo control – how to use Arduino scripts to convert a physical input into something that will mechanically control the position of a physical object in 2 dimensions (eyeballs!)
  • A simple lamp circuit – how to get Arduino to convert the signal from an input and make it turn a light on and adjust its brightness (dimming)

The Arduino community is immense (both in size and in helpfulness!). This project acknowledges all the people that give to it.

The servo scripting is based upon ‘Servo.h – interrupt-driven Servo library for Arduino using 16 bit timers- Version 2’
by Michael Margolis.  Respect!

http://code.google.com/p/arduino/source/browse/trunk/libraries/Servo/Servo.h?r=1088

The complete Arduino sketch is included here for reference. It went through 10 versions to get to this.
There is nothing very sophisticated. The script comments explain what it’s doing.

In later steps in this Instructable, I have added extra  expanded comments about the code within the context of specific steps (e.g. for the servo controls for the eyeballs)

This is an “.ino” sketch. This is a later Arduino format. It started out as a “.pde”

/*
Lamp head  – arduino sketch to control a remote control reading lamp head
Andrew Lewis January 2012
This code is in the public domain.
The servo scripting is based upon Servo.h – Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 by Michael Margolis.  Respect!

// http://code.google.com/p/arduino/source/browse/trunk/libraries/Servo/Servo.h?r=1088

Version 10
This version uses three potentiometers (pots) as inputs wired across the voltage rails (varying from 0 to 5V).
The variable output voltage of each seperately controlling 2 servos and 2 LEDs (operating as a pair)
The voltage is read by the arduino by 3 analog inputs (1 per pot)
The outputs from the Arduino to the servos are from digital pins, which use pulse modulation to control the voltage output.
The power supply is a standard 5V, 2A unit. It needs to have this amount of current to power the servos and high-power LEDs
*/

// @@@@@@@ DEFINE LAMPS @@@@@@@

// set Lamp pin numbers
const int lampPin = 5; // declares the ANALOG INPUT pin number for signal – IN
const int ledPinEyes =  3;      // the number of the LED OUTPUT pin for the eyeball LEDs – OUT
int valLamp=0; // variable to read analog input from switch to set off lights

// @@@@@@@ END LAMPS @@@@@@@

// @@@@@@@ DEFINE SERVOS @@@@@@@

#include <Servo.h> // includes standard arduino servo class
int delay_val = 5;  // assigns the servo increment lag (delay between applying values) for both servos

// @@@@ SERVO 1 @@@@
Servo myservo;  // create servo object to control a servo
const int potPin1 = 0;  // declares which analog pin is used to connect the analogue variable voltage output from potentiometer 1 (controls servo 1)
int valPot1;    // variable to read the value from the analog pin for servo 1

// @@@@ END SERVO 1 @@@@

// @@@@ SERVO 2 @@@@
Servo myservo2; // create second servo object to control a second servo
const int potPin2 = 1;  // declares which analog pin is used to connect the analogue variable voltage output from potentiometer 2 (controls servo 2)
int valPot2;    // variable to read the value from the analog pin for servo 2
// @@@@ END SERVO 1 @@@@

// @@@@@@@ SERVOS @@@@@@@
void setup() {
//pinMode (lampPin,INPUT);  // sets up digital pin as an input for ON/OFF LED input signal (for eyes)

pinMode (ledPinEyes, OUTPUT);// this is the output that turns the lamps on or off

// attach servos
myservo.attach(5);  // attaches the servo on pin 5 to the servo object
myservo2.attach(9); // attaches second servo to pin 9 to second servo object
}

void loop(){
lampCheck();// check lamp INPUT and adjust brightness
servoCheck(); // check for servo inputs and adjust position accordingly
}

void servoCheck() {
// servo controls @@@@@@@@@@@@@@@@@@@@@

// Servo 1 ————-
valPot1 = analogRead(potPin1);            // reads the value of the potentiometer (value between 0 and 1023)

//  digitalWrite (ledPinJoystick,HIGH);

valPot1 = map(valPot1, 50, 1000, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
myservo.write(valPot1);                  // sets the servo position according to the scaled value
// delay(delay_val);

// ———— servo 1 end
// servo 2 ————————
valPot2 = analogRead(potPin2);            // reads the value of the potentiometer (value between 0 and 1023)

// digitalWrite (ledPinJoystick,HIGH);
valPot2 = map(valPot2, 50, 1000, 179, 0);     // scale it to use it with the servo (value between 0 and 180)
myservo2.write(valPot2);               // sets the servo position according to the scaled value
// delay(delay_val);
// ———— servo 2 end
// end servo controls  @@@@@@@@@@@@@@@@@@@@@@ */
}
// lamp functions  @@@@@@@@@@@@@@@@@@@@@@ */
void lampCheck() {
valLamp=analogRead(lampPin);
valLamp = map(valLamp, 20, 1023, 0, 255);     // scale it to use it with the servo (value between 0 and 180)
valLamp = constrain (valLamp, 0,255);
analogWrite (ledPinEyes,valLamp);
}

Step 6: Arduino code for controlling the eyeballs using variable input voltages

In this step, the Arduino code and original code comments from the sketch are shown in blue. Extra comments added in this Instructable are in bold.

To direct the lamp beam, the eyeballs needed to be controllable. When the Arduino code is being run, the in-built ‘loop ()’ function simply calls a custom function called ‘servoCheck()’ repeatedly.

This is the line that is calling the servo checking function servoCheck()
servoCheck()  // check for servo inputs and adjust position accordingly

servoCheck in turn calls other functions that interact with the code in a quite complex code library. The good news is that you don’t need to know how that works at all!

This is where the beauty of Arduino emerges.  Because it is open source, there is always some generous clever person out there who has solved most of the tricky stuff. The servo controls used in this project are all based on an external library “servo.h”, by Michael Margolis. Hats off to Michael!

His code library is available here:

http://code.google.com/p/arduino/source/browse/trunk/libraries/Servo/Servo.h?r=1088


Within the sketch, there is initialisation code to include the servo library, declare variables, define which pins are in use etc., and functions that are called within servoCheck() to execute the code that repositions the servos.

The following #include line is the biggy.  It brings in the clever servo code:

#include // includes standard arduino servo class (the library)

The next line is defining a delay (5 milliseconds) so the servo is not being readjusted too often. With no delay, the servos are being readjusted constantly, and this may lead to burn-out. If the delay is too long though, the servos become jerky and slow to respond.

int delay_val = 5;  // assigns the servo increment lag (delay between applying values) for both servos

The servo control is based on analog input signals in the form of variable input voltages, which the Arduino converts to digital values (in other words numbers!) and then the code below is used to manipulate these numbers and create digital outputs to reposition the servos when the inputs are varied. The code in the servo.h library does all the grunt work. The code you need to write is really sending very simple data values to functions from the library to make it all happen.

The input voltages were created by using simple variable resistors (potentiometers), one for each servo. Potentiometers (pots) are easy to recycle from old electrical kit, such as old radios.  The value of the resistor is not especially important. Typically they are 0-10k Ohms. For each pot, the two supply poles are connected to ground (earth) and 5V respectively and the signal output is connected to an analog pin of the Arduino.

For the circuit diagram see step 10. It is very simple.

This bit declares the first servo…

// @@@@ SERVO 1 @@@@
Servo myservo;  // create servo object to control a servo
const int potPin1 = 0;  // declares which analog pin is used to connect the analogue variable voltage output from potentiometer 1 (controls servo 1)
int valPot1;    // variable to read the value from the analog pin for servo 1

// @@@@ END SERVO 1 @@@@

This bit declares the second servo…

// @@@@ SERVO 2 @@@@
Servo myservo2; // create second servo object to control a second servo
const int potPin2 = 1;  // declares which analog pin is used to connect the analogue variable voltage output from potentiometer 2 (controls servo 2)
int valPot2;    // variable to read the value from the analog pin for servo 2
// @@@@ END SERVO 2 @@@@

// @@@@@@@ SERVOS @@@@@@@

void setup() {
Arduino controlled anima
Once the servos (myservo, myservo2) have been declared, the Arduino pin connections are defined:

// attach servos
myservo.attach(5);  // attaches the servo on pin 5 to the servo object
myservo2.attach(9); // attaches second servo to pin 9 to second servo object
}

Once the servos have been defined, the ‘servoCheck()’ function was defined. This is called in the Arduino’s standard function ‘Loop ()’ to repeatedly check for inputs and convert these to outputs that control the servos and translate this to eyeball movement.

void servoCheck() {
// servo controls @@@@@@@@@@@@@@@@@@@@@

// Servo 1 ————-
valPot1 = analogRead(potPin1);            // reads the value of the potentiometer (value between 0 and 1023)

The variable valPot1 is taking the input signal from one of the potentiomaters.

The analogRead() command is used for this. It tells the Arduino to convert the raw analog input voltage (within the range 0 to 5 volts) into a digital value between 0 and 1023.

The servo code needs input values between  0 and 179. It will use these values  to set its position. an input of 0 positions the servo spindle at -90 degrees and 179 will set it at 90 degrees .

The number ranges (0 – 1023 and 0-179) need to be scaled. This is done using the Arduino map () function. This takes the digital values (0 to 1023) delivered by the analogRead() function and scales them to a number between 0 an 179.

valPot1 = map(valPot1, 50, 1000, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
myservo.write(valPot1);                  // sets the servo position according to the scaled value
// delay(delay_val);

// ———— servo 1 end

This is the same for the second servo

// servo 2 ————————

valPot2 = analogRead(potPin2);            // reads the value of the potentiometer (value between 0 and 1023)

// digitalWrite (ledPinJoystick,HIGH);
valPot2 = map(valPot2, 50, 1000, 179, 0);     // scale it to use it with the servo (value between 0 and 180)
myservo2.write(valPot2);               // sets the servo position according to the scaled value
// delay(delay_val);
// ———— servo 2 end
// end servo controls  @@@@@@@@@@@@@@@@@@@@@@ */
}

 

For more detail: Arduino controlled animatronic wooden head (reading lamp)


About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top