#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ThingSpeak API details
const char* server = "https://api.thingspeak.com";
const char* apiKey = "CDJEFTTGRAFUMV67";
// Pins
#define ONE_WIRE_BUS 15
const int voltagePin = 35;
const int currentPin = 34;
// Temperature sensor
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature tempSensor(&oneWire);
float voltage, current, power, powerConsumption, temperature, costOfElectricity;
unsigned long previousMillis = 0;
unsigned long totalMillis = 0;
// Password protection
const String correctPassword = "Afeeq2002";
bool isAuthenticated = false;
// Timeout constants
const unsigned long timeoutDuration = 5 * 60 * 1000; // 5 minutes in milliseconds
const unsigned long inactivityDuration = 5 * 60 * 1000; // Inactivity timeout (5 minutes)
// Timer for inactivity
unsigned long lastActivityTime = 0;
// Function to calculate cost based on TNB tariff
float calculateCost(float powerConsumption) {
float cost = 0.0;
if (powerConsumption <= 200) {
cost = powerConsumption * 0.218; // Tier 1
} else if (powerConsumption <= 300) {
cost = (200 * 0.218) + ((powerConsumption - 200) * 0.334); // Tier 2
} else if (powerConsumption <= 600) {
cost = (200 * 0.218) + (100 * 0.334) + ((powerConsumption - 300) * 0.516); // Tier 3
} else {
cost = (200 * 0.218) + (100 * 0.334) + (300 * 0.516) + ((powerConsumption - 600) * 0.546); // Tier 4
}
return cost;
}
void authenticateUser() {
Serial.println("Enter Password:");
String enteredPassword = "";
unsigned long startTime = millis();
while (!isAuthenticated) {
if (millis() - startTime >= timeoutDuration) {
Serial.println("Authentication timeout! Restarting system...");
ESP.restart(); // Restart the ESP32
}
if (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (enteredPassword == correctPassword) {
isAuthenticated = true;
lastActivityTime = millis(); // Reset inactivity timer
Serial.println("Access Granted!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Access Granted!");
display.display();
delay(1000);
} else {
Serial.println("Incorrect Password! Try again:");
enteredPassword = "";
}
} else {
enteredPassword += c;
}
}
}
}
void connectToWiFi() {
WiFi.begin(ssid, password);
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - startTime >= timeoutDuration) {
Serial.println("WiFi connection timeout! Restarting system...");
ESP.restart(); // Restart the ESP32
}
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi connected!");
lastActivityTime = millis(); // Reset inactivity timer
}
void sendDataToThingSpeak() {
int rawVoltage = analogRead(voltagePin);
int rawCurrent = analogRead(currentPin);
voltage = (rawVoltage / 4095.0) * 230; // Assuming 230V as a reference
float currentVoltage = (rawCurrent / 4095.0) * 5; // Assuming 5V reference
current = currentVoltage / 0.1; // Sensor sensitivity: 0.1V/A
power = voltage * current;
unsigned long currentMillis = millis();
unsigned long elapsedTime = currentMillis - previousMillis;
previousMillis = currentMillis;
totalMillis += elapsedTime;
float elapsedTimeHours = totalMillis / 3600000.0; // Convert milliseconds to hours
powerConsumption = (power / 1000.0) * elapsedTimeHours; // Convert power to kWh
costOfElectricity = calculateCost(powerConsumption); // Use TNB tariff for cost calculation
tempSensor.requestTemperatures();
temperature = tempSensor.getTempCByIndex(0); // Assuming one temperature sensor
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = String(server) + "/update?api_key=" + apiKey +
"&field1=" + String(voltage, 2) +
"&field2=" + String(current, 2) +
"&field3=" + String(powerConsumption, 2) +
"&field4=" + String(temperature, 2) +
"&field5=" + String(costOfElectricity, 2);
http.begin(url);
int httpCode = http.GET();
http.end();
if (httpCode > 0) {
Serial.println("Data sent to ThingSpeak successfully!");
} else {
Serial.println("Error sending data.");
}
} else {
Serial.println("WiFi not connected!");
}
lastActivityTime = millis(); // Reset inactivity timer
}
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED allocation failed");
for (;;);
}
display.clearDisplay();
display.setTextColor(WHITE);
authenticateUser(); // Password protection
connectToWiFi(); // Connect to WiFi
tempSensor.begin();
lastActivityTime = millis(); // Reset inactivity timer
}
void loop() {
static unsigned long lastSendTime = 0;
if (millis() - lastSendTime >= 5000) { // Send data every 5 seconds
sendDataToThingSpeak();
lastSendTime = millis();
}
// Check for inactivity timeout
if (millis() - lastActivityTime >= inactivityDuration) {
Serial.println("Inactivity timeout! Restarting system...");
ESP.restart(); // Restart the ESP32
}
display.clearDisplay();
display.setCursor(0, 0);
display.print("Voltage: ");
display.println(voltage, 2);
display.print("Current: ");
display.println(current, 2);
display.print("Power (kWh): ");
display.println(powerConsumption, 2);
display.print("Temp: ");
display.println(temperature, 2);
display.print("Cost: RM ");
display.println(costOfElectricity, 2);
display.display();
}