Google+ Followers

Wednesday, January 29, 2014

44. Robotics - A Light Follower with Two Servos

So we're still on the theme of motors, and I still haven't revealed why, only to do a bit on DC motors, and now, servos.  I thought I would re-create the Arduino Solar Tracker by Geo Bruce.  See http://www.instructables.com/id/Arduino-Solar-Tracker/ - it's a great little project, and quite ambitious, but I wanted to make something with servos.

I was so excited about getting it working, that I just had to do a blog post, in case something blew up before I had a chance to document it.  I still have a lot of tweaking and adjusting to do to get it to be just right, but it works fine - I just have to make some of the connections more secure, and play with the trimmer potentiometers which adjust the sensitivity.  I'll see how it gets on at night before doing too much.

Here is my version:
 
The white object on the left is the 'eye', mounted on the black pan-and-tilt bracket.  The trusty Arduino is in the middle, and the mini breadboard is on the right, bearing four 10kΩ  resistors, and 2 (blue) adjustable trimmer 10kΩ potentiometers.  Actually, I later changed the 10kΩ resistors to 1kΩ resistors to improve sensitivity.

 
Here's a closer look at the Arduino and mini breadboard - you can see the 2 trimmers and the 4 resistors.
Here's a closer look at the 'eye' mounted on the pan-and-tilt bracket.  The blue object just below is the 'vertical' servo - the one that makes the assembly tilt.  

You can see into the 'eye' here - there are 4 segments in the white cylindrical surround, formed by two interlocking pieces of black plastic.  You can just about see the 4 light dependent resistors (LDRs), one in each segment.  The idea is that they're somewhat isolated from one another, the incident light being seen brighter by some of them than others.  Their signals sent back to the Arduino then tell the microprocessor how to move the servos until the 'eye' is staring straight at the light, that is, each LDR is seeing the same amount of light.

You can see the blue 'horizontal' servo behind.  This makes the assembly, including the other servo, pan (rotate horizontally).  The two servos are identical.  Here's what it looks like from a short distance:




The base is a dummy CD and the upright post hot-glued to it is a medical supplies tube, into which the horizontal servo fits snugly.  The 'eye' was made from a drying capsule from the inside of a medical supplies tube lid, the interior separators made from a piece of black plastic which I cut from a highlighter pen. A 2 cm diameter piece of clear plastic forms a window which also retains the black plastic separators.

And here it is - working!!!
video
I have it on continuously, on a very sensitive setting, and it's constantly moving and twitching, reacting to the changing light conditions.  It's like a living thing, and seems to have a character all on it's own!  Surely this is truly a robot?

I had to get a few extra parts to make this project - 2 servos, some light dependant resistors, and a pan-and-tilt bracket.  I also had to design an 'eye' for the system.

The servos are Hextronik HXT900 9g/ 1.6kg/0.12 Micro Servos which I got delivered from eBay for £7.16.  They weigh about 9g each, the torque is 1.6 kg-cm and the speed is 0.12 seconds per 60 degrees, all at 4.8V.  

The LDRs were £3.60 for 10 from CPC, one of which I measured as 120 kΩ in the dark and 3kΩ  with bright light shining on it.  The 10kΩ resistors (currently 1kΩ) in series are needed to limit the current drawn by the LDRs.

The pan-and-tilt bracket came from RelChron for £5.60 plus £3.00 p&p.  Here it is assembled, with two micro servos very similar to mine, 'horizontal' (pan) at the bottom, and 'vertical' (tilt) at the top:
Here's the circuit:

and here's the code:
1:  #include <Servo.h> // include Servo library   
2:  Servo horizontal; // horizontal servo  
3:  int servoh = 90;   // stand horizontal servo  
4:  Servo vertical;  // vertical servo   
5:  int servov = 90;   // stand vertical servo  
6:  // LDR pin connections  
7:  // name = analogpin;  
8:  int ldrlt = 0; //LDR top left  
9:  int ldrrt = 1; //LDR top rigt  
10:  int ldrld = 2; //LDR down left  
11:  int ldrrd = 3; //ldr down rigt  
12:  void setup()  
13:  {  
14:   Serial.begin(9600);  
15:  // servo connections  
16:  // name.attacht(pin);  
17:   horizontal.attach(9);   
18:   vertical.attach(10);  
19:  }  
20:  void loop()   
21:  {  
22:   int lt = analogRead(ldrlt); // top left  
23:   int rt = analogRead(ldrrt); // top right  
24:   int ld = analogRead(ldrld); // down left  
25:   int rd = analogRead(ldrrd); // down rigt  
26:   int dtime = analogRead(4)/20; // read potentiometers   
27:   int tol = analogRead(5)/4;  
28:   int avt = (lt + rt) / 2; // average value top  
29:   int avd = (ld + rd) / 2; // average value down  
30:   int avl = (lt + ld) / 2; // average value left  
31:   int avr = (rt + rd) / 2; // average value right  
32:   int dvert = avt - avd; // check the diffirence of up and down  
33:   int dhoriz = avl - avr;// check the diffirence og left and rigt  
34:   if (-1*tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle  
35:   {  
36:   if (avt > avd)  
37:   {  
38:    servov = ++servov;  
39:     if (servov > 180)   
40:     {   
41:     servov = 180;  
42:     }  
43:   }  
44:   else if (avt < avd)  
45:   {  
46:    servov= --servov;  
47:    if (servov < 0)  
48:   {  
49:    servov = 0;  
50:   }  
51:   }  
52:   vertical.write(servov);  
53:   }  
54:   if (-1*tol > dhoriz || dhoriz > tol) // check if the diffirence is in the tolerance else change horizontal angle  
55:   {  
56:   if (avl > avr)  
57:   {  
58:    servoh = --servoh;  
59:    if (servoh < 0)  
60:    {  
61:    servoh = 0;  
62:    }  
63:   }  
64:   else if (avl < avr)  
65:   {  
66:    servoh = ++servoh;  
67:     if (servoh > 180)  
68:     {  
69:     servoh = 180;  
70:     }  
71:   }  
72:   else if (avl = avr)  
73:   {  
74:    // nothing  
75:   }  
76:   horizontal.write(servoh);  
77:   }  
78:    delay(dtime);   
79:  }  

This is the code and circuitry of Geo Bruce at the link given above.  A nice project Geo!





No comments:

Post a Comment