Simple Eye Movement Help

Hi there,

I'm an illustration student planning on making a very slightly animatronic silicone doll for my degree show. Now, I thought I had enough time to teach myself enough Arduino to accomplish what I set out to do, but it's now 17 days until hand ins and because of some technical and post-office related hitches with my moulding process I haven't got round to writing the program for the animatronics.

What I originally wanted to do was have a head up/down mechanism, eyes l/r, up/down and ears forward and back but I quickly realised this was unrealistic (and expensive) and I quickly reduced it down to the eyes simply moving left, right, up and down. Here was my hardware layout for the eye movement, based on one of WilletFX's designs.

I have made the rig and tested it with a servo sweep - it works well! It's just my basic, basic knowledge of arduino hardware means I am constantly terrified I might explode my servos because I didn't put in the right resistor or something. It takes me a lot of brain power to get my head around engineering and right now I'm focussing it all on getting my portfolio polished, blah blah...

I do however know how to connect up one servo, so I've reduced the movement yet again to just... left and right. (I got a strange mini breadboard with my starter kit and I'm not sure how it works :S) What I've come here to ask is if anyone would be willing to write a few short and simple lines of code to move the servo randomly (and slowly) to mimic eye movement. I can do the wiring for this one, messily but well enough for the exhibition.

If anyone wants to tackle two servos and try and help me set up the wiring I would be forever appreciative. I have a lot of electrical gubbins I bought for the project but no brain behind it really! I know this is a lot to ask because it would be so much simpler in real life but I learn quickly and I am willing and able to accept any advice or abuse you have for me!

I did write some code which was working well enough but it's on my laptop locked up in uni at the moment so I can't show it. It was a modified version of the sweep program, very basic and probably stupid.

Also, as an art student I would be more than happy to pay you in the form of what I do best, making art dolls... It's not much of an incentive but it's there if you want it. (You can see some on my website, magweno.com) I will also credit your incredibly helpful contribution at the degree show (with your consent of course).

Any help, any help at all, is incredibly appreciated.

-Mads

So what exactly do you want it to do - move imitating human eye movement?

If you can be a bit more detailed about what you want then the code is simple enough.

Yep exactly. I was going to code it so the servo moved a small amount and stayed there for a few seconds, moved to another random position for a second or two then move again, sort of basic REM. The idea is that the creature will be crouched at ground level looking up at the audience at the exhibition, so it would be good if it was almost looking from person to person. Of course it won't actually recognise that there's someone there but if luck strikes it might look straight at them which would cause a great reaction. :smiley:

I had planned for it to be on a loop with a mains power supply with an idea of having a random number generator in the code so it never did the same pattern of positions twice but I don't know how feasible that is, if it's simply a sequence of positions over and over again then that's fine too, so long as it's not immediately noticeable.

Sounds simple enough - random number generator should be easy enough too.

So what are the servo limits? is 0-180 min to max movement or is it going to break something if it goes to 0 or 180? (in either direction).

If it's on the floor does that mean that it wants to be looking up more than down? to look at people?

Yeah I had a rough code working well, I just don't have time to smooth out the kinks.

I might also need a little bit of help with the wiring.

Hmm I think it's less than 180, while the rods swivel with the ball-joints and the fishing swivels aide movement I think 0-180 might break them. I think when the ball-joint touches the edge of the servo is probably the limit, I couldn't tell you the specific numbers though (how helpful!) However on Monday if I have code to work with I'll set it up, take some videos and have a play with it all.

As for being on the ground if you're going to us both servos rather than just the L/R then keeping the eyes more up than down would be good, but if it's just one servo with L/R movement I'll make sure they're looking up when I fit them in the skull.

But you know anything's great, I really appreciate your help!

Here's some code I whipped up (and tested with some servos):

#include <Servo.h> //include servo library for servo control 
 
Servo horServo; //servo for left/right movement
Servo vertServo; //servo for up/down movement

byte randomhor; //define random horizontal position variable
byte randomvert; //define random vertical position variable
int randomdelay; //define random delay variable

#define HLEFTLIMIT 0 //define left limit on horizontal (left/right) servo
#define HRIGHTLIMIT 180 //define right limit on horizontal (left/right) servo

#define VTOPLIMIT 60 //define top limit on vertical (up/down) servo
#define VBOTLIMIT 180 //define bottom limit on horizontal (up/down) servo

 
void setup() 
{ 
  horServo.attach(4); //horizontal servo on pin 8
  vertServo.attach(5); //vertical servo on pin 9
  randomSeed(analogRead(0)); //Create some random values using an unconnected analog pin
} 
 
 
void loop() 
{ 
  randomhor = random(HLEFTLIMIT, HRIGHTLIMIT); //set limits
  randomvert = random(VTOPLIMIT, VBOTLIMIT); //set limits
  randomdelay = random(1000, 4000); //moves every 1 to 4 seconds
  
  horServo.write(randomhor); //write to the horizontal servo
  vertServo.write(randomvert); //write to the vertical servo
  delay(randomdelay); //delay a random amount of time (within values set above)
}

That code will make the servos move randomly with a random time interval (all within set limits).

You can define the limits and random delay time - have a fiddle to make it function how you want it to. You may have to reverse some values depending on how your servos are set up. You will need to change the limits so it doesn't try and break itself. Try them small to work out what does what then slowly increase them to close to the limits of your hardware.

You could do things like make the up/down eye movement on a longer random time so it moved less frequently up and down to left and right but this code will give you something at least.

I look forward to seeing what this creature looks like :smiley:

Wiring is easy - power wires from the servos connected together and to arduino 5V, ground wires connected together and to arduino GND and signal lines connected individually (in this case to 4 & 5).

Mowcius

Ahhh amazing, thank you so much! I'll test this on Monday and let you know how it goes/if I am stupid and have problems.

Here's a photo of the sculpt of the creature, he'll be cast out of silicone by the end of the week. Hopefully he'll have moving eyes too.

Out of curiosity for the mains power do I just set the AC adapter to the right voltage then plug it into the Arduino? Will it automatically run the uploaded program without having to be connected through USB?

Also connecting the two respective servo wires... I have this breadboard:

Does the power run vertically or horizontally? (Gosh I feel really silly asking this but I swear I've looked and can't find the info I need!)

Out of curiosity for the mains power do I just set the AC adapter to the right voltage then plug it into the Arduino? Will it automatically run the uploaded program without having to be connected through USB?

Yeah - if you have an adjustable supply, I'd suggest you set to it to 7V or close to that. The uploaded program is saved on your arduino so it will run whenever it has power - no need to connect it to a computer.

I'll test this on Monday and let you know how it goes/if I am stupid and have problems.

Well like I say, make the limit values close to 90 (middle of the servo's movement say 70 and 90) and test that - then see what happens - if you then make one of the limits larger (further off 90) then you will be able to see if the values need switching.
Then simply fiddle with the values until it acts as desired.

If I get bored before monday I might fiddle around with the code some more. :wink:

Does the power run vertically or horizontally? (Gosh I feel really silly asking this but I swear I've looked and can't find the info I need!)

The connections will run towards the middle from the outside.
You shouldn't need a breadboard though - its only two wires for the signals and two for the power (to each servo)

I had it set to 6V and nothing seemed to happen but it's probably the stupid uni plugs on the fritz again.

There's only one 5V input on the duemilanove though so won't I have to link the two power cables through the breadboard?

I had it set to 6V and nothing seemed to happen but it's probably the stupid uni plugs on the fritz again.

6V isn't high enough. If you're connecting it via the DC jack it needs to be ~7V or higher.

There's only one 5V input on the duemilanove though so won't I have to link the two power cables through the breadboard?

Well either that or use a soldering iron and connect two cables to one :slight_smile:

Now just cos I can and I realised I had some circle code sitting around - it now rolls its eyes on startup :stuck_out_tongue:
You could modify this so it rolls its eyes in the opposite direction/rolls them at random times etc...

//======================================
//Circle Math
//======================================
#include <math.h>

#define pi    3.14159265358979323846
#define twopi (2*pi)
float circleradius = 50; //50 each side - make no more any of your max limit values
float stepnumber = 360;
float stepangle;
//======================================


#include <Servo.h> //include servo library for servo control 
 
Servo horServo; //servo for left/right movement
Servo vertServo; //servo for up/down movement

byte randomhor; //define random horizontal position variable
byte randomvert; //define random vertical position variable
int randomdelay; //define random delay variable

#define HLEFTLIMIT 0 //define left limit on horizontal (left/right) servo
#define HRIGHTLIMIT 180 //define right limit on horizontal (left/right) servo

#define VTOPLIMIT 60 //define top limit on vertical (up/down) servo
#define VBOTLIMIT 180 //define bottom limit on horizontal (up/down) servo

 
void setup() 
{ 
  horServo.attach(4); //horizontal servo on pin 8
  vertServo.attach(5); //vertical servo on pin 9
  randomSeed(analogRead(0)); //Create some random values using an unconnected analog pin
  
  
  //=====================================================
  //Roll Eyes :D
  //=====================================================
  stepangle = twopi/stepnumber;
    for(int i = 0; i<stepnumber; i++){
    float angle = i*stepangle;
    float x = sin(angle)*circleradius;
    float y = cos(angle)*circleradius;
    
    x = map(x, 1-circleradius, circleradius, 0, 2*circleradius);
    y = map(y, 1-circleradius, circleradius, 0, 2*circleradius);
    
    horServo.write(x); //write to the horizontal servo
    vertServo.write(y); //write to the horizontal servo
    
    delay(10);
  }
  //=====================================================
} 
 
 
void loop() 
{ 
  randomhor = random(HLEFTLIMIT, HRIGHTLIMIT); //set limits
  randomvert = random(VTOPLIMIT, VBOTLIMIT); //set limits
  randomdelay = random(1000, 4000); //moves every 1 to 4 seconds
  
  horServo.write(randomhor); //write to the horizontal servo
  vertServo.write(randomvert); //write to the vertical servo
  delay(randomdelay); //delay a random amount of time (within values set above)
}

:smiley:

Sadly I don't have access to a soldering iron so breadboard it is for me. Well I could ask the boys up in product design but they're running around like headless chickens at the moment (their hand-ins are a week earlier than ours).

Haha I like that, not sure about it doing it during the exhibition but as a start up test that's great. Thank you again, I'll let you know how it goes tomorrow.

Right, I look forward to updates.

The below projects may be of interest.

http://www.lynxmotion.net/viewtopic.php?f=20&t=5948
http://www.lynxmotion.net/viewtopic.php?f=20&t=416&start=0

Thanks for the links, Zoomkat, they were very interesting!

Here's a video of one eye, as it says in the description I have set up the other eye and the rig is working. The code works perfectly, thank you so much. I tweaked the values a little because I didn't think there was enough movement but after a while and re-reading the brief I set myself I reduced the values again to make the movements smaller and slightly faster.

Thanks again for your help, I can reference you on the degree show website or on my plaque at the show, it's up to you, but if I do I'll need a full name. :slight_smile:

The code works perfectly, thank you so much. I tweaked the values a little because I didn't think there was enough movement

Well I did anticipate that you'd want to adjust the values to make it right. I can't watch the video at the moment but I'll watch it when I get home this evening.

Nice - just got round to watching the video - yeah seems to work pretty well :slight_smile:

My name's Rob Whitfield - mention me wherever you like - the code was simple enough to do, just happy to help.

Great, I'll put credit up on my website then which the tutors will see.

I got round to casting the final eyes on Tuesday and build the final rig yesterday, here's a video with movement which I'm happy with. I'll post again when they're in the Brownie at the degree show on the 21st.

Shouldn't that right hand eye have the servo horn connection one further across?

I'll post again when they're in the Brownie at the degree show on the 21st.

I'll no doubt have forgotten all about it by then :slight_smile:

Which connection, the one that attaches the horns together or the one that connects to the eye?
I moved the eye connection one over on the right before the video because it was slanting from the eye.

Ahh I see - yes that one. The right eye doesn't move quite as much as the left one with the connection in a different place.