#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Define stepper motor parameters
const int stepsPerRevolution = 200; // Adjust based on your stepper motors
// HorizontalStepper pins
const int stepPin1 = 5;
const int dirPin1 = 6;
// VerticalStepper pins
const int stepPin2 = 3; // Assign appropriate pins for stepper 2
const int dirPin2 = 4; // Assign appropriate pins for stepper 2
// LDR pins
const int ldrTopLeftPin = A0;
const int ldrTopRightPin = A1;
const int ldrBottomLeftPin = A2;
const int ldrBottomRightPin = A3;
// Voltage and current sensor pins
const int voltagePin = A4; // Replace with the correct pin for voltage sensor
const int currentPin = A5; // Replace with the correct pin for current sensor
// Threshold for LDR difference to trigger movement
const int threshold = 25; // Adjust for sensitivity
// Create stepper objects
Stepper azimuthStepper(stepsPerRevolution, stepPin1, dirPin1);
Stepper elevationStepper(stepsPerRevolution, stepPin2, dirPin2);
// LCD object
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust I2C address if needed
// Constants for calculations
const float latitude = 30.04; // Replace with your latitude
void setup() {
// Set initial stepper speeds
azimuthStepper.setSpeed(200); // Adjust as needed
elevationStepper.setSpeed(200); // Adjust as needed
// Start serial communication for debugging
Serial.begin(9600);
// Initialize the LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("System Ready");
delay(2000);
lcd.clear();
}
void az_elev() {
float p = 3.1416;
// Simulated sun position calculations
float delta = 23.45 * sin(2 * p * (81) / 365); // Example declination angle
float H = 15 * (12 - 12); // Example hour angle (12 noon)
// Calculate altitude
float alt = (sin(radians(latitude)) * sin(radians(delta)) + (cos(radians(latitude)) * cos(radians(delta)) * cos(radians(H))));
alt = degrees(asin(alt));
// Calculate azimuth
float az = (sin(radians(delta)) - sin(radians(latitude)) * sin(radians(alt))) / (cos(radians(latitude)) * cos(radians(alt)));
az = degrees(asin(az));
if (H < 0) {
az = az;
} else {
az = 360 - az;
}
// Move stepper motors using calculated azimuth and elevation
azimuthStepper.step(stepsPerRevolution * az / 360);
elevationStepper.step(stepsPerRevolution * alt / 90); // Assuming 90 degrees max elevation
delay(1000); // Update positions every second
}
void displayVoltageAndCurrent() {
// Read voltage and current values
float voltage = analogRead(voltagePin) * (5.0 / 1023.0) * 10; // Example calculation, adjust as needed
float current = analogRead(currentPin) * (5.0 / 1023.0) * 5; // Example calculation, adjust as needed
// Display values on LCD
lcd.setCursor(0, 0);
lcd.print("Voltage: ");
lcd.print(voltage, 2);
lcd.print(" V");
lcd.setCursor(0, 1);
lcd.print("Current: ");
lcd.print(current, 2);
lcd.print(" A");
}
void loop() {
// Read LDR values
int ldrTopLeft = analogRead(ldrTopLeftPin);
int ldrTopRight = analogRead(ldrTopRightPin);
int ldrBottomLeft = analogRead(ldrBottomLeftPin);
int ldrBottomRight = analogRead(ldrBottomRightPin);
// Calculate differences for horizontal and vertical movement
int horizontalDifference = ldrTopLeft + ldrBottomLeft - ldrTopRight - ldrBottomRight;
int verticalDifference = ldrTopLeft + ldrTopRight - ldrBottomLeft - ldrBottomRight;
// Determine movement directions and step
if (ldrTopLeft < 500 && ldrTopRight < 500 && ldrBottomLeft < 500 && ldrBottomRight < 500) {
if (horizontalDifference > threshold) {
azimuthStepper.step(1); // Move right
} else if (horizontalDifference < -threshold) {
azimuthStepper.step(-1); // Move left
} else {
azimuthStepper.step(0); // Stop
}
if (verticalDifference > threshold) {
elevationStepper.step(1); // Move up
} else if (verticalDifference < -threshold) {
elevationStepper.step(-1); // Move down
} else {
elevationStepper.step(0); // Stop
}
} else {
az_elev();
}
// Update LCD with voltage and current readings
displayVoltageAndCurrent();
delay(1000); // Adjust delay for smoother movement
}
Horizontal
Vertical
Solar Tracker
(Aim Horizontal pointer at sun
then north is up^^^)