Introduction: Arduino-controlled Dual Axis Solar Tracker

Picture of 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

Picture of 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

Picture of 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

Picture of 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:

Picture of

I got a perspex lid, so one can look into the compartment and see what's going on.

Step 5:

Picture of

Here is another image of the inside

Step 6: The Sensors

Picture of The Sensors

The sensors are mounted in 4 Quadrants as seen on a few other projects.

Step 7: Circuit

Picture of 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

Picture of 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);





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.println(" percent t ");


Serial.println(" percent b ");


Serial.println(" percent l ");


Serial.println(" percent r ");


Serial.println(" delay time");


Serial.println(" tolerance ");


Serial.println(" Difference Horizontal ");


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;





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







ZacWolf (author)2017-09-29

What size servos are you using? I've not worked much with servos and most of what I'm finding seem geared for toy usage. Would a 30kg servo position a 23lb panel ok? THANKS!

Victor EmmanuelS (author)2016-10-20

Amazing I made something similar although with transistors, logic gates and an h-bridge for the motors. I definitely have to grab an arduino kit. BTW I had a similar sensor design but i placed it in the middle of the panel

colinmcc (author)2016-10-18

Nicely done! Simple but effective.

BTW, A typo "This bearing then fits snuggly into the caser-cut base of the compartment."


BorisGerdes (author)colinmcc2016-10-19

Haha, my bad. Will correct it. Thanks for pointing out. No spell-check on instructables :-P

DIY Hacks and How Tos (author)2016-10-16

This is a great design. Tracking makes a solar panel a lot more efficient.

Thank you! I have put a lot of work into it. Should have started the instructable earlier with nice step-by-step pictures, but oh well. Maybe, when the project is done, I can redo it with nice instructions.

Yes, tracking gives 30-35% more production.

About This Instructable




Bio: I live in the desert country Namibia, in severe drought at the moment. There is not much to do other than drink beer :-P So ... More »
More by BorisGerdes:Arduino-controlled Dual Axis Solar tracker
Add instructable to: