Tuesday, February 4, 2014

45. Improved Light Follower with Wide Field of View

I have made an improvement to the collimation system, which happens to be the same design that Geo Bruce had in his original instructables.com post at http://www.instructables.com/id/Arduino-Solar-Tracker/ !  My previous design of an 'eye' was restricting the field seen, and the tracking system was only making adjustments within a narrow field of view.  Geo's design exposes the light-dependent resistors (LDRs) to light from a much bigger solid angle, and therefore allows the tracker to 'watch' the light levels almost all around it.  (Strictly speaking, the field of view of the whole detection system is a solid angle of almost 2π steradians, [a hemisphere] so the field of view of each LDR is π/2 steradians).  So this makes the system more sensitive to light variations in its vicinity.

Here is what the collimation system looks like now:





I made the collimator's leaves from some cardboard and hot-glued it to a black plastic cap which was screwed onto the pan and tilt bracket.  

The system is now very sensitive - a result of this new collimator, replacing the 10kΩ resistors by 1kΩ resistors in series with the LDRs, and fine adjustment of the two trimmer potentiometers, 'delay' and 'tolerance'.

Here's a video of it working - watch how it follows the beam of the torch - even in a brightly daylight-lit room.  It reacts when I shadow it with my hand.  It even twitches when a tall truck passes by!  I'm watching it slowly pan across the sky as the time passes.  I'm looking forward to seeing it track the sun across the sky (if the sun ever comes out!).


I have also tidied up the software, and here's the code:
1:  // Originally written by Geo Bruce at:  
2:  // http://www.instructables.com/id/Arduino-Solar-Tracker/   
3:  // then slightly modified by S & S Feb 2014  
4:    
5:  #include <Servo.h>                    // include Servo library   
6:    
7:  Servo horizontal;                     // horizontal servo  
8:  int servoh = 90;                      // initialise the position of   
9:                                        // the horizontal servo  
10:    
11:  Servo vertical;                      // vertical servo   
12:  int servov = 90;                     // initialise the position of  
13:                                       // the vertical servo  
14:    
15:  int ldrlt = 0;                       // LDR left top = analog pin 0  
16:  int ldrrt = 1;                       // LDR right top = analog pin 1  
17:  int ldrlb = 2;                       // LDR left bottom = analog pin 2  
18:  int ldrrb = 3;                       // LDR left bottom = analog pin 3  
19:    
20:  void setup()  
21:  {  
22:   Serial.begin(9600);  
23:                                       // servo connections  
24:                                       // attach digital pins  
25:   horizontal.attach(9);   
26:   vertical.attach(10);  
27:  }  
28:    
29:  void loop()   
30:  {  
31:   int lt = analogRead(ldrlt);         // left top  
32:   int rt = analogRead(ldrrt);         // right top  
33:   int lb = analogRead(ldrlb);         // left bottom  
34:   int rb = analogRead(ldrrb);         // right bottom  
35:     
36:   int dtime = analogRead(4)/20;       // read delay potentiometer   
37:   int tol = analogRead(5)/4;          // read tolerance potentiometer  
38:     
39:   int avt = (lt + rt) / 2;            // average value top  
40:   int avd = (lb + rb) / 2;            // average value bottom  
41:   int avl = (lt + lb) / 2;            // average value left  
42:   int avr = (rt + rb) / 2;            // average value right  
43:    
44:   int dvert = avt - avd;              // difference between top and bottom  
45:   int dhoriz = avl - avr;             // difference between left and right  
46:      
47:   if (-1*tol > dvert || dvert > tol)  // check if the difference is within the  
48:                                       // tolerance else change the vertical angle  
49:   {  
50:   if (avt > avd)  
51:   {  
52:    servov = ++servov;  
53:     if (servov > 180)   
54:     {   
55:     servov = 180;  
56:     }  
57:   }  
58:   else if (avt < avd)  
59:   {  
60:    servov= --servov;  
61:    if (servov < 0)  
62:   {  
63:    servov = 0;  
64:   }  
65:   }  
66:   vertical.write(servov);  
67:   }  
68:     
69:   if (-1*tol > dhoriz || dhoriz > tol) // check if the difference is within the   
70:                                        // tolerance else change the horizontal angle  
71:   {  
72:   if (avl > avr)  
73:   {  
74:    servoh = --servoh;  
75:    if (servoh < 0)  
76:    {  
77:    servoh = 0;  
78:    }  
79:   }  
80:   else if (avl < avr)  
81:   {  
82:    servoh = ++servoh;  
83:     if (servoh > 180)  
84:     {  
85:     servoh = 180;  
86:     }  
87:   }  
88:   horizontal.write(servoh);  
89:   }  
90:    delay(dtime);   
91:  }  








No comments:

Post a Comment