#include <PubSubClient.h> //library for MQTT
#include <WiFi.h> //library for WiFi
#include "cJSON.h" //library for parsing json
const char *WIFI_SSID = "Wokwi-GUEST";
const char *WIFI_PWD = "";
const int ID = 4; //Identifier of the device
const int TotalDevices = 4;
#define clientId "iot-polimi-actuator-4"
#define MQTT_TOPIC "polimi/project3/2023/10606435"
const char *MQTT_SERVER = "broker.hivemq.com";
const uint16_t MQTT_PORT = 1883;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
#define LED 12
#define C_TIME 100
volatile int pmw_value = 0; //variable used for set the luminosity
volatile int control = 0; //variable used to esabilish if the payload is a message or a number
hw_timer_t *My_timer = NULL;
//FUnciton for the PMW
void IRAM_ATTR onTimer(){
bool led_status = digitalRead(LED);
if (led_status && pmw_value != C_TIME){
digitalWrite(LED, !led_status);
timerWrite(My_timer, pmw_value);
}
else if(!led_status && pmw_value !=0){
digitalWrite(LED, !led_status);
timerWrite(My_timer, C_TIME-pmw_value);
}
}
char msg[100]; // to store the payload
char capmsg[100]; // to store the message for the response in the CAP.
char *endPtr; // string to numeric value
int msgIndex = 0;
int frameDuration_value = 0;
void CallbackPan(char* topic, byte* payload, unsigned int length)
{
msgIndex = 0;
//Store the paylaod
for (int i = 0; i < length; i++)
{
msg[msgIndex] = payload[i];
msgIndex++;
}
Serial.println(msg);
const char* json_string = msg;
// Parse the JSON string
cJSON* root = cJSON_Parse(json_string);
control = strtof(msg, &endPtr);
// Check if parsing was successful
if (*endPtr != '\0' && root == NULL) {
//It's not a json
memset(msg, 0, sizeof(msg));
}
else if (*endPtr != '\0') {
//It's a json
// Extract individual variables using cJSON_GetObjectItem
cJSON* frameDuration = cJSON_GetObjectItem(root, "FrameDuration");
cJSON* cap = cJSON_GetObjectItem(root, "CAP");
cJSON* cfp = cJSON_GetObjectItem(root, "CFP");
cJSON* info = cJSON_GetObjectItem(root, "Info");
cJSON* bi = cJSON_GetObjectItem(root, "BI");
memset(msg, 0, sizeof(msg)); //Erase the payload
// Check if variables were extracted successfully
if (frameDuration && cap && cfp && info && bi) {
printf("FrameDuration: %s\n", frameDuration->valuestring);
printf("CAP: %s\n", cap->valuestring);
printf("CFP: %s\n", cfp->valuestring);
printf("Info: %s\n", info->valuestring);
printf("BI: %s\n", bi->valuestring);
memset(msg, 0, sizeof(msg)); //Erase the payload
int i ; //Convert to int
int cap_value = atoi(cap->valuestring); //Convert to int
int cfp_value = atoi(cfp->valuestring); //Convert to int
frameDuration_value = atoi( frameDuration->valuestring); //Convert to int
sprintf(capmsg, "%s connected in CAP!", clientId);
mqttClient.publish(MQTT_TOPIC, capmsg); // Send connection message
Serial.println(capmsg);
delay(cap_value); // Wait for the CFP
printf("CAP FINISHED.\n");}
delay(frameDuration_value*(ID-1)); // Wait for the first assigned slot
}else{
// It's a numeric value
pmw_value = strtof(msg, &endPtr); //change the pmw value
memset(msg, 0, sizeof(msg)); //Erase the payload
sprintf(msg, "Client ID: %s Led ON", clientId);
Serial.println(msg);
mqttClient.publish(MQTT_TOPIC, msg); //Publish the status
memset(msg, 0, sizeof(msg)); //Erase the msg
delay(frameDuration_value*(TotalDevices-1));
}
}
void SetupPan()
{
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
// set the callback function
mqttClient.setCallback(CallbackPan);
}
void ConnectToPan()
{
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected())
{
Serial.println(clientId);
if (mqttClient.connect(clientId))
{
Serial.println("Connected to MQTT broker.");
// subscribe to topic
mqttClient.subscribe(MQTT_TOPIC);
}
}
}
void ConnectToWiFi()
{
Serial.print("Connecting to WiFi ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PWD, 6);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.print("\nConnected to ");
Serial.println(WIFI_SSID);
}
void setup()
{
Serial.begin(115200);
Serial.println("Setup begin");
pinMode(LED, OUTPUT);
ConnectToWiFi();
SetupPan();
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &onTimer, true);
timerAlarmWrite(My_timer, C_TIME, true);
timerAlarmEnable(My_timer);
Serial.println("Setup end");
}
void loop()
{
if (!mqttClient.connected())
{
ConnectToPan();
}
mqttClient.loop();
}