An intelligent rover that autonomously tracks the sun's position to maximize solar energy collection while navigating its environment.
Explore FeaturesOur solar tracking rover combines advanced sensing with intelligent movement algorithms
Horizontal and vertical servo motors precisely position the solar panel to capture maximum sunlight throughout the day.
When light is insufficient, the rover autonomously moves to find better positioning based on optimal sun angle calculations.
Optimized movement patterns and smart scanning algorithms minimize power consumption while maximizing energy collection.
Continuous voltage monitoring and angle tracking ensure the rover always operates at peak efficiency.
Turns for 1 second when changing direction, then moves forward for 2 seconds to efficiently navigate toward light sources.
Built on the versatile ESP8266 platform with Wi-Fi capabilities for future IoT integrations.
The solar tracking rover follows a systematic process to maximize energy collection
Scans horizontally (0-180°) and vertically (20-90°) to find optimal sun position
Measures solar panel output at each position to determine maximum energy point
Moves servos to optimal angles for maximum energy collection
If voltage is low, moves rover based on optimal sun angle (1s turn + 2s forward)
Explore the code that powers the solar tracking rover
// --- Pin Definitions ---
// Servo Pins
const int BOTTOM_SERVO_PIN = D3; // Horizontal movement
const int TOP_SERVO_PIN = D4; // Vertical movement
// Solar Panel Analog Pin
const int SOLAR_PANEL_PIN = A0; // Reads panel voltage
// Motor Driver (L298N) Pins (ESP8266 Mapping)
const int IN1 = D1; // Left Forward
const int IN2 = D2; // Left Backward
const int IN3 = D6; // Right Forward
const int IN4 = D7; // Right Backward
const int ENA = D5; // PWM Left motors
const int ENB = D8; // PWM Right motors
// --- Constants ---
#define LEFT_THRESHOLD 50
#define RIGHT_THRESHOLD 130
int speedValue = 255; // PWM speed (0-255)
// --- Servo Setup ---
Servo bottomServo;
Servo topServo;
// --- Tracking Variables ---
int bestHorizontalAngle = 90;
int bestVerticalAngle = 90;
float maxVoltage = 0;
int currentHorizontalAngle = 90;
int currentVerticalAngle = 90;
void setup() {
Serial.begin(9600);
// Attach servos
bottomServo.attach(BOTTOM_SERVO_PIN);
topServo.attach(TOP_SERVO_PIN);
// Initialize motor pins
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
stopMotors();
bottomServo.write(90);
topServo.write(90);
delay(1000);
}
void loop() {
energising();
delay(100);
}
// --- MAIN LOGIC ---
void energising() {
float voltage = readVoltage();
Serial.print("Initial voltage: "); Serial.println(voltage);
handleStartTracking();
if (maxVoltage <= 3.0) {
Serial.println("[LOW VOLTAGE] Initiating rover movement...");
moveRoverBasedOnAngle(bestHorizontalAngle);
}
delay(3000); // 3 second delay like original ESP logic
}
// --- Solar Tracking ---
void handleStartTracking() {
maxVoltage = 0;
bestHorizontalAngle = 90;
bestVerticalAngle = 90;
Serial.println("Starting Sun Tracking...");
initialisehor();
initialisever();
moveToBestPosition();
Serial.print("Best H Angle: "); Serial.println(bestHorizontalAngle);
Serial.print("Best V Angle: "); Serial.println(bestVerticalAngle);
Serial.print("Max Voltage: "); Serial.println(maxVoltage);
}
void initialisehor() {
for (int angle = 0; angle <= 180; angle++) {
bottomServo.write(angle);
delay(20);
float avgVoltage = 0;
for (int i = 0; i < 5; i++) {
avgVoltage += readVoltage();
delay(10);
}
avgVoltage /= 5.0;
if (avgVoltage > maxVoltage) {
maxVoltage = avgVoltage;
bestHorizontalAngle = angle;
}
}
}
void initialisever() {
for (int angle = 20; angle <= 90; angle++) {
topServo.write(angle);
delay(20);
float avgVoltage = 0;
for (int i = 0; i < 5; i++) {
avgVoltage += readVoltage();
delay(10);
}
avgVoltage /= 5.0;
if (avgVoltage > maxVoltage) {
maxVoltage = avgVoltage;
bestVerticalAngle = angle;
}
}
}
void moveToBestPosition() {
bottomServo.write(bestHorizontalAngle);
topServo.write(bestVerticalAngle);
delay(500);
}
float readVoltage() {
int sensorValue = analogRead(SOLAR_PANEL_PIN);
float voltage = sensorValue * (3.3 / 1023.0); // ESP8266 analog range is 0–3.3V
return voltage;
}
// --- Rover Movement Based on Angle ---
void moveRoverBasedOnAngle(int angle) {
if (angle < LEFT_THRESHOLD) {
turnLeft();
} else if (angle > RIGHT_THRESHOLD) {
turnRight();
} else {
moveForward();
}
delay(3000);
stopMotors();
}
// --- Motor Movement Functions ---
void moveForward() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, speedValue);
analogWrite(ENB, speedValue);
Serial.println("Moving Forward");
}
void turnLeft() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, speedValue);
analogWrite(ENB, speedValue);
Serial.println("Turning Left");
}
void turnRight() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(ENA, speedValue);
analogWrite(ENB, speedValue);
Serial.println("Turning Right");
}
void stopMotors() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(ENA, 0);
analogWrite(ENB, 0);
Serial.println("Motors Stopped");
}