Arduino-controlled Dual Axis Solar Tracker





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





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








    • Pocket-Sized Contest

      Pocket-Sized Contest
    • Pro Tips Challenge

      Pro Tips Challenge
    • Paper Contest 2018

      Paper Contest 2018

    We have a be nice policy.
    Please be positive and constructive.




    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!

    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

    Nicely done! Simple but effective.

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


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

    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.