Skip to main content

Dual Axis Solar Tracker System With Battery Charging

Dual Axis Solar Tracker with Battery Charging | SimpleCircuits
Renewable Energy Project

Dual Axis
Solar Tracker
+ Battery Charging

A complete solar energy solution — dual-axis LDR tracking, 12V panel array, TP5100 charging, 2S BMS protection, and 7.4V battery. Up to 40% more energy capture than fixed mounts.

40%Efficiency Gain
12VPanel Output
2-AxisTracking
7.4VBattery
BMSProtected
Solar Tracker Front View Finished Build

System Overview

How the System Works

Four LDR modules with adjustable potentiometers sense directional light intensity. Arduino computes top/bottom and left/right deltas, driving two SG90 servos to keep the panel perpendicular to sunlight. Harvested energy flows through the TP5100 → BMS → battery chain.

01

Sense

4 LDR modules on A0–A3 read directional light intensity continuously.

02

Compare

Arduino averages top/bottom and left/right pairs, calculates delta.

03

Track

If delta exceeds tolerance (90), servo steps toward higher brightness.

04

Harvest

2 × 6V panels in series → 12V → TP5100 → BMS → 7.4V battery.


Power System

Power Management

A complete solar-to-battery chain with protection at every stage. The TP5100 handles the voltage step-down from 12V to 8.4V, while the 2S BMS guards the lithium battery against all common failure modes.

☀️

Solar Array

2 × 6V panels in series = 12V output. Feeds directly into TP5100 input.

TP5100 Charger

Converts 12V input to 8.4V for 2S lithium battery charging. Handles up to 2A.

🛡️

2S 20A BMS

Protects against overcharge, over-discharge, overcurrent, and short circuits.

🔋

7.4V Battery

Provides stable power for both servo motors and Arduino via BMS output.


Bill of Materials

Components Required

Nine components — everything from the 3D-printed frame to the battery protection board.

ComponentNotesBuy
Arduino UNOMain controllerBuy Now
SG90 Servo Motors (×2)Horizontal pin 3, Vertical pin 13Buy Now
LDR Modules (×4)With adjustable potentiometerBuy Now
6V Solar Panels (×2)In series = 12VBuy Now
TP5100 Charging Module12V → 8.4V, up to 2ABuy Now
2S 20A BMSBattery protection boardBuy Now
7.4V Li-ion Battery2S configurationBuy Now
BreadboardPower distributionBuy Now
Jumper WiresM-M and M-F setBuy Now

3D Printable

3D Model Files

Download the dual-axis mechanism, servo mounts, panel platform, and mounting brackets. Print at home or order a professional print via JLC3DP.


Wiring Reference

Pin Connections

Complete wiring table for all components. LDR modules use analog pins A0–A3. Servos on D3 and D13. Power flows from panels → TP5100 → BMS → battery → Arduino VIN.

ComponentComponent PinArduino / DestinationNotes
LDR Module — Top LeftAO (Analog Out)A0Analog input
LDR Module — Top RightAO (Analog Out)A1Analog input
LDR Module — Bottom RightAO (Analog Out)A2Analog input
LDR Module — Bottom LeftAO (Analog Out)A3Analog input
All LDR ModulesVCC5VArduino 5V rail
All LDR ModulesGNDGNDCommon ground
SG90 Servo — HorizontalSignal (Orange)D3PWM pin
SG90 Servo — VerticalSignal (Orange)D13PWM pin
Both ServosVCC (Red)7.4V BatteryDirect from BMS output — not Arduino 5V
Both ServosGND (Brown)GND (common)Shared ground rail
6V Panel 1 + Panel 2Series connectionTP5100 IN++12V to TP5100 input
Panels (series GND)Panel 2 negativeTP5100 IN–Common ground
TP5100OUT+ (8.4V)BMS B+Charging input to BMS
TP5100OUT–GND (common)Common ground
2S BMSP+ (output)Arduino VINPowers Arduino
2S BMSP– (output)GND (common)Common ground
7.4V BatteryB1+, B2+ (cells)BMS cell inputsConnect per BMS datasheet

Servo power note: Power the SG90 servos directly from the battery output (via BMS), not from the Arduino 5V pin. Two servos under load can draw 500–800mA which exceeds the Arduino's onboard regulator limit. Share a common GND between Arduino and battery.


Build Guide

Step-by-Step Assembly

01

3D Print & Mechanical Assembly

Print all components from the provided files. Assemble the dual-axis gimbal mechanism, mount both SG90 servos, and attach the solar panel platform. Verify smooth movement in both axes.

02

Mount LDR Sensors

Position one LDR module in each quadrant around the panel edge — top-left (A0), top-right (A1), bottom-right (A2), bottom-left (A3). Use the potentiometers to set equal sensitivity.

03

Connect Servo Motors

Horizontal servo signal → D3, vertical servo signal → D13. Power both servos directly from the BMS 7.4V output, not the Arduino 5V pin. Share common GND.

04

Wire Solar Panels in Series

Connect Panel 1 positive to Panel 2 negative (series). Panel 1 negative → TP5100 IN–. Panel 2 positive → TP5100 IN+. This gives ~12V input to the charger.

05

Set Up Charging Chain

TP5100 OUT+ → BMS B+ charging input. TP5100 OUT– → GND. Connect 7.4V Li-ion cells to BMS per its datasheet (cell 1 and cell 2 inputs).

06

Power the Arduino

BMS P+ output → Arduino VIN. BMS P– → GND common rail. This allows the fully charged 7.4V battery to power the Arduino through its onboard regulator.

07

Upload Code & Calibrate

Upload the Arduino code. Shine a light from different angles to verify tracking direction. Adjust LDR pot sensitivity if response is sluggish or over-reactive.

08

Test Battery Charging

Place in sunlight and verify the TP5100 charging LED activates. Check BMS output voltage with a multimeter. Confirm servos respond to light movement.


Demo

Assembly & Demo Video

Full assembly walkthrough, power system wiring, LDR calibration, and live sun-tracking demonstration.

🎥

Watch for the power chain wiring — especially how the TP5100, BMS, and battery connect together. The video also shows the 3D assembly sequence and LDR sensitivity adjustment.


Firmware

Arduino Code

Both servos start at 90°. Tolerance of 90 prevents micro-jitter. Movement direction is reversed from the basic tracker to match this mechanism's physical orientation.

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

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

Servo vertical;            // Vertical Servo Motor
int servovert          = 90;
int servovertLimitHigh = 175;
int servovertLimitLow  = 5;

// LDR module connections
int ldrTopLeft     = A0;   // Top Left LDR
int ldrTopRight    = A1;   // Top Right LDR
int ldrBottomRight = A2;   // Bottom Right LDR
int ldrBottomLeft  = A3;   // Bottom Left LDR

void setup() {
  horizontal.attach(3);    // Horizontal servo on pin 3
  vertical.attach(13);     // Vertical servo on pin 13
  horizontal.write(servohori);
  vertical.write(servovert);
  delay(2500);
}

void loop() {
  int tl = analogRead(ldrTopLeft);     // Top Left
  int tr = analogRead(ldrTopRight);    // Top Right
  int br = analogRead(ldrBottomRight); // Bottom Right
  int bl = analogRead(ldrBottomLeft);  // Bottom Left

  int dtime = 10;
  int tol   = 90;  // Tolerance — increase to reduce jitter

  // Axis averages
  int avt = (tl + tr) / 2;   // Top average
  int avd = (bl + br) / 2;   // Bottom average
  int avl = (tl + bl) / 2;   // Left average
  int avr = (tr + br) / 2;   // Right average

  int dvert  = avt - avd;    // Top-bottom difference
  int dhoriz = avl - avr;    // Left-right difference

  // ── Vertical axis (REVERSED for this mechanism) ─────
  if (abs(dvert) > tol) {
    if (avt > avd) {
      servovert = --servovert;
      if (servovert < servovertLimitLow) servovert = servovertLimitLow;
    } else {
      servovert = ++servovert;
      if (servovert > servovertLimitHigh) servovert = servovertLimitHigh;
    }
    vertical.write(servovert);
  }

  // ── Horizontal axis (REVERSED for this mechanism) ───
  if (abs(dhoriz) > tol) {
    if (avl > avr) {
      servohori = ++servohori;
      if (servohori > servohoriLimitHigh) servohori = servohoriLimitHigh;
    } else {
      servohori = --servohori;
      if (servohori < servohoriLimitLow) servohori = servohoriLimitLow;
    }
    horizontal.write(servohori);
  }

  delay(dtime);
}

setup()

Both servos initialise to 90° (centre). 2.5 s delay lets servos reach position before tracking begins.

loop()

Reads 4 LDR values, averages axis pairs, checks delta against tolerance (90). Steps servo ±1° per cycle.

Reversed Logic

Movement direction is flipped vs. the basic tracker to suit this 3D-printed mechanism's servo orientation.

Tuning

Increase tol (e.g. 120) to reduce jitter in wind. Decrease for faster response indoors.


Performance

Why Choose This Design?

40% Higher Yield

Dual-axis tracking vs fixed panel, all day and all season.

Integrated Charging

Complete power management — panels charge the battery automatically.

🛡️

Battery Safety

2S BMS prevents overcharge, over-discharge, short circuits.

🌞

Precise Tracking

4 LDR modules with individual sensitivity potentiometers.

🔄

Dual-Axis

Tracks both daily East–West arc and seasonal elevation changes.

🛠️

3D Printed

Custom enclosure for durability and professional finish.


Design Your Own PCBs with Altium

For designing a custom solar tracker PCB — integrating Arduino, servo drivers, and BMS monitoring on one board — I use Altium. It makes professional electronics design faster and production-ready.

Students get free access via Altium Student Lab — sign up with your university email for PCB courses and industry certifications.

👉 Start designing with Altium →

Moonlight Silver Theme · Designed for makers & solar enthusiasts

Comments

Post a Comment

Popular posts from this blog

Solar Tracking System

Dual-Axis Solar Tracking System | Arduino SimpleCircuits Arduino Solar DIY 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 Finished Build System Overview 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. ...

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