#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
const char* MQTT_SERVER = "7c2ee808033a4bd288c1525d0c30fc34.s1.eu.hivemq.cloud";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "Benedict";
const char* MQTT_PASS = "Benedict1";
// Paste your full ROOT_CA certificate here
static const char* ROOT_CA = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)EOF";
const char* TOPIC_VOLTAGE = "microgrid/voltage";
const char* TOPIC_CURRENT = "microgrid/current";
const char* TOPIC_POWER = "microgrid/power";
const char* TOPIC_RPM = "microgrid/rpm";
const char* TOPIC_STATE = "microgrid/state";
#define VOLTAGE_PIN 34
#define CURRENT_PIN 35
#define RPM_PIN 27
#define RELAY_PIN 26
#define LED_GREEN 32
#define LED_YELLOW 33
#define LED_RED 25
float STRESS_V_MIN = 3.0;
float STRESS_P_MIN = 1.0;
float RPM_MIN = 50;
WiFiClientSecure secureClient;
PubSubClient client(secureClient);
volatile uint32_t pulses = 0;
float voltage,current,power,rpm;
unsigned long lastRPMTime=0;
unsigned long lastSend=0;
enum State{OPTIMAL,STRESSED,STOPPED};
State state=STOPPED;
void IRAM_ATTR rpmISR(){
pulses++;
}
void connectWiFi(){
WiFi.begin(WIFI_SSID,WIFI_PASS);
while(WiFi.status()!=WL_CONNECTED){
delay(300);
Serial.print(".");
}
Serial.println("\nWiFi Connected");
}
void connectMQTT(){
secureClient.setCACert(ROOT_CA);
client.setServer(MQTT_SERVER,MQTT_PORT);
while(!client.connected()){
Serial.println("Connecting MQTT...");
client.connect("microgrid-node",MQTT_USER,MQTT_PASS);
delay(500);
}
Serial.println("MQTT Connected");
}
void updateState(){
if(rpm<RPM_MIN) state=STOPPED;
else if(power<STRESS_P_MIN||voltage<STRESS_V_MIN) state=STRESSED;
else state=OPTIMAL;
}
void setup(){
Serial.begin(115200);
pinMode(RPM_PIN,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(RPM_PIN),rpmISR,FALLING);
pinMode(RELAY_PIN,OUTPUT);
pinMode(LED_GREEN,OUTPUT);
pinMode(LED_YELLOW,OUTPUT);
pinMode(LED_RED,OUTPUT);
connectWiFi();
connectMQTT();
}
void loop(){
if(!client.connected()) connectMQTT();
client.loop();
voltage=analogRead(VOLTAGE_PIN)*(3.3/4095.0)*4.0;
current=analogRead(CURRENT_PIN)*(3.3/4095.0)*2.0;
power=voltage*current;
if(millis()-lastRPMTime>=1000){
noInterrupts();
uint32_t count=pulses;
pulses=0;
interrupts();
rpm=count*60.0;
Serial.print("Pulse Count: ");
Serial.print(count);
Serial.print(" RPM: ");
Serial.println(rpm);
lastRPMTime=millis();
}
updateState();
digitalWrite(RELAY_PIN,state==OPTIMAL);
digitalWrite(LED_GREEN,state==OPTIMAL);
digitalWrite(LED_YELLOW,state==STRESSED);
digitalWrite(LED_RED,state==STOPPED);
if(millis()-lastSend>2000){
lastSend=millis();
client.publish(TOPIC_VOLTAGE,String(voltage).c_str());
client.publish(TOPIC_CURRENT,String(current).c_str());
client.publish(TOPIC_POWER,String(power).c_str());
client.publish(TOPIC_RPM,String(rpm).c_str());
const char* s=(state==OPTIMAL)?"OPTIMAL":(state==STRESSED)?"STRESSED":"STOPPED";
client.publish(TOPIC_STATE,s);
Serial.println("MQTT Published");
}
}