#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <Keypad.h>
#include <WiFi.h>
#include <HTTPClient.h>
// ---------------- LCD & PINS ----------------
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define SENSOR_PIN 34
#define RELAY_PIN 5
#define TAMPER_PIN 15
#define BUZZER_PIN 18
// ---------------- KEYPAD ----------------
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 14, 27};
byte colPins[COLS] = {26, 25, 33, 32};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// ---------------- VARIABLES ----------------
float voltage = 230.0, current = 0, power = 0, energy = 0;
float balance = 0.0, cost_per_unit = 100.0;
byte tamperFlag = 0;
unsigned long lastTime = 0, lastCloudUpdate = 0, lastEepromWrite = 0;
bool pinVerified = false, enteringAmount = false;
bool lowBalanceAlertSent = false;
String input = "";
String enteredPIN = "";
String correctPIN = "1234";
const char* ssid = "Wokwi-GUEST";
const char* password = "";
String apiKey = "RY1OBK9W52Y7LARL";
// ---------------- SETUP ----------------
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
pinMode(TAMPER_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH);
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
EEPROM.begin(512);
EEPROM.get(10, tamperFlag);
if (tamperFlag == 1) {
lcd.print("LOCKED");
while (true) delay(100);
}
EEPROM.get(0, balance);
if (isnan(balance) || balance < 0) {
balance = 50;
EEPROM.put(0, balance);
EEPROM.commit();
}
lcd.print("Enter PIN");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(300);
}
}
// ---------------- HELPERS ----------------
void beep(int d) {
digitalWrite(BUZZER_PIN, HIGH);
delay(d);
digitalWrite(BUZZER_PIN, LOW);
}
void sendToCloud(int statusFlag) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
char url[200];
snprintf(url, sizeof(url),
"http://api.thingspeak.com/update?api_key=%s&field1=%.2f&field2=%.2f&field3=%.2f&field4=%d",
apiKey.c_str(), balance, energy, power, statusFlag);
http.begin(url);
http.setTimeout(2000);
http.GET();
http.end();
}
}
// ---------------- MODULES ----------------
void handleTamper() {
if (digitalRead(TAMPER_PIN) == LOW) {
tamperFlag = 1;
EEPROM.put(10, tamperFlag);
EEPROM.commit();
digitalWrite(RELAY_PIN, LOW);
lcd.clear();
lcd.print("TAMPER!");
while (true) delay(100);
}
}
void handleKeypad() {
char key = keypad.getKey();
if (!key) return;
if (key == '*') {
input = "";
enteredPIN = "";
lcd.clear();
lcd.print("Enter PIN");
}
else if (key == '#') {
if (!pinVerified) {
if (enteredPIN == correctPIN) {
pinVerified = true;
enteringAmount = true;
lcd.clear();
lcd.print("Enter Amt");
} else {
lcd.clear();
lcd.print("Wrong PIN");
beep(300);
enteredPIN = "";
}
}
else {
float recharge = input.toFloat();
if (recharge > 0) {
balance += recharge;
EEPROM.put(0, balance);
EEPROM.commit();
beep(100);
}
input = "";
enteredPIN = "";
pinVerified = false;
enteringAmount = false;
lcd.clear();
lcd.print("Enter PIN");
}
}
else {
if (!pinVerified) {
enteredPIN += key;
lcd.setCursor(0,1);
lcd.print(enteredPIN);
} else {
input += key;
lcd.setCursor(0,1);
lcd.print(input);
}
}
}
void updateEnergy() {
if (millis() - lastTime < 1000) return;
lastTime = millis();
int sensorValue = analogRead(SENSOR_PIN);
current = (sensorValue / 4095.0) * 5.0;
power = voltage * current;
float delta = (power / 1000.0) / 3600.0;
energy += delta;
balance -= delta * cost_per_unit;
if (balance < 0) balance = 0;
if (millis() - lastEepromWrite > 60000) {
EEPROM.put(0, balance);
EEPROM.commit();
lastEepromWrite = millis();
}
}
void updateRelay() {
digitalWrite(RELAY_PIN, balance > 0 ? HIGH : LOW);
}
void updateDisplay() {
lcd.setCursor(0,0);
lcd.print("E:");
lcd.print(energy,2);
lcd.setCursor(0,1);
lcd.print("Bal:");
lcd.print(balance,1);
}
void handleCloud() {
if (millis() - lastCloudUpdate > 20000) {
sendToCloud(0);
lastCloudUpdate = millis();
}
}
// ---------------- LOOP ----------------
void loop() {
handleTamper();
handleKeypad();
updateEnergy();
updateRelay();
updateDisplay();
handleCloud();
delay(10); // IMPORTANT
}Loading
esp32-devkit-c-v4
esp32-devkit-c-v4