0% found this document useful (0 votes)
3 views7 pages

SEMS code

The document is an Arduino sketch for a smart meter that connects to WiFi and monitors electrical parameters such as voltage, current, and power consumption. It features a web server for client communication, allows for output toggling, and includes alert systems for overload and unit consumption limits. The code also handles data storage using EEPROM and provides a calibration function for voltage readings.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views7 pages

SEMS code

The document is an Arduino sketch for a smart meter that connects to WiFi and monitors electrical parameters such as voltage, current, and power consumption. It features a web server for client communication, allows for output toggling, and includes alert systems for overload and unit consumption limits. The code also handles data storage using EEPROM and provides a calibration function for voltage readings.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

#include <WiFi.

h>
#include <WiFiClient.h>
#include <WiFiAP.h>
const char *ssid = "play";
const char *password = "play1234";
WiFiServer server(80);
#include <ArduinoJson.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

WiFiClient client;

#define OUTPUT_1_PIN 27
#define OUTPUT_2_PIN 26
#define OUTPUT_3_PIN 25
#define OUTPUT_4_PIN 33
#define PUSH_SWITCH_1 13
#define PUSH_SWITCH_2 15
#define PUSH_SWITCH_3 14
#define PUSH_SWITCH_4 12
#define CURRENT_SENSOR_PIN 34
#define VOLTAGE_SENSOR_PIN 35

#define VOLTAGE_DIVIDER_RATIO 100.0


#define BASE_WATT_VOLTAGE 0.2
#define WATT_INCREMENT_PER_VOLT 0.9
#define ALERT_UNIT_THRESHOLD 10.0
#define NOMINAL_VOLTAGE 220.0

LiquidCrystal_I2C lcd(0x27, 16, 2);

bool outputStates[4] = {false, false, false, false};


bool lastSwitchStates[4] = {false, false, false, false};
float currentReading = 0.0;
float voltageReading = 0.0;
float powerReading = 0.0;
float unitConsumed = 1.0;
float totalUnits = 1.0;
unsigned long lastTime = 0;
bool alertShown = false;
bool clientConnected = false;
String alert = "";

#define UNIT_ADDR 0
#define TOTAL_UNITS_ADDR 4

void setup() {
Serial.begin(115200);
pinMode(OUTPUT_1_PIN, OUTPUT);
pinMode(OUTPUT_2_PIN, OUTPUT);
pinMode(OUTPUT_3_PIN, OUTPUT);
pinMode(OUTPUT_4_PIN, OUTPUT);
pinMode(PUSH_SWITCH_1, INPUT_PULLUP);
pinMode(PUSH_SWITCH_2, INPUT_PULLUP);
pinMode(PUSH_SWITCH_3, INPUT_PULLUP);
pinMode(PUSH_SWITCH_4, INPUT_PULLUP);

digitalWrite(OUTPUT_1_PIN, HIGH);
digitalWrite(OUTPUT_2_PIN, HIGH);
digitalWrite(OUTPUT_3_PIN, HIGH);
digitalWrite(OUTPUT_4_PIN, HIGH);

lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Smart Meter");
lcd.setCursor(0, 1);
lcd.print("Initializing...");

EEPROM.begin(512);
loadData();
setupAccessPoint();
updateDisplay();
}

void setupAccessPoint() {
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi AP Ready");
lcd.setCursor(0, 1);
lcd.print("SSID: play");
delay(3000);
}

void loop() {
handleSocketConnection();
if (millis() - lastTime >= 1000) {
readSensors();
calculatePower();
calculateCurrent();
calculateUnits();
checkAlert();
updateDisplay();
sendDataToClient();
lastTime = millis();
handlePushSwitches();
}
}

void handleSocketConnection() {
if (!clientConnected) {
client = server.available();
if (client) {
Serial.println("New client connected");
clientConnected = true;
client.setNoDelay(true);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Client Connected");
delay(2000);
}
} else {
if (!client.connected()) {
Serial.println("Client disconnected");
clientConnected = false;
client.stop();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Client Disconnected");
delay(2000);
} else {
handleClientCommands();
}
}
}

void handleClientCommands() {
if (client.available()) {
String command = client.readStringUntil('\n');
command.trim();
if (command.length() > 0) {
Serial.println("Received command: " + command);
if (command.startsWith("TOGGLE:")) {
int output = command.substring(7).toInt();
if (output >= 0 && output < 4) {
toggleOutput(output);
sendResponse("OK");
} else {
sendResponse("ERROR: Invalid output");
}
} else if (command == "RESET") {
resetUnits();
sendResponse("OK");
} else if (command == "GET_DATA") {
sendDataToClient();
} else if (command == "CALIBRATE") {
calibrateVoltage();
sendResponse("Calibration complete - check Serial Monitor");
} else {
sendResponse("ERROR: Unknown command");
}
}
}
}

void sendResponse(String response) {


if (clientConnected && client.connected()) {
client.println(response);
client.flush();
}
}

void sendDataToClient() {
if (clientConnected && client.connected()) {
StaticJsonDocument<200> doc;
doc["voltage"] = voltageReading;
doc["current"] = currentReading;
doc["power"] = powerReading;
doc["unitConsumed"] = unitConsumed;
doc["totalUnits"] = totalUnits;
doc["output1"] = outputStates[0];
doc["output2"] = outputStates[1];
doc["output3"] = outputStates[2];
doc["output4"] = outputStates[3];
doc["alert"] = alert;
String jsonString;
serializeJson(doc, jsonString);
client.println("DATA:" + jsonString);
client.flush();
}
}

void handlePushSwitches() {
int switchPins[4] = {PUSH_SWITCH_1, PUSH_SWITCH_2, PUSH_SWITCH_3, PUSH_SWITCH_4};
int outputPins[4] = {OUTPUT_1_PIN, OUTPUT_2_PIN, OUTPUT_3_PIN, OUTPUT_4_PIN};
for (int i = 0; i < 4; i++) {
bool currentSwitchState = !digitalRead(switchPins[i]);
if (currentSwitchState && !lastSwitchStates[i]) {
toggleOutput(i);
Serial.print("Output ");
Serial.print(i + 1);
Serial.print(": ");
Serial.println(outputStates[i] ? "ON" : "OFF");
}
lastSwitchStates[i] = currentSwitchState;
}
}

void toggleOutput(int output) {


if (output >= 0 && output < 4) {
outputStates[output] = !outputStates[output];
int outputPins[4] = {OUTPUT_1_PIN, OUTPUT_2_PIN, OUTPUT_3_PIN, OUTPUT_4_PIN};
digitalWrite(outputPins[output], !outputStates[output]);
}
}

float voltageReadings[10] = {0};


int voltageIndex = 0;
float powerReadings[5] = {0};
int powerIndex = 0;

void readSensors() {
int voltageRaw = 0;
for (int i = 0; i < 5; i++) {
voltageRaw += analogRead(VOLTAGE_SENSOR_PIN);
delayMicroseconds(100);
}
voltageRaw = voltageRaw / 5;
float voltage = (voltageRaw / 12.08);
voltageReadings[voltageIndex] = voltage;
voltageIndex = (voltageIndex + 1) % 10;
float sum = 0;
for (int i = 0; i < 10; i++) {
sum += voltageReadings[i];
}
voltageReading = sum / 10.0;
if (voltageReading < 5.0) {
voltageReading = 0.0;
}
static int debugCounter = 0;
debugCounter++;
if (debugCounter >= 10) {
Serial.print("Raw ADC: ");
Serial.print(voltageRaw);
Serial.print(", ADC Voltage: ");
Serial.print(voltage, 2);
Serial.print("V, AC RMS: ");
Serial.print(voltageReading, 1);
Serial.println("V");
debugCounter = 0;
}
}

void calculatePower() {
int temppowerReading = 0;
if ((analogRead(CURRENT_SENSOR_PIN) == 0)) {
if ((outputStates[0] == true) || (outputStates[1] == true) || (outputStates[2]
== true) || (outputStates[3] == true)) {
powerReading = 100.0;
} else {
powerReading = 0.0;
}
} else if ((analogRead(CURRENT_SENSOR_PIN) < 1500) &&
(analogRead(CURRENT_SENSOR_PIN) > 500)) {
powerReading = (analogRead(CURRENT_SENSOR_PIN) + 144) / 6.82;
} else if ((analogRead(CURRENT_SENSOR_PIN) > 1500) &&
(analogRead(CURRENT_SENSOR_PIN) < 2500)) {
powerReading = (analogRead(CURRENT_SENSOR_PIN)) / 8.73;
} else if ((analogRead(CURRENT_SENSOR_PIN) > 2500)) {
powerReading = (analogRead(CURRENT_SENSOR_PIN)) / 9.77;
} else {
powerReading = 0.0;
}
if (powerReading < 2.0) {
powerReading = 0.0;
}
if (powerReading > 450) {
outputStates[0] = false;
outputStates[1] = false;
outputStates[2] = false;
outputStates[3] = false;
digitalWrite(OUTPUT_1_PIN, HIGH);
digitalWrite(OUTPUT_2_PIN, HIGH);
digitalWrite(OUTPUT_3_PIN, HIGH);
digitalWrite(OUTPUT_4_PIN, HIGH);
overloadScreen();
alert = "OVER LOAD";
sendDataToClient();
delay(4000);
alert = "";
}
}

void overloadScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Alert! ");
lcd.setCursor(0, 1);
lcd.print(" OVER LOAD ");
}

void calculateCurrent() {
if (voltageReading > 0) {
currentReading = powerReading / voltageReading;
} else {
currentReading = 0.0;
}
if (currentReading > 100.0) currentReading = 100.0;
if (currentReading < 0.0) currentReading = 0.0;
}

void calculateUnits() {
float energyThisSecond = (powerReading / 1000);
Serial.println(energyThisSecond);
unitConsumed = unitConsumed + energyThisSecond;
Serial.println(unitConsumed);
totalUnits = totalUnits + energyThisSecond;
static int saveCounter = 0;
saveCounter++;
if (saveCounter >= 30) {
saveData();
saveCounter = 0;
}
}

void checkAlert() {
if (unitConsumed >= ALERT_UNIT_THRESHOLD && !alertShown) {
showAlert();
alert = "Unit limit exceeded";
sendDataToClient();
alertShown = true;
}
}

void showAlert() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALERT!");
lcd.setCursor(0, 1);
lcd.print("Unit: ");
lcd.print(unitConsumed, 3);
lcd.print(" kWh");
delay(3000);
}

void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("V:");
lcd.print(voltageReading, 1);
lcd.print("VAC I:");
lcd.print(currentReading, 2);
lcd.print("A");
lcd.setCursor(0, 1);
lcd.print("P:");
lcd.print(powerReading, 0);
lcd.print("W U:");
lcd.print(unitConsumed, 3);
}

void resetUnits() {
unitConsumed = 0.0;
alertShown = false;
saveData();
alert = "";
Serial.println("Units reset");
}

void loadData() {
EEPROM.get(UNIT_ADDR, unitConsumed);
EEPROM.get(TOTAL_UNITS_ADDR, totalUnits);
if (isnan(unitConsumed)) {
unitConsumed = 0;
}
if (isnan(totalUnits)) {
totalUnits = 0;
}
}

void saveData() {
EEPROM.put(UNIT_ADDR, unitConsumed);
EEPROM.put(TOTAL_UNITS_ADDR, totalUnits);
EEPROM.commit();
}

void calibrateVoltage() {
Serial.println("=== Voltage Calibration for Pakistan AC (220V) ===");
Serial.println("Connect 220V AC and check readings");
Serial.println("Expected: ADC ~2.2V should show ~220V AC");
for (int i = 0; i < 10; i++) {
int voltageRaw = analogRead(VOLTAGE_SENSOR_PIN);
float voltage = (voltageRaw / 4095.0) * 3.3 * VOLTAGE_DIVIDER_RATIO;
float voltageRMS = voltage / 1.414;
Serial.print("Sample ");
Serial.print(i + 1);
Serial.print(": Raw ADC = ");
Serial.print(voltageRaw);
Serial.print(", ADC Voltage = ");
Serial.print(voltage, 2);
Serial.print("V, AC RMS = ");
Serial.print(voltageRMS, 1);
Serial.println("V");
delay(1000);
}
Serial.println("=== Calibration Complete ===");
Serial.println("For 220V AC, ADC should read ~2.2V");
Serial.println("If incorrect, adjust VOLTAGE_DIVIDER_RATIO");
}

You might also like