#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h> // For making the GET request
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Relay pins
const int line1RelayPin = 18;
const int line2RelayPin = 4;
// Fault check points
const int r1Pin = 12; // Line 1 Resistance Check
const int r2Pin = 26; // Line 2 Resistance Check
const int g1Pin = 25; // Line 1 Ground Check
const int g2Pin = 14; // Line 2 Ground Check
const int v1Pin = 33; // Line 1 Voltage Check
const int v2Pin = 27; // Line 2 Voltage Check
// Latitude and Longitude for each fault point (assumed values)
float latR1 = 19.031124, lonR1 = 72.841415; // Line 1 Resistance Check
float latR2 = 19.031924, lonR2 = 72.859415; // Line 2 Resistance Check
float latG1 = 19.021224, lonG1 = 72.842415; // Line 1 Ground Check
float latG2 = 19.021924, lonG2 = 72.849415; // Line 2 Ground Check
float latV1 = 19.111146, lonV1 = 72.861736; // Line 1 Voltage Check
float latV2 = 19.113646, lonV2 = 72.869736; // Line 2 Voltage Check
// Distance definitions
const int distanceR = 1; // 1 km
const int distanceG = 2; // 2 km
const int distanceV = 3; // 3 km
// Variables to store the last fault details
String lastLineNumber;
int lastDistance = 0;
float lastLat = 0.0, lastLon = 0.0;
int faultFlag = 0;
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
// Initialize the OLED display with error handling
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Ensure I2C address is correct
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
// Initialize relay pins as outputs
pinMode(line1RelayPin, OUTPUT);
pinMode(line2RelayPin, OUTPUT);
// Initialize fault check pins as inputs
pinMode(r1Pin, INPUT_PULLUP); // Pull-up resistor for stable input
pinMode(r2Pin, INPUT_PULLUP);
pinMode(g1Pin, INPUT_PULLUP);
pinMode(g2Pin, INPUT_PULLUP);
pinMode(v1Pin, INPUT_PULLUP);
pinMode(v2Pin, INPUT_PULLUP);
// Initialize WiFi
connectToWiFi();
Serial.println("Fault Detection System Initialized");
delay(1000);
}
void loop() {
// Read the pin states
int r1State = digitalRead(r1Pin);
int g1State = digitalRead(g1Pin);
int v1State = digitalRead(v1Pin);
int r2State = digitalRead(r2Pin);
int g2State = digitalRead(g2Pin);
int v2State = digitalRead(v2Pin);
// Reset faultFlag before checking
faultFlag = 0;
// Check fault conditions for Line 1
if (r1State == HIGH) {
updateFault("1", distanceR, latR1, lonR1, line1RelayPin);
} else if (g1State == HIGH) {
updateFault("1", distanceG, latG1, lonG1, line1RelayPin);
} else if (v1State == HIGH) {
updateFault("1", distanceV, latV1, lonV1, line1RelayPin);
}
// Check fault conditions for Line 2
if (r2State == HIGH) {
updateFault("2", distanceR, latR2, lonR2, line2RelayPin);
} else if (g2State == HIGH) {
updateFault("2", distanceG, latG2, lonG2, line2RelayPin);
} else if (v2State == HIGH) {
updateFault("2", distanceV, latV2, lonV2, line2RelayPin);
}
// Print last fault details if faultFlag == 1
if (faultFlag == 1) {
printLastFault();
sendFaultDetailsToAPI(lastLineNumber, lastDistance, lastLat, lastLon); // Send fault details to ThingSpeak
}
// Delay before the next check
delay(1000);
}
// Function to update the last fault details and set the relay HIGH
void updateFault(const String& line, int distance, float lat, float lon, int relayPin) {
lastLineNumber = line;
lastDistance = distance;
lastLat = lat;
lastLon = lon;
faultFlag = 1;
digitalWrite(relayPin, HIGH); // Set relay HIGH for the faulted line
}
// Function to print the last fault details
void printLastFault() {
// Print fault details to serial monitor
Serial.println("===== LAST FAULT DETAILS =====");
Serial.print("Line: "); Serial.println(lastLineNumber);
Serial.print("Distance: "); Serial.print(lastDistance); Serial.println(" km");
Serial.print("Latitude: "); Serial.print(lastLat, 4);
Serial.print(" | Longitude: "); Serial.println(lastLon, 4);
Serial.println("================================");
// Display fault on OLED
display.clearDisplay();
display.setCursor(0, 0);
display.print("Last Fault at:");
display.setCursor(0, 10);
display.print(lastLineNumber);
display.setCursor(0, 20);
display.print("Dist: ");
display.print(lastDistance);
display.print(" km");
display.setCursor(0, 30);
display.print("Lat: ");
display.print(lastLat, 4);
display.setCursor(0, 40);
display.print("Lon: ");
display.print(lastLon, 4);
display.display();
}
// Function to connect to WiFi
void connectToWiFi() {
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
// Function to send fault details to ThingSpeak via GET request
void sendFaultDetailsToAPI(const String& line, int distance, float lat, float lon) {
if (WiFi.status() == WL_CONNECTED) {
WiFiClient client;
String url = "https://api.thingspeak.com/update?api_key=K8CH7XH11OFPA1WG";
url += "&field1=" + line;
url += "&field2=" + String(distance);
url += "&field3=" + String(lon, 4);
url += "&field4=" + String(lat, 4);
Serial.print("Making GET request: ");
Serial.println(url);
if (client.connect("api.thingspeak.com", 80)) {
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: api.thingspeak.com\r\n" +
"Connection: close\r\n\r\n");
delay(500);
while (client.available()) {
String response = client.readString();
Serial.println(response);
}
} else {
Serial.println("Connection to ThingSpeak failed");
}
} else {
Serial.println("WiFi not connected");
}
}