Introduction: PUPPET CONTROLLER
Or, Pacman - three ways.
This Instructable includes:
- Using an adjustable resistor as input to the Arduino Micro-controller
- Controlling two servo motors from the Arduino
-Controlling animation on the computer from the Arduino
Here are the basic steps:
- Servo control with Arduino and potentiometer
- Replace potentiometer with a flexible sensor
- Create animation on the computer screen
- Setup communication between the computer and Arduino
- Mount everything in a usable way and test it out!
Here is a good book for learning arduino:
Programming Arduino Getting Started with Sketches
Here is an arduino starter kit on amazon:
Starter Kit for Newsite Uno R3 - Bundle of 6 Items: Newsite Uno R3, Breadboard, Holder, Jumper Wires, USB Cable and 9V Battery Connector
There are videos, photos, and code along the way.
Step 1: Servo Code for Arduino
-two servos
-opposite angles
-Pot input
////////// Arduino Code ///////////////
//This is from an example inluded with Arduino IDE download.
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott
//MPC - added serial output 'n stuff
/*
Here is the wiring:
Wiring -
|------Arduino Gnd
Encoder |------Analog 0
|------Arduino 5V
| Yellow ------ Digi 9 (PWM)
Top servo | Red -----------5V
| Brown -------Gnd
| Yellow ------ Digi 10 (PWM)
Bottom servo | Red -----------5V
| Brown ------
*/
#include < Servo.h >
Servo myservo; // create servo object to control a servo
Servo otherServo ;
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
int valComp;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
otherServo.attach(10);
Serial.begin(9600);
}
void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
valComp = analogRead(potpin);
Serial.println(val);
val = map(val, 0, 1023, 90, 179); // scale it to use it with the servo (value between 0 and 180)
valComp = map(valComp, 1023, 0, 0, 90);
myservo.write(val); // sets the servo position according to the scaled value
delay(15);
otherServo.write(valComp);
delay(25); // waits for the servo to get there
}
Step 2: Add a Flex Sensor
-Adjust Analog input values so everything works right with the flex sensor. It is okay to guess a little
-Here's the updated code
////////// Arduino Code ///////////////
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott
//MPC - added serial output 'n stuff
// With flex sensor
// -Tweak Val to Angle Map
/*
Here is the wiring:
Wiring -
Flex Sensor |------Arduino Gnd
Flex Sensor |------Analog 0
100K |------Analog 0
100K |------Arduino 5V
| Yellow ------ Digi 9 (PWM)
Top servo | Red -----------5V
| Brown -------Gnd
| Yellow ------ Digi 10 (PWM)
Bottom servo | Red -----------5V
| Brown ------
*/
#include
Servo myservo; // create servo object to control a servo
Servo otherServo ;
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
int valComp;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
otherServo.attach(10);
Serial.begin(9600);
}
void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
Serial.println(val);
valComp = analogRead(potpin);
Serial.println(val);
val = map(val, 40, 350, 90, 179); // scale it to use it with the servo (value between 0 and 180)
valComp = map(valComp, 350, 40, 0, 90); //other servo does oposite
myservo.write(val); // sets the servo position according to the scaled value
delay(15);
otherServo.write(valComp);
delay(25); // waits for the servo to get there
}
Step 3: Mouth on Computer Screen
This uses Processing (from www.processing.org)
//PROCESSING CODE
//pacman moouth opens/close with X input from mouse
float x = 0;
float val = 0;
void setup(){
size(200,200);
background(100);
smooth();
}
void draw(){
background(100); //clear last image
val = mouseX;
x = map(val,0,200,0.01,0.3); //translate values input to useful values
println(x);
arc(100,100,50,50,(x)*PI,PI+(1-x)*PI); //draw packman, using radians... p21
}
Step 4: Hook 'em Together
We can do this by using the serial output from the Arduino as the input to the processing code.
Now we have two peices of code. The Arduino code reads the flex center, makes the readings into useful numbers and sends the values to the serial port.
The Processing code will read the values from the serial port and use the info to draw on the screen.
Here is a video clip:
[embeded video]
Here is the code:
//PROCESSING CODE
//pacman moouth opens/close with X input from arduino output (flex sensor)
import processing.serial.*;
Serial port;
float x = 0;
float val = 0;
void setup(){
size(400,400);
background(100);
smooth();
println(Serial.list());
String arduinoPort = Serial.list()[1];
port =new Serial(this, arduinoPort, 9600);
}
void draw(){
if (port.available() > 0) {
val = port.read();
print(val);
//val = mouseX;
print("-----");
x = map(val,0,150,0.01,0.5); //translate values input to useful values/println(x);
println(x);
}
background(100); //clear last image
arc(200,200,100,100,(x)*PI,PI+(1-x)*PI); //draw packman, using radians... p21
}
////////// Arduino Code ///////////////
//This is from an example inluded with Arduino IDE download.
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott
//MPC - added serial output 'n stuff
//Here is the wiring:
//
//Wiring -
//|------Arduino Gnd
//Encoder |------Analog 0
//|------Arduino 5V
//
//| Yellow ------ Digi 9 (PWM)
//Top servo | Red -----------5V
//| Brown -------Gnd
//
//| Yellow ------ Digi 10 (PWM)
//Bottom servo | Red -----------5V
//| Brown ------
#include
Servo myservo; // create servo object to control a servo
Servo otherServo ;
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
int valComp;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
otherServo.attach(10);
Serial.begin(9600);
}
void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
//Serial.print(val);
//Serial.print("---");
val = map(val, 0,1023, 0,255);
valComp = val;
//Serial.println(val);
Serial.print(val,BYTE);
delay(10);
val = map(val, 10, 100, 90, 179); // scale it to use it with the servo (value between 0 and 180)
valComp = map(valComp, 100, 10, 0, 90);
myservo.write(val); // sets the servo position according to the scaled value
delay(10);
otherServo.write(valComp);
delay(10); // waits for the servo to get there
}
Step 5: Make It Like a Puppet... Sort Of
Here are the basic steps:
Hand puppet (big one):
- Cut a circle out of cardboard.
- Slice the circle down the middle
- Make a hinge to hold onto (folded piece of cardboard)
- Glue the hinge to the half circles
- Attach flex sensor to hinge with double sided foam tape
- Cut and glue some loops for your fingers
- Wire up the flex sensor (same as before, it is just stuck to something now)
- Cut a smaller circle
- Cut it in half
- Glue the servos together
- Glue the half circles to the servo arm
Step 6: A Working Thing!
- Now that the flex sensor is tapped to the hinge, it is always a little flexed so the impedance is lower. I changed the resistor to 10K.
- The mapping from sensor input to servo angle needed to be adjusted a bit.
- I also flipped around the pacman animation in processing and made it bigger for the photos.
Video:
This shows the back a little
Code with all the peices working nicely:
note: using 10K pullup resistor
////////// Arduino Code ///////////////
//This is from an example inluded with Arduino IDE download.
// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott
//MPC - added serial output 'n stuff
/*
Here is the wiring:
Wiring -
|------Arduino Gnd
Encoder |------Analog 0
|------Arduino 5V
| Yellow ------ Digi 9 (PWM)
Top servo | Red -----------5V
| Brown -------Gnd
| Yellow ------ Digi 10 (PWM)
Bottom servo | Red -----------5V
| Brown ------
*/
#include
Servo myservo; // create servo object to control a servo
Servo otherServo ;
int potpin = 0; // analog pin used to connect the potentiometer
int val=0; // variable to read the value from the analog pin
int valComp;
int valOld=100;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
otherServo.attach(10);
Serial.begin(9600);
}
void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
//Serial.print(val);
//Serial.print("---");
val = map(val, 0,1023, 0,255);
if(val > 175){ //wide open
val = 185;
}
if(val <80){ //closed
val = 80;
}
if((abs(val-valOld))>7){ //filter out the jitter
valComp = val;
//Serial.println(val);//DEBUG
Serial.print(val,BYTE);//USE
delay(10);
val = map(val, 80, 255, 90, 179); // scale it to use it with the servo (value between 0 and 180)
valComp = map(valComp, 255, 80, 0, 90);
myservo.write(val); // sets the servo position according to the scaled value
delay(10);
otherServo.write(valComp);
delay(10); // waits for the servo to get there
valOld = val;
}
}
/*
//PROCESSING CODE
//pacman moouth opens/close with X input from arduino output (flex sensor)
import processing.serial.*;
Serial port;
float x = 0;
float val = 0;
int frame = 1000;
float easing = 0.5;
float xOld;
void setup(){
size(frame,frame);
background(100);
smooth();
println(Serial.list());
String arduinoPort = Serial.list()[1];
port =new Serial(this, arduinoPort, 9600);
}
void draw(){
if (port.available() > 0) {
val = port.read();
print(val);
//val = mouseX;
print("-----");
x = map(val,80,255,0.01,0.6); //translate values input to useful values/println(x);
println(x);
}
background(100); //clear last image
rotate(PI);
translate(-frame,-frame);
float targetX = x;
x+=(targetX - x)*easing;
arc(frame/2,frame/2,frame/2,frame/2,(x)*PI,PI+(1-x)*PI); //draw packman, using radians... p21
//x= xOld;
}
*/
Step 7: What to Do Next?
I let the girls play with it... they got tired of it quickly.
So what else could we do?
We could:
- Stop and do something else (look at all these contests!)
- Decorate the puppet and sow the sensors to a glove or sock
- Network the puppet (ie Puppet-Net)
- Send values over the internet to another computer with the same setup
- Show animation on the other computer
- Output motion to an arduino with servos on the other computer
-Network goal -
- Puppet controller at each location
- Puppet physical output at each location
- Animations of both virtual puppets shown an screen
- Add sound
- Stop and do something else (look at all these contests!)