Autonomous Solar Tracking Rover

An intelligent rover that autonomously tracks the sun's position to maximize solar energy collection while navigating its environment.

Explore Features

Key Features

Our solar tracking rover combines advanced sensing with intelligent movement algorithms

🔄

Dual-Axis Solar Tracking

Horizontal and vertical servo motors precisely position the solar panel to capture maximum sunlight throughout the day.

🚗

Intelligent Navigation

When light is insufficient, the rover autonomously moves to find better positioning based on optimal sun angle calculations.

Energy Efficient

Optimized movement patterns and smart scanning algorithms minimize power consumption while maximizing energy collection.

📊

Real-time Monitoring

Continuous voltage monitoring and angle tracking ensure the rover always operates at peak efficiency.

🔧

Adaptive Movement

Turns for 1 second when changing direction, then moves forward for 2 seconds to efficiently navigate toward light sources.

🌐

ESP8266 Powered

Built on the versatile ESP8266 platform with Wi-Fi capabilities for future IoT integrations.

How It Works

The solar tracking rover follows a systematic process to maximize energy collection

1

Solar Scanning

Scans horizontally (0-180°) and vertically (20-90°) to find optimal sun position

2

Voltage Analysis

Measures solar panel output at each position to determine maximum energy point

3

Position Adjustment

Moves servos to optimal angles for maximum energy collection

4

Rover Navigation

If voltage is low, moves rover based on optimal sun angle (1s turn + 2s forward)

Arduino Code

Explore the code that powers the solar tracking rover

sunChazer.ino
Copy Wrap
// --- 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");
}