Introduction: Arduino-controlled Dual Axis Solar Tracker
I had to build and program a solar tracker for my BTech project.
I got most parts laser cut out of wood from a drawing I made in Solidworks.
Step 1: Parts
You need:
4 x LDRs
4 x 1kOhm resistors
female pin connectors
chipboard screws
M6 bolts & washers
M8 bolts&washers
Arduino Mega 2560
Motor Control shield (for 2 servos)
1x6V battery if you want to drive it without cables
1 x 180° Servo
1 x 360° continuous rotation servo
Step 2: Step 1: Shaft
I turned a stepped shaft on the lathe where the bearing fits onto. This bearing then fits snugly into the laser-cut base of the compartment. On top of the shaft is the connecting union for the motor. It is fixed through the shaft with a bolt.
The shaft is pressed into a stainless steel shaft, so it looks like the tracker is sitting on a post.
Only for aesthetics really.
Step 3: Step 2: Box Assembly
As you can see, the box fits together nicely, with holes at the exact right place for mounting purposes.
I made two small shafts out of brass round bar, and drilled and tapped them for the side shafts. They both run through a cylindrical bearing in the side of the box.
I had a 180° servo for the vertical, and a 360° continuous rotation servo for the horizontal. The 360° servo gave me some trouble, and I have not streamlined it 100% yet. But it works.
Only one side is driven, and the other follows as it is attached to the other arm.
Step 4:
I got a perspex lid, so one can look into the compartment and see what's going on.
Step 5:
Here is another image of the inside
Step 6: The Sensors
The sensors are mounted in 4 Quadrants as seen on a few other projects.
Step 7: Circuit
Here is the circuit setup. The motor shield is of course stacked on top of the Mega. I left it off just for demo.
Step 8: TEST
Here is the result :-)
The image is the readings that are displayed in the Serial monitor
Step 9: Code
I used parts of Geo Bruce's code, and added a bunch of stuff to it.
#include //Library for Servo
#include //Library for Motor Sheld
// 180 horizontal MAX Servo horizontal; // Horizontal/Azimuth servo
int servoh = 90; // Make servo stationary
int servohLimitHigh = 92; int servohLimitLow = 88;
Servo vertical; // Vertical/Zenith servo
int servov = 45; // Make servo horizontal
int servovLimitHigh = 110; int servovLimitLow = 20;
// LDR pin connections //position = Analog pin
int ldrbl = 11; //Bottom Left
int ldrbr = 10; //Bottom Right
int ldrtl = 9; //Top Left
int ldrtr = 8; //Top Right
void setup() { Serial.begin(9600);
// servo connections
// name.attacht(digital pin);
horizontal.attach(9);
vertical.attach(10);
delay(1000);
}
void loop() { int bl = analogRead(ldrbl); // Bottom left
int br = analogRead(ldrbr); // Bottom Right
int tl = analogRead(ldrtl); // Top Left
int tr = analogRead(ldrtr); // Top Right
int percentb, percentt, percentl, percentr;
// int dtime = analogRead(4)/20; // read potentiometers
// int tol = analogRead(5)/4;
int dtime = 500; int tol = 10;
int avb = (bl + br) / 2; // average value bottom
int avt = (tl + tr) / 2; // average value top
int avl = (bl + tl) / 2; // average value left
int avr = (br + tr) / 2; // average value right
percentb = map(avb,0,1023,0,100); percentt = map(avt,0,1023,0,100); percentl = map(avl,0,1023,0,100); percentr = map(avr,0,1023,0,100);
int dvert = avt - avb; // check the diffirence of top and bottom
int dhoriz = avl - avr;// check the diffirence of left and rigt
Serial.print(percentt);
Serial.println(" percent t ");
Serial.print(percentb);
Serial.println(" percent b ");
Serial.print(percentl);
Serial.println(" percent l ");
Serial.print(percentr);
Serial.println(" percent r ");
Serial.print(dtime);
Serial.println(" delay time");
Serial.print(tol);
Serial.println(" tolerance ");
Serial.print(dhoriz);
Serial.println(" Difference Horizontal ");
Serial.print(dvert);
Serial.println(" Difference Vertical ");
if (-1*tol > dvert || dvert > tol) // check if there is a difference,within the tolerance, or else change vertical angle
{
if (avt > avb)
{
servov = ++servov;
if (servov > servovLimitHigh)
{
servov = servovLimitHigh;
}
}
else if (avt < avb)
{
servov= --servov;
if (servov < servovLimitLow)
{
servov = servovLimitLow;
}
}
vertical.write(servov);
}
if (-1*tol > dhoriz || dhoriz > tol) // check if there is a difference,within the tolerance, or else change horizontal angle
{
if (avl > avr)
{
servoh = (90-1);
if (servoh < servohLimitLow)
{
servoh = servohLimitLow;
}
}
else if (avl < avr)
{
servoh = (90+1);
if (servoh > servohLimitHigh)
{
servoh = servohLimitHigh;
}
}
else if (avl = avr)
{
// nothing
}
horizontal.write(servoh);
}
delay(dtime);
}