Skip to main content

Solar Tracking System

Dual-Axis Solar Tracking System | Arduino
Renewable Energy Project

Dual-Axis Solar
Tracking System

Build a high-performance solar tracker that follows the sun in real-time. Four LDR sensors, an Arduino UNO, and two servo motors — boosting energy capture by up to 40% versus fixed mounts.

40% More Efficient
4 LDR Sensors
2 Servo Axes
<300mA Power Draw
Dual-Axis Solar Tracking System Finished Build

How the System Works

The tracker reads the sky through four LDR sensors placed around the panel, computes intensity deltas, and drives two SG90 servos in a real-time closed loop — keeping the panel perpendicular to sunlight from sunrise to sunset.

01

Sense

4 LDRs in voltage-divider config stream analog light data to A0–A3.

02

Compare

Arduino computes top/bottom and left/right intensity differences.

03

Decide

If delta exceeds tolerance (90), servo receives a step command.

04

Track

Panel tilts and rotates toward max brightness, loops at 10 ms.


Components Required

Everything you need to build the complete dual-axis tracker. All components are widely available and beginner-friendly.

Component Qty Buy
Arduino UNO Buy Now
Solar Panel (5V–6V) Buy Now
SG90 Servo Motors Buy Now
LDR Sensors Buy Now
10kΩ Resistors Buy Now
Breadboard + Jumper Wires 1 set
Battery / Power Bank (5V) Buy Now

3D Model Files

Download the STL files for the dual-axis bracket, servo mounts, and sensor housing. Print at home or order a professional print through JLCPCB's 3D service.


Circuit Diagram

Connect LDRs at A0–A3 in voltage divider configuration with 10kΩ pull-down resistors. Horizontal servo on pin 2, vertical on pin 13. Power with 5V from Arduino or external USB bank.

🎥

Full assembly tutorial above — step-by-step wiring, servo calibration, and a real-time sun tracking demo from first power-on.


Arduino Code

Upload this sketch to your UNO. The closed-loop algorithm reads all four LDR channels, calculates axis deltas, and steps each servo toward maximum brightness within user-defined angle limits.

solar_tracker.ino — Arduino C++
#include <Servo.h>

Servo horizontal;        // Horizontal Servo Motor
int servohori = 180;
int servohoriLimitHigh = 175;
int servohoriLimitLow  = 5;

Servo vertical;          // Vertical Servo Motor
int servovert = 45;
int servovertLimitHigh = 100;
int servovertLimitLow  = 1;

// LDR pin connections
int ldrlt = A0;  // Bottom Left  LDR
int ldrrt = A3;  // Bottom Right LDR
int ldrld = A1;  // Top Left     LDR
int ldrrd = A2;  // Top Right    LDR

void setup() {
  horizontal.attach(2);
  vertical.attach(13);
  horizontal.write(180);
  vertical.write(45);
  delay(2500);
}

void loop() {
  int lt = analogRead(ldrlt);
  int rt = analogRead(ldrrt);
  int ld = analogRead(ldrld);
  int rd = analogRead(ldrrd);

  int dtime = 10;
  int tol   = 90;  // Tolerance — adjust for sensitivity

  int avt = (lt + rt) / 2;  // Average top
  int avd = (ld + rd) / 2;  // Average bottom
  int avl = (lt + ld) / 2;  // Average left
  int avr = (rt + rd) / 2;  // Average right

  int dvert  = avt - avd;
  int dhoriz = avl - avr;

  if (abs(dvert) > tol) {
    if (avt > avd) {
      servovert = ++servovert;
      if (servovert > servovertLimitHigh) servovert = servovertLimitHigh;
    } else {
      servovert = --servovert;
      if (servovert < servovertLimitLow) servovert = servovertLimitLow;
    }
    vertical.write(servovert);
  }

  if (abs(dhoriz) > tol) {
    if (avl > avr) {
      servohori = --servohori;
      if (servohori < servohoriLimitLow) servohori = servohoriLimitLow;
    } else {
      servohori = ++servohori;
      if (servohori > servohoriLimitHigh) servohori = servohoriLimitHigh;
    }
    horizontal.write(servohori);
  }

  delay(dtime);
}

setup()

Attaches servos on pins 2 & 13. Sets horizontal to 180°, vertical to 45°. 2.5 s warm-up delay ensures stable servo position on power-on.

loop()

Reads 4 LDR values, averages axis pairs, checks delta vs. tolerance. Steps the appropriate servo by ±1° and clamps within safe limits. 10 ms delay smooths movement.


Why Dual-Axis Tracking?

A static south-facing panel captures peak power for only a fraction of the day. Dual-axis tracking eliminates that waste by keeping incidence angles near 90° across the full solar arc.

~40% Higher Yield

Prototype testing showed 38% more charging current versus a fixed panel.

🔄

Fully Open Source

Modify tolerance, limits, or add sensors. Works with any panel size.

☀️

Real-time Response

10 ms loop reacts instantly to clouds, season changes, or angle shifts.

đź§ 

STEM Education

Perfect for workshops, science fairs, and off-grid renewable demos.

Notable Coral Theme · Designed for makers & solar enthusiasts

Comments

  1. Thanks a lot! :)

    ReplyDelete
    Replies
    1. I sir, I seen your video then realised what we give output

      Delete
  2. me puedes decir si genera energĂ­a, y la puede almacenar ? por favor, gracias

    ReplyDelete
  3. Can you make a smart army tank with max features bro pls?

    ReplyDelete
    Replies
    1. 6767676767676767676766766767676776

      Delete
    2. 67676767676767676767676767676767676767

      Delete
  4. Hi I'm need to use stm32f103c8t6
    How do I change the code for this micro?

    ReplyDelete
  5. thank you this helped me and my school group a lot

    ReplyDelete
  6. how do i open the 3d model of the arms and other?

    ReplyDelete
  7. how do i get the 3d model? the google drive link dont work

    ReplyDelete
  8. I need to use rain sensor also how can it be done

    ReplyDelete
  9. did you use a 3mm photoresistor or a 12mm

    ReplyDelete
  10. how many voltage is this project needs to run

    ReplyDelete
  11. Can i also use 1,5 V Solar Panels ?

    ReplyDelete

Post a Comment

Popular posts from this blog

Arduino Code Car Parking System

 // Created by Simple Circuits  #include <Wire.h>  #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2);    #include <Servo.h>  Servo myservo; int IR1 = 2; int IR2 = 3; int Slot = 4;           //Total number of parking Slots int flag1 = 0; int flag2 = 0; void setup() {   Serial.begin(9600);      lcd.init(); //initialize the lcd     lcd.backlight(); //open the backlight     pinMode(IR1, INPUT); pinMode(IR2, INPUT);    myservo.attach(4); myservo.write(100); lcd.setCursor (0,0); lcd.print("     ARDUINO    "); lcd.setCursor (0,1); lcd.print(" PARKING SYSTEM "); delay (2000); lcd.clear();   } void loop(){  if(digitalRead (IR1) == LOW && flag1==0){ if(Slot>0){flag1=1; if(flag2==0){myservo.write(0); Slot = Slot-1;} }else{ lcd.setCursor (0,0); lcd.print("    SORRY :(    ");   lc...

Arduino Code

 //define Pins #include <Servo.h> Servo servo; int trigPin = 11; int echoPin = 12; // defines variables long duration; int distance; void setup()  {   servo.attach(13);   servo.write(180);  delay(2000);    // Sets the trigPin as an Output pinMode(trigPin, OUTPUT); // Sets the echoPin as an Input  pinMode(echoPin, INPUT); } void loop()  { // Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculating the distance distance= duration*0.034/2; // Prints the distance on the Serial Monitor Serial.print("Distance: "); Serial.println(distance); if ( distance <= 25   ) // Change Distance according to Ultrasonic Sensor Placement  { servo.write(180); delay(3000); ...