Flat solar panels lose significant power as the sun moves across the sky. This project uses four light-dependent resistors (LDRs) and two servo motors to track the sun's position accurately in both azimuth and elevation, keeping your panel perpendicular to the sun's rays all day long.
The core logic of a solar tracker involves comparing light levels between sensors. Four LDRs are arranged in a "quad" pattern separated by a divider. If the sun is slightly to the right, the right-side sensors receive more light, and the Arduino commands the horizontal servo to rotate until the light levels are balanced.
Single-axis trackers follow the sun from East to West. Dual-axis trackers also account for seasonal changes in the sun's height (elevation), ensuring peak efficiency through all four seasons.
The LDRs are wired as voltage dividers. The servos require a stable 5V source (external power recommended for MG90S).
| Peripheral | Device Pin | Arduino Pin | Notes |
|---|---|---|---|
| LDR Top-Left | Signal | Analog A0 | Divider Network |
| LDR Top-Right | Signal | Analog A1 | Divider Network |
| LDR Bottom-Left | Signal | Analog A2 | Divider Network |
| LDR Bottom-Right | Signal | Analog A3 | Divider Network |
| Horizontal Servo | PWM | Digital 9 | Azimuth Control |
| Vertical Servo | PWM | Digital 10 | Elevation Control |
Be careful when mounting your solar panel; ensure wires have enough slack for 180° rotation. Program travel limits in your code to prevent the servos from stalling against the frame.
#include <Servo.h>
Servo horizontal;
Servo vertical;
int servoh = 90; // Horizontal pos
int servov = 90; // Vertical pos
void setup() {
horizontal.attach(9);
vertical.attach(10);
horizontal.write(servoh);
vertical.write(servov);
}
void loop() {
int tl = analogRead(A0); // Top Left
int tr = analogRead(A1); // Top Right
int bl = analogRead(A2); // Bottom Left
int br = analogRead(A3); // Bottom Right
int dvert = ((tl + tr) / 2) - ((bl + br) / 2); // vertical diff
int dhoriz = ((tl + bl) / 2) - ((tr + br) / 2); // horizontal diff
if (abs(dvert) > 15) {
if (dvert > 0) servov++; else servov--;
vertical.write(constrain(servov, 10, 160));
}
if (abs(dhoriz) > 15) {
if (dhoriz > 0) servoh--; else servoh++;
horizontal.write(constrain(servoh, 10, 170));
}
delay(50);
}