Build a Dual Axis Solar Tracker Using Arduino

by ElectroScope Archive in Circuits > Arduino

24 Views, 0 Favorites, 0 Comments

Build a Dual Axis Solar Tracker Using Arduino

dual-axis-solar-tracker.jpg

My solar panel was just sitting there all day at one angle. Meanwhile the sun's moving across the entire sky. Seemed like a waste so I built this tracker that follows the sun in both directions.

The difference is pretty noticeable. I'm getting 30-40% more power compared to when it was fixed. Not a bad return for a weekend of tinkering.

How This Actually Works

Picture four light sensors arranged in a cross around your panel. Top, bottom, left, right. They're constantly checking which direction has the brightest light.

Arduino reads those sensors and does some quick math to figure out where the sun is. Then it moves two servos to point the panel that way. One servo handles horizontal rotation, the other handles vertical tilt.

When it gets dark the system just stops moving. No point tracking at night.

Supplies

Components-Of-Dual-Axis-Solar-Tracker.jpg

For the electronics:

  1. Arduino UNO (the controller brain)
  2. 4x LDR sensors, the 5mm ones work great
  3. 2x Micro servo motors
  4. 4x 10k ohm resistors
  5. A small solar panel (whatever size you want to experiment with)
  6. Breadboard and jumper wires
  7. USB cable for programming

Software:

  1. Arduino IDE, free download from their website

Mechanical bits:

  1. 3D printed parts (I'll link the files)
  2. Some screws and basic mounting hardware

If you don't have a 3D printer no worries. I've seen people hack this together with cardboard, PVC pipe even old coat hangers. As long as the servos can move freely and everything's reasonably sturdy you're good.

Getting the Electronics Wired

Circuit-Connection-Of-Dual-Axis-Solar-Tracker.jpg

Each LDR needs a 10k resistor paired with it. This creates a voltage divider so the Arduino can read light levels. Here's the pattern for each one: LDR leg one goes to 5V. LDR leg two connects to an analog pin AND one side of the resistor. Other side of the resistor goes to ground.

Do this four times and connect them like this:

  1. Top-left LDR to A0
  2. Top-right LDR to A3
  3. Bottom-left LDR to A1
  4. Bottom-right LDR to A2

The servos are simpler. Horizontal servo signal goes to digital pin 2. Vertical servo signal goes to pin 13. Both need 5V and ground.

One thing to watch out for. Servos pull serious current. If your Arduino starts glitching or resetting randomly you might need to power the servos separately. I ran into this and switching to an external 5V supply fixed it immediately.

Building the Frame

3D-Models-Fabricating-Process.jpg
3D-Models-Of-Dual-Axis-Solar-Tracker.jpg
3D-Printed-Parts-Of-Dual-Axis-Solar-Tracker.jpg

I used 3D printed parts from a design I found at simplecircuitslol.blogspot.com. Worked out pretty well.

You need a base mount, some servo brackets, a panel holder and clips for the LDRs. Takes maybe 3-4 hours to print with standard PLA.

Assembly is straightforward. Mount your horizontal servo to the base first. Then the vertical servo attaches to the horizontal servo's arm. Panel goes on the vertical servo bracket. Finally position your four LDRs at the corners in that cross pattern.

Keep it light. Heavy builds make servos struggle especially when wind picks up. My first version was way too bulky and the tracking was sluggish.

The Code

Open Arduino IDE and paste this in:

#include <Servo.h>

Servo horizontal;
Servo vertical;

int ldrlt = A0; // top-left
int ldrrt = A3; // top-right
int ldrld = A1; // bottom-left
int ldrrd = A2; // bottom-right

int tol = 15;
int servoh = 90;
int servov = 90;

void setup() {
horizontal.attach(2);
vertical.attach(13);
horizontal.write(servoh);
vertical.write(servov);
Serial.begin(9600);
}

void loop() {
int lt = readAverage(ldrlt);
int rt = readAverage(ldrrt);
int ld = readAverage(ldrld);
int rd = readAverage(ldrrd);
int avt = (lt + rt) / 2;
int avd = (ld + rd) / 2;
int avl = (lt + ld) / 2;
int avr = (rt + rd) / 2;
int avgLight = (lt + rt + ld + rd) / 4;
if (avgLight < 200) {
Serial.println("Too dark");
delay(5000);
return;
}
int dvert = avt - avd;
int dhoriz = avl - avr;
if (abs(dvert) > tol) {
if (dvert > 0) {
if (servov > 20) servov--;
} else {
if (servov < 160) servov++;
}
vertical.write(servov);
}
if (abs(dhoriz) > tol) {
if (dhoriz > 0) {
if (servoh > 20) servoh--;
} else {
if (servoh < 160) servoh++;
}
horizontal.write(servoh);
}
delay(100);
}

int readAverage(int pin) {
long total = 0;
for (int i = 0; i < 10; i++) {
total += analogRead(pin);
delay(2);
}
return total / 10;
}

The readAverage() function is doing something important here. Instead of just reading each sensor once it takes 10 samples and averages them. Smooths out electrical noise. Without this the panel gets really twitchy because it's reacting to every tiny fluctuation.

Main loop reads all four sensors then calculates which sides are brighter. If one side has significantly more light than the opposite side it moves that servo a bit. The tolerance value (set to 15) determines how much difference triggers movement. Play with this number to tune your tracker.

There's a night mode check too. When average light drops below 200 the system stops and waits. Otherwise it would try tracking your porch light or whatever.

Servo angles are limited to 20-160 degrees so the mechanism doesn't try to rotate too far and bind up.

Testing It Out

Full-Setup-Of-Dual-Axis-Solar-Tracker.jpg

Power it up and use a flashlight. Move the light around and watch the panel follow it. Should be smooth not jerky.

If it's overshooting or hunting around bump up the tolerance to 20 or 25. If it's not tracking accurately enough lower it to 10.

Take it outside on a sunny day. At sunrise it'll wake up and start tracking east. Through the morning it tilts up as the sun climbs. Afternoon it tracks west. Sunset it parks and waits for tomorrow.

Pretty satisfying to watch once it's dialed in.

Real Performance

I've been running this for a few weeks. Clear days I'm consistently seeing 30-40% more output than when the panel was fixed. Morning and evening make the biggest difference because the sun's so low. A fixed panel barely catches anything but the tracker stays pointed right at it.

Single-axis trackers usually give you 20-25% improvement. That second axis really makes a difference.

When Something's Not Right

Panel drifting to one side means check your LDR wiring. Test each sensor by shining the same light on it and making sure they all read similar values.

Too much twitchy movement try increasing the samples in readAverage() from 10 to 15 or 20. You can also add 0.1uF capacitors across each LDR. Sometimes servo electrical noise interferes with the readings.

Won't track at dawn or dusk lower that 200 threshold to maybe 100 or 150. Just don't go too low or it'll track in the dark.

Servos not moving at all double check power and signal wire connections.

Few More Things

If this is going outside permanently protect those LDRs from rain. I put mine under a clear acrylic dome with some ventilation holes. Keeps them dry but light gets through fine.

Wind matters with bigger panels. Keep the build light. Scale it up and you might want metal gear servos instead of plastic.

That tolerance value is really the tuning knob for good tracking. Spend time getting it right for your setup.

If you're using this to charge batteries add a charge controller. Don't wire the panel directly to anything.

Done

Building this dual-axis solar tracker system using Arduino has been one of those projects that hits the sweet spot. It combines electronics, programming, mechanical design and practical renewable energy stuff all in one package. Plus there's just something satisfying about watching your creation follow the sun across the sky.

The energy gains are legit. If you're already messing around with solar power adding tracking capability makes your panels work way harder for you. And if you're just getting into solar this is a fantastic learning project that teaches fundamentals while actually producing results you can measure.