/*
ADE9153A Custom Chip Arduino Driver Code
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <WiFiManager.h>
#include <SPI.h>
#include "ADE9153A.h"
#include "ADE9153AAPI.h"
#define SPI_SPEED 1000000 //SPI Speed
#define CS 15
#define STATE 2
#define LED 33
ADE9153AClass ade9153A;
struct PowerRegs powerVals; //Metrology data can be accessed from these structures
struct RMSRegs rmsVals;
void readandwrite(void);
unsigned long lastReport = 0;
const long reportInterval = 2000; /// Every 2s
const long SwitchToggleInterval = 2500;
const long blinkInterval = 500;
// WiFi
const char *ssid = "Wokwi-GUEST"; // Enter your WiFi name
const char *password = ""; // Enter WiFi password
// MQTT Broker
const char *mqtt_broker = "https://test.mosquitto.org/";
// const char *topic = "SPM-MS";
const char *mqtt_username = "";
const char *mqtt_password = "";
const int mqtt_port = 1883;
char buffer[200];
bool isScheduledOn = false;
unsigned long scheduledOnTime;
bool isScheduledOff = false;
unsigned long scheduledOffTime;
////////////////////////////
WiFiClient espClient;
PubSubClient mqttClient(espClient);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
void connectToWifi(){
WiFi.begin("Wokwi-GUEST","");
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address : ");
Serial.println(WiFi.localIP());
}
void setupWifi(){
WiFiManager wm;
bool res;
res = wm.autoConnect("Wokwi-GUEST","");
if (!res){
Serial.println("Failed to connect...");
} else {
Serial.println("Connected...");
}
}
void setupMqtt(){
mqttClient.setServer("test.mosquitto.org", 1883);
mqttClient.setCallback(receiveCallBack);
}
void connectToBroker(){
while(!mqttClient.connected()){
Serial.println("Attempting MQTT Connection...");
if(mqttClient.connect("ESP32-321654684684")){
Serial.println("MQTT Connected!!!");
mqttClient.subscribe("SPM-MS");
mqttClient.subscribe("SPM-SS-ON");
mqttClient.subscribe("SPM-SS-OFF");
}else{
Serial.println("MQTT Failed!!!");
Serial.println(mqttClient.state());
delay(5000);
}
}
}
void switchRelay(boolean statusRelay){
if(statusRelay){
digitalWrite(LED, HIGH);
digitalWrite(STATE, HIGH);
}else{
digitalWrite(LED, LOW);
digitalWrite(STATE, LOW);
}
}
void setupRelay(){
pinMode(LED, OUTPUT);
pinMode(STATE, OUTPUT);
}
void receiveCallBack(char* topic, byte* payload, unsigned int l){
Serial.print("Got a message : ");
Serial.println(topic);
char payLoadCharAr[l];
for(int i = 0; i < l; i++){
Serial.print((char)payload[i]);
payLoadCharAr[i] = (char)payload[i];
}
Serial.println();
if(strcmp(topic, "SPM-MS") == 0){
switchRelay((char)payload[0] == '1');
}
if(strcmp(topic, "SPM-SS-ON") == 0){
if((char)payload[0] == 'N'){
isScheduledOn = false;
}else{
isScheduledOn = true;
scheduledOnTime = atol(payLoadCharAr);
}
}
if(strcmp(topic, "SPM-SS-OFF") == 0){
if((char)payload[0] == 'N'){
isScheduledOff = false;
}else{
isScheduledOff = true;
scheduledOffTime = atol(payLoadCharAr);
}
}
}
void setupTime(){
timeClient.begin();
timeClient.setTimeOffset(5.5*3600);
}
unsigned long getTime(){
timeClient.update();
return timeClient.getEpochTime();
}
void checkScheduleON(){
if(isScheduledOn){
unsigned long currentTime = getTime() - (5.5*3600);
if(isScheduledOn && (currentTime > scheduledOnTime)){
switchRelay(true);
isScheduledOn = false;
mqttClient.publish("SPM-MS-AUTO", "1");
mqttClient.publish("SPM-SS-ON-AUTO", "0");
Serial.println("Schedule On");
}
}
}
void checkScheduleOFF(){
if(isScheduledOff){
unsigned long currentTime = getTime() - (5.5*3600);
if(isScheduledOff && (currentTime > scheduledOffTime)){
switchRelay(false);
isScheduledOff = false;
mqttClient.publish("SPM-MS-AUTO", "0");
mqttClient.publish("SPM-SS-OFF-AUTO", "0");
Serial.println("Schedule Off");
}
}
}
///////////////////////////
unsigned long lastMsg = 0;
char randNumber;
// // Define NTP Client to get time
// WiFiUDP ntpUDP;
// NTPClient timeClient(ntpUDP, "pool.ntp.org");
////////////////////////////////////////////////
//////////////////////////////////
void setup() {
Serial.begin(115200);
pinMode(CS, OUTPUT);
// pinMode(LED, OUTPUT);
// pinMode(STATE, OUTPUT);
// digitalWrite(STATE, LOW);
bool commscheck = ade9153A.SPI_Init(SPI_SPEED, CS); //Initialize SPI
if (!commscheck) {
Serial.println("ADE9153A Shield not detected. Plug in Shield and reset the Arduino");
while (!commscheck) { //Hold until arduino is reset
delay(1000);
}
}
// WiFi.begin(ssid, password);
// while (WiFi.status() != WL_CONNECTED) {
// delay(500);
// Serial.println("Connecting to WiFi..");
// }
// Serial.println("Connected to the WiFi network");
// // Set offset time in seconds to adjust for your timezone, for example:
// // GMT +1 = 3600
// // GMT +8 = 28800
// // GMT -1 = -3600
// // GMT 0 = 0
// timeClient.begin();
// timeClient.setTimeOffset(19800);
// mqttClient.setServer(mqtt_broker, mqtt_port);
// client.setCallback(callback);
// mqttReconnect();
// client.subscribe(topic);
// setupWifi();
connectToWifi();
setupMqtt();
setupRelay();
setupTime();
}
void loop() {
// if (!client.connected()) {
// mqttReconnect();
// }
if(!mqttClient.connected()){
connectToBroker();
}
mqttClient.loop();
unsigned long currentReport = millis();
readandwrite();
checkScheduleON();
checkScheduleOFF();
delay(2000);
}
void readandwrite()
{
// rmsVals.CurrentRMSValue = ade9153A.SPI_Read_32(REG_AIRMS);
// rmsVals.VoltageRMSValue = ade9153A.SPI_Read_32(REG_AVRMS);
// powerVals.ActivePowerValue = ade9153A.SPI_Read_32(REG_AWATT);
// powerVals.FundReactivePowerValue = ade9153A.SPI_Read_32(REG_AFVAR);
// powerVals.ApparentPowerValue = ade9153A.SPI_Read_32(REG_AVA);
ade9153A.ReadPowerRegs(&powerVals);
ade9153A.ReadRMSRegs(&rmsVals);
Serial.print("RMS Current:\t");
Serial.print(rmsVals.CurrentRMSValue/1000);
Serial.println(" A");
Serial.print("RMS Voltage:\t");
Serial.print(rmsVals.VoltageRMSValue/1000);
Serial.println(" V");
Serial.print("Active Power:\t");
Serial.print(powerVals.ActivePowerValue/1000);
Serial.println(" W");
Serial.print("Reactive Power:\t");
Serial.print(powerVals.FundReactivePowerValue/1000);
Serial.println(" VAR");
Serial.print("Apparent Power:\t");
Serial.print(powerVals.ApparentPowerValue/1000);
Serial.println(" VA");
Serial.println("");
Serial.println("");
timeClient.update();
time_t epochTime = timeClient.getEpochTime();
//Get a time structure
struct tm *ptm = gmtime ((time_t *)&epochTime);
int currentYear = ptm->tm_year+1900;
int currentMonth = ptm->tm_mon+1;
int monthDay = ptm->tm_mday;
String formattedTime = timeClient.getFormattedTime();
char month_str[4];
sprintf(month_str,"%02d",currentMonth);
String currentDate = String(currentYear) + "-" + month_str + "-" + String(monthDay)+" "+ String(formattedTime);
DynamicJsonDocument doc(200);
doc["deviceId"] = "0001";
doc["time_stamp"] = currentDate;
doc["state"] = digitalRead(STATE);
doc["energy"] = String((powerVals.ActivePowerValue)/1000,2);
doc["durationInSeconds"] = "1";
doc["voltage"] = String((rmsVals.VoltageRMSValue)/1000,2);
doc["current"] = String((rmsVals.CurrentRMSValue)/1000,2);
doc["var"] = String((powerVals.FundReactivePowerValue)/1000,2);
doc["kva"] = String((powerVals.ApparentPowerValue)/1000,2);
doc["valid"] = 1;
serializeJson(doc, buffer);
mqttClient.publish("SPM-DATA", buffer);
}
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message and subscribe arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char) payload[i]);
}
if ((char) payload[0] == '1'){
digitalWrite(STATE,HIGH);
digitalWrite(LED,HIGH);
} else {
digitalWrite(STATE,LOW);
digitalWrite(LED,LOW);
}
Serial.println();
Serial.println("-----------------------");
}
// void mqttReconnect() {
// while (!client.connected()) {
// String client_id = "esp32-client-moko";
// client_id += String(WiFi.macAddress());
// Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
// if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
// Serial.println("Public broker connected");
// } else {
// Serial.print("failed with state ");
// Serial.print(client.state());
// delay(2000);
// }
// }
// }