#include <ESP32Servo.h>
#include <WiFi.h>
#include "ThingSpeak.h"
const int myChannelNumber = 2623310;
const char* myApiKey = "LCVN9YA4INZMWAEZ";
const char* server = "api.thingspeak.com";
const char *ssid = "Wokwi-GUEST";
const char *pass = "";
WiFiClient client;
// Create servo objects
Servo azimuthServo;
Servo elevationServo;
// Define LDR pins
const int ldrPinTop = 32;
const int ldrPinBottom = 33;
const int ldrPinLeft = 34;
const int ldrPinRight = 35;
// Define servo pins
const int azimuthServoPin = 18;
const int elevationServoPin = 19;
// Solar panel simulation constants
const float PANEL_EFFICIENCY = 0.15; // 15% efficiency
const float PANEL_AREA = 0.01; // m^2
const float MAX_LIGHT_INTENSITY = 1000; // W/m^2, maximum possible light intensity
const float MAX_VOLTAGE = 18; // Volts, maximum possible voltage
const float MIN_VOLTAGE = 9; // Volts, minimum possible voltage
void setup() {
Serial.begin(115200);
// Attach servos to their respective pins
azimuthServo.attach(azimuthServoPin);
elevationServo.attach(elevationServoPin);
// Initialize LDR pins as inputs
pinMode(ldrPinTop, INPUT);
pinMode(ldrPinBottom, INPUT);
pinMode(ldrPinLeft, INPUT);
pinMode(ldrPinRight, INPUT);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
// Initialize ThingSpeak
ThingSpeak.begin(client);
}
// Function to simulate voltage variation
float simulate_voltage(float lightIntensity) {
// Voltage varies linearly with light intensity
// Assume minimum voltage at 0 intensity, maximum at full intensity
float voltage = MIN_VOLTAGE + (MAX_VOLTAGE - MIN_VOLTAGE) * (lightIntensity / MAX_LIGHT_INTENSITY);
return voltage;
}
void loop() {
// Read values from the LDRs
int ldrValueTop = analogRead(ldrPinTop);
int ldrValueBottom = analogRead(ldrPinBottom);
int ldrValueLeft = analogRead(ldrPinLeft);
int ldrValueRight = analogRead(ldrPinRight);
// Print LDR values to Serial Monitor for debugging
Serial.print("Top: "); Serial.print(ldrValueTop);
Serial.print(" Bottom: "); Serial.print(ldrValueBottom);
Serial.print(" Left: "); Serial.print(ldrValueLeft);
Serial.print(" Right: "); Serial.println(ldrValueRight);
// Get current servo positions
int azimuthPos = azimuthServo.read();
int elevationPos = elevationServo.read();
// Determine which LDR reading to use based on servo positions
float selectedLdrValue;
if (elevationPos < 90) {
// Panel facing more upwards, use Top or Bottom LDR
selectedLdrValue = (ldrValueTop + ldrValueBottom) / 2.0;
} else {
// Panel facing more downwards, use Bottom LDR
selectedLdrValue = (ldrValueBottom + ldrValueTop) / 2.0;
}
if (azimuthPos < 90) {
// Panel facing more left, use Left LDR
selectedLdrValue = (ldrValueLeft + ldrValueRight) / 2.0;
} else {
// Panel facing more right, use Right LDR
selectedLdrValue = (ldrValueRight + ldrValueLeft) / 2.0;
}
// Calculate light intensity based on selected LDR value
float lightIntensity = (selectedLdrValue / 4095.0) * MAX_LIGHT_INTENSITY;
// Simulate variable voltage based on light intensity
float voltage = simulate_voltage(lightIntensity);
// Calculate solar panel output power
float outputPower = PANEL_EFFICIENCY * PANEL_AREA * lightIntensity;
// Calculate current from power and voltage
float current = outputPower / voltage;
// Send data to ThingSpeak
ThingSpeak.setField(1, ldrValueTop); // LDR Top value
ThingSpeak.setField(2, ldrValueBottom); // LDR Bottom value
ThingSpeak.setField(3, ldrValueLeft); // LDR Left value
ThingSpeak.setField(4, ldrValueRight); // LDR Right value
ThingSpeak.setField(5, lightIntensity); // Calculated light intensity
ThingSpeak.setField(6, outputPower); // Solar panel output power
ThingSpeak.setField(7, current); // Calculated current
ThingSpeak.setField(8, voltage); // Simulated voltage
int status = ThingSpeak.writeFields(myChannelNumber, myApiKey);
if (status == 200) {
Serial.println("Data sent to ThingSpeak successfully!");
} else {
Serial.println("Error sending data to ThingSpeak");
}
// Calculate differences for servo movement
int verticalDifference = ldrValueTop - ldrValueBottom;
int horizontalDifference = ldrValueLeft - ldrValueRight;
// Adjust azimuth (horizontal) servo position
if (horizontalDifference > 100) {
azimuthPos += 1; // Move servo to the right
} else if (horizontalDifference < -100) {
azimuthPos -= 1; // Move servo to the left
}
// Adjust elevation (vertical) servo position
if (verticalDifference > 100) {
elevationPos += 1; // Move servo up
} else if (verticalDifference < -100) {
elevationPos -= 1; // Move servo down
}
// Constrain servo positions to 0-180 degrees
azimuthPos = constrain(azimuthPos, 0, 180);
elevationPos = constrain(elevationPos, 0, 180);
// Write the new positions to the servos
azimuthServo.write(azimuthPos);
elevationServo.write(elevationPos);
delay(1000); // Wait a little before the next loop
}