#include "MessageQueue.h"
// Instantiate the three queues for decoupled communication
SystemQueue actuationQueue; // Sensor -> Actuation (Priority Data)
SystemQueue uartQueue; // Actuation -> UART (Broadcast for Remote)
SystemQueue monitorQueue; // Actuation -> Monitor (Broadcast for Local Display)
// Pin for Actuation (e.g., a warning light or relay)
const int WARNING_PIN = 8;
// --- Task 1: Sensor Producer (Generates Mock Data) ---
void sensor_producer_task() {
static unsigned long lastReadTime = 0;
const long READ_INTERVAL = 50; // Read sensors fast: 50ms
if (millis() - lastReadTime >= READ_INTERVAL) {
lastReadTime = millis();
SystemData data;
// Mock data generation for varied parameters:
// Temp: 20.0 to 35.0 C (simulated float)
data.temperature = (float)random(200, 350) / 10.0;
// Humidity: 40.0 to 90.0 % (simulated float)
data.humidity = (float)random(400, 900) / 10.0;
// Pressure: 900 to 1100 hPa (simulated integer)
data.pressure = random(900, 1100);
// Light: 0 to 1023 (simulated analog)
data.lightLevel = random(0, 1024);
// Door Status: 10% chance of being TRUE (open)
data.doorStatus = (random(0, 100) < 10);
// Motion: 5% chance of being TRUE (detected)
data.motionDetected = (random(0, 100) < 5);
data.timestamp = millis();
// Send data ONLY to the central Actuation Task
if (!actuationQueue.send(data)) {
// This indicates the Actuation task is not keeping up!
Serial.println("-> SENSOR: Actuation Queue FULL! Dropping data.");
}
}
}
// --- Task 2: Actuation (Intelligence Center) ---
void actuation_task_processor() {
SystemData currentData;
// Check if the priority data queue has a new message
if (actuationQueue.receive(currentData)) {
// --- DUMMY ACTUATION LOGIC / STATE MACHINE ---
bool warningCondition = false;
// Logic 1: High Temperature Warning
if (currentData.temperature > 32.0) {
warningCondition = true;
Serial.println("ACTUATION: Warning! High Temperature.");
}
// Logic 2: Security Breach Check
if (currentData.doorStatus || currentData.motionDetected) {
warningCondition = true;
Serial.println("ACTUATION: Warning! Security Event.");
}
// Apply physical actuation based on system state
digitalWrite(WARNING_PIN, warningCondition ? HIGH : LOW);
// --- BROADCAST TO CONSUMERS ---
// Send to UART and Monitor queues (broadcast)
uartQueue.send(currentData);
monitorQueue.send(currentData);
}
}
// --- Task 3: UART Consumer (Slow Remote Communication) ---
void uart_consumer_task() {
static unsigned long lastSendTime = 0;
const long SEND_RATE = 2000; // Only send data every 2 seconds
if (millis() - lastSendTime >= SEND_RATE) {
SystemData data;
// Check the UART queue for the latest data from Actuation
if (uartQueue.receive(data)) {
Serial.print("-> UART: Sent @");
Serial.print(data.timestamp);
Serial.print(" | Temp: ");
Serial.print(data.temperature);
Serial.print(" | Door: ");
Serial.println(data.doorStatus ? "OPEN" : "CLOSED");
lastSendTime = millis();
}
}
}
// --- Task 4: Monitor Consumer (Slow Local Display) ---
void monitor_consumer_task() {
SystemData data;
// Consumes data as fast as Actuation produces it
if (monitorQueue.receive(data)) {
// This simulates a local display update for the user (e.g., an LCD)
Serial.print("-> MONITOR: Hum=");
Serial.print(data.humidity);
Serial.print("%, Light=");
Serial.println(data.lightLevel);
}
}
// ====================================================================
void setup() {
Serial.begin(115200);
Serial.println("--- Decoupled System Initialized ---");
randomSeed(analogRead(A0));
pinMode(WARNING_PIN, OUTPUT);
digitalWrite(WARNING_PIN, LOW);
}
void loop() {
// 1. Run high-speed data collection
sensor_producer_task();
// 2. Run the central logic
actuation_task_processor();
// 3. Run the slow consumers
uart_consumer_task();
monitor_consumer_task();
// All tasks run non-blocking checks in every loop cycle, ensuring responsiveness.
}