#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Arduino_FreeRTOS.h>
#include <queue.h>
#include <semphr.h>
// Definições para o semáforo
SemaphoreHandle_t temperatureSemaphore;
// Definições para o sensor DS18B20
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Definições para o LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Definições para o Buzzer e o LED Azul
#define BUZZER_PIN 3
#define BLUE_LED_PIN 2
// Handles para as tarefas
TaskHandle_t buzzerTaskHandle;
TaskHandle_t blueLedTaskHandle;
TaskHandle_t timeAndTemperatureTaskHandle;
TaskHandle_t temperatureTaskHandle;
// Fila para troca de dados
#define TEMPERATURE_QUEUE_SIZE 5
QueueHandle_t temperatureQueue;
unsigned int elapsedSeconds = 0; // Contador de segundos
void setup() {
// Inicialização dos pinos do Buzzer e do LED Azul
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);
// Inicialização do sensor DS18B20
sensors.begin();
// Inicialização do LCD I2C
lcd.init();
lcd.backlight();
// Inicialização do semáforo
temperatureSemaphore = xSemaphoreCreateMutex();
// Inicialização da fila
temperatureQueue = xQueueCreate(TEMPERATURE_QUEUE_SIZE, sizeof(float));
// Criação das tarefas
xTaskCreate(buzzerTask, "BuzzerTask", 128, NULL, 1, &buzzerTaskHandle);
xTaskCreate(blueLedTask, "BlueLedTask", 128, NULL, 1, &blueLedTaskHandle);
xTaskCreate(timeAndTemperatureTask, "TimeAndTemperatureTask", 128, NULL, 1, &timeAndTemperatureTaskHandle);
xTaskCreate(temperatureTask, "TemperatureTask", 128, NULL, 1, &temperatureTaskHandle);
// Inicialização do FreeRTOS
vTaskStartScheduler();
}
void loop() {
// O loop não é usado no FreeRTOS
}
void buzzerTask(void *pvParameters) {
while (1) {
tone(BUZZER_PIN, 100); // Ativa o Buzzer
vTaskDelay(1000 / portTICK_PERIOD_MS); // Reduzido para 500 ms para fazer dois tons por segundo
noTone(BUZZER_PIN); // Desativa o Buzzer
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void blueLedTask(void *pvParameters) {
while (1) {
digitalWrite(BLUE_LED_PIN, HIGH);
vTaskDelay(1000 / portTICK_PERIOD_MS); // Mantido em 1 segundo
digitalWrite(BLUE_LED_PIN, LOW);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void timeAndTemperatureTask(void *pvParameters) {
float temperature;
while (1) {
if (xSemaphoreTake(temperatureSemaphore, (TickType_t)10) == pdTRUE) {
// Acesso seguro à fila
if (xQueueReceive(temperatureQueue, &temperature, portMAX_DELAY)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
// Exibindo elapsedSeconds no formato 000 a 999
lcd.print(elapsedSeconds / 100 % 10);
lcd.print(elapsedSeconds / 10 % 10);
lcd.print(elapsedSeconds % 10);
lcd.print(" s");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
vTaskDelay(1000 / portTICK_PERIOD_MS); // Aguarda 1 segundo
elapsedSeconds = (elapsedSeconds + 1) % 1000; // Incrementa elapsedSeconds e mantém no intervalo de 000 a 999
}
xSemaphoreGive(temperatureSemaphore); // Libera o semáforo após a operação
}
}
}
void temperatureTask(void *pvParameters) {
float temperature;
if (xSemaphoreTake(temperatureSemaphore, (TickType_t)10) == pdTRUE) {
// Acesso seguro à fila
xQueueReceive(temperatureQueue, &temperature, portMAX_DELAY);
xSemaphoreGive(temperatureSemaphore); // Libera o semáforo após a operação
}
while (1) {
sensors.requestTemperatures();
temperature = sensors.getTempCByIndex(0);
// Envia a temperatura para a fila
xQueueSend(temperatureQueue, &temperature, portMAX_DELAY);
vTaskDelay(1000 / portTICK_PERIOD_MS); // Aguarda 0.5 segundos
}
}