#include <stdio.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "driver/adc.h"
// ================= PIN CONFIG =================
#define LDR_PIN ADC1_CHANNEL_6 // GPIO34
#define TEMP_PIN ADC1_CHANNEL_7 // GPIO35
#define LED_LAMP GPIO_NUM_2
#define LED_FAN GPIO_NUM_4
#define BUTTON_PIN GPIO_NUM_14
// ================= THRESHOLD =================
#define LIGHT_THRESHOLD 2000
#define TEMP_THRESHOLD 30.0
// ================= STRUCT =================
typedef struct {
int lightValue;
float temperature;
} SensorData;
// ================= RTOS OBJECT =================
QueueHandle_t sensorQueue;
SemaphoreHandle_t buttonSemaphore;
// ================= GLOBAL VARIABLE =================
bool manualOverride = false;
// ================= ISR BUTTON =================
void IRAM_ATTR buttonISR(void *arg) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(
buttonSemaphore,
&xHigherPriorityTaskWoken
);
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}
// ================= SENSOR TASK =================
void sensorTask(void *pvParameters) {
SensorData data;
while (1) {
// ===== READ LDR =====
int rawLight = adc1_get_raw(LDR_PIN);
// ===== READ POTENTIOMETER =====
int rawTemp = adc1_get_raw(TEMP_PIN);
// ===== CONVERT TO CELSIUS =====
// 0 - 4095 => 0 - 100 C
float temperatureC =
((float)rawTemp / 4095.0) * 100.0;
// ===== SAVE DATA =====
data.lightValue = rawLight;
data.temperature = temperatureC;
// ===== SEND TO QUEUE =====
xQueueSend(
sensorQueue,
&data,
portMAX_DELAY
);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
// ================= DECISION TASK =================
void decisionTask(void *pvParameters) {
SensorData receivedData;
while (1) {
if (xQueueReceive(
sensorQueue,
&receivedData,
portMAX_DELAY
)) {
printf("\n===== SENSOR DATA =====\n");
printf(
"Light ADC : %d\n",
receivedData.lightValue
);
printf(
"Temperature : %.2f C\n",
receivedData.temperature
);
// ================= LIGHT CONTROL =================
if (receivedData.lightValue
< LIGHT_THRESHOLD) {
gpio_set_level(LED_LAMP, 1);
printf(
"Condition : DARK -> Lamp ON\n"
);
} else {
gpio_set_level(LED_LAMP, 0);
printf(
"Condition : BRIGHT -> Lamp OFF\n"
);
}
// ================= FAN CONTROL =================
if (manualOverride) {
gpio_set_level(LED_FAN, 1);
printf(
"Manual Override -> Fan ON\n"
);
} else {
if (receivedData.temperature
> TEMP_THRESHOLD) {
gpio_set_level(LED_FAN, 1);
printf(
"Condition : HOT -> Fan ON\n"
);
} else {
gpio_set_level(LED_FAN, 0);
printf(
"Condition : NORMAL -> Fan OFF\n"
);
}
}
}
}
}
// ================= BUTTON TASK =================
void buttonTask(void *pvParameters) {
while (1) {
if (xSemaphoreTake(
buttonSemaphore,
portMAX_DELAY
)) {
manualOverride = !manualOverride;
printf(
"\n=== BUTTON PRESSED ===\n"
);
if (manualOverride) {
printf(
"Manual Override ENABLED\n"
);
} else {
printf(
"Manual Override DISABLED\n"
);
}
}
}
}
// ================= MAIN =================
void app_main() {
// ================= GPIO OUTPUT =================
gpio_set_direction(
LED_LAMP,
GPIO_MODE_OUTPUT
);
gpio_set_direction(
LED_FAN,
GPIO_MODE_OUTPUT
);
// ================= BUTTON INPUT =================
gpio_set_direction(
BUTTON_PIN,
GPIO_MODE_INPUT
);
gpio_pullup_en(BUTTON_PIN);
// ================= INTERRUPT =================
gpio_set_intr_type(
BUTTON_PIN,
GPIO_INTR_NEGEDGE
);
gpio_install_isr_service(0);
gpio_isr_handler_add(
BUTTON_PIN,
buttonISR,
NULL
);
// ================= ADC CONFIG =================
adc1_config_width(
ADC_WIDTH_BIT_12
);
adc1_config_channel_atten(
LDR_PIN,
ADC_ATTEN_DB_11
);
adc1_config_channel_atten(
TEMP_PIN,
ADC_ATTEN_DB_11
);
// ================= QUEUE =================
sensorQueue = xQueueCreate(
5,
sizeof(SensorData)
);
// ================= SEMAPHORE =================
buttonSemaphore =
xSemaphoreCreateBinary();
// ================= CREATE TASK =================
xTaskCreate(
sensorTask,
"Sensor Task",
2048,
NULL,
1,
NULL
);
xTaskCreate(
decisionTask,
"Decision Task",
4096,
NULL,
2,
NULL
);
xTaskCreate(
buttonTask,
"Button Task",
2048,
NULL,
3,
NULL
);
}