#include <Arduino.h>
#include <WiFi.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <WokwiMQTT.h>
#include <EEPROM.h>
// WiFi Configuration
const char* ssid = "Wokwi_GUEST";
const char* password = "";
// MQTT Configuration
const char* mqtt_server = "your_MQTT_broker_IP";
const char* client_id = "your_client_id";
// LED Pins
const int led1Pin = 2;
const int led2Pin = 4;
const int led3Pin = 5;
// Button and Potentiometer Pins
const int button1Pin = 12;
const int button2Pin = 13;
const int potentiometerPin = 27;
// Task Handles
TaskHandle_t wifiTask;
TaskHandle_t mqttTask;
TaskHandle_t ledControlTask;
TaskHandle_t controlLoopTask;
// Global Variables
bool remoteLed1Status = false;
bool remoteLed2Status = false;
int analogFeedbackValue = 0;
// MQTT Client
WiFiClient espClient;
WokwiMQTT mqttClient (espClient);
// WiFi Task
void wifiTaskFunction(void* pvParameters) {
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
setupMQTT(); // Set up MQTT connection
xTaskCreatePinnedToCore(mqttTaskFunction, "mqttTask", 10000, NULL, 1, &mqttTask, 1);
xTaskCreatePinnedToCore(ledControlTaskFunction, "ledControlTask", 10000, NULL, 2, &ledControlTask, 1);
xTaskCreatePinnedToCore(controlLoopTaskFunction, "controlLoopTask", 10000, NULL, 3, &controlLoopTask, 1);
vTaskDelete(wifiTask);
}
// MQTT Task
void mqttTaskFunction(void* pvParameters) {
// Set up MQTT connection
mqttClient.begin(mqtt_server, 1883, espClient);
while (!mqttClient.connect(client_id, mqtt_username, mqtt_password)) {
Serial.println("Failed to connect to MQTT. Retrying...");
delay(1000);
}
Serial.println("Connected to MQTT");
// Subscribe to MQTT topics for remote LED control and analog feedback
mqttClient.subscribe("led/1/control");
mqttClient.subscribe("led/2/control");
mqttClient.subscribe("analog/feedback/control");
// Retrieve saved LED status from EEPROM
remoteLed1Status = EEPROM.read(0);
remoteLed2Status = EEPROM.read(1);
while (1) {
// Handle MQTT messages
mqttClient.loop();
// Publish local LED status to MQTT
mqttClient.publish("led/3/status", String(digitalRead(led3Pin)).c_str());
// Save LED status to EEPROM
EEPROM.write(0, remoteLed1Status);
EEPROM.write(1, remoteLed2Status);
EEPROM.commit();
// Delay for stability
delay(1000);
}
}
// LED Control Task
void ledControlTaskFunction(void* pvParameters) {
while (1) {
// Update local LED status based on remote control
digitalWrite(led1Pin, remoteLed1Status ? HIGH : LOW);
digitalWrite(led2Pin, remoteLed2Status ? HIGH : LOW);
// Delay for stability
delay(100);
}
}
// Control Loop Task
void controlLoopTaskFunction(void* pvParameters) {
while (1) {
// Read analog feedback value
analogFeedbackValue = analogRead(potentiometerPin);
// Perform closed-loop control based on feedback value
// Update led3Pin status accordingly
int threshold = 512; // Example threshold, adjust as needed
digitalWrite(led3Pin, (analogFeedbackValue > threshold) ? HIGH : LOW);
// Publish analog feedback value to MQTT
mqttClient.publish("analog/feedback/status", String(analogFeedbackValue).c_str());
// Delay for stability
delay(1000);
}
}
// MQTT Callback function for handling incoming messages
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String incomingTopic = String(topic);
String payloadStr = "";
for (int i = 0; i < length; i++) {
payloadStr += (char)payload[i];
}
// Update remote LED status or analog feedback value based on MQTT message
if (incomingTopic.equals("led/1/control")) {
remoteLed1Status = (payloadStr.toInt() == 1);
} else if (incomingTopic.equals("led/2/control")) {
remoteLed2Status = (payloadStr.toInt() == 1);
} else if (incomingTopic.equals("analog/feedback/control")) {
// Set the analog feedback value remotely (assuming payload is a valid integer)
analogFeedbackValue = payloadStr.toInt();
// Perform closed-loop control based on the received value
int threshold = 512; // Example threshold, adjust as needed
digitalWrite(led3Pin, (analogFeedbackValue > threshold) ? HIGH : LOW);
}
}
// Setup MQTT connection
void setupMQTT() {
mqttClient.onMessage(mqttCallback);
}
void setup() {
Serial.begin(115200);
// Initialize LED pins
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
// Initialize WiFi and connect
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Create WiFi task
xTaskCreatePinnedToCore(wifiTaskFunction, "wifiTask", 10000, NULL, 0, &wifiTask, 1);
}
void loop() {
// This loop is intentionally left empty
// All tasks are handled in FreeRTOS tasks
}