// Learn about the ESP32 WiFi simulation in
#include <TimeLib.h>
#include <DHT.h>
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include "P.h"
SemaphoreHandle_t xSerialSem;
QueueHandle_t xFila;
SemaphoreHandle_t xSerialSem2;
TaskHandle_t Task1;
TaskHandle_t Task2;
TaskHandle_t Task3;
TaskHandle_t Task4;
TaskHandle_t Task5;
// LED pins
const int led1 = 2;
const int led2 = 4;
int connected = 0;
DHT dht(12, DHT22);
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 0
#define UTC_OFFSET_DST 0
#define SPEAKER_PIN 5
int tamFila = 200;
void setup()
{
Serial.begin(115200);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(SPEAKER_PIN, OUTPUT);
// Cria o semáforo na memória
if (xSerialSem == NULL)
{
xSerialSem = xSemaphoreCreateMutex();
if (xSerialSem != NULL)
xSemaphoreGive(xSerialSem);
}
// Cria o semáforo na memória
if (xSerialSem2 == NULL)
{
xSerialSem2 = xSemaphoreCreateMutex();
if (xSerialSem2 != NULL)
xSemaphoreGive(xSerialSem2);
}
xFila = xQueueCreate( tamFila, sizeof( String ) );
if(xFila == NULL){
Serial.println("Erro criando fila");
}
LCD.init();
LCD.backlight();
// create a task that will be executed in the Task1code() function,
// with priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
// create a task that will be executed in the Task2code() function
// with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task2code, /* Task function. */
"Task2", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task2, /* Task handle to keep track of created task */
0); /* pin task to core 1 */
// create a task that will be executed in the Task2code() function
// with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task3code, /* Task function. */
"Task3", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task3, /* Task handle to keep track of created task */
1); /* pin task to core 1 */
// create a task that will be executed in the Task2code() function
// with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task4code, /* Task function. */
"Task4", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task4, /* Task handle to keep track of created task */
1); /* pin task to core 1 */
// create a task that will be executed in the Task2code() function
// with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task5code, /* Task function. */
"Task5", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task5, /* Task handle to keep track of created task */
0); /* pin task to core 1 */
}
// Task1code: blinks an LED every 1000 ms
void Task1code(void *pvParameters)
{
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
for (;;)
{
digitalWrite(led1, HIGH);
vTaskDelay(1000);
digitalWrite(led1, LOW);
vTaskDelay(1000);
}
}
// Task2code: blinks an LED every 700 ms
void Task2code(void *pvParameters)
{
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());
for (;;)
{
digitalWrite(led2, HIGH);
vTaskDelay(700);
digitalWrite(led2, LOW);
vTaskDelay(700);
}
}
// Task3code:
void Task3code(void *pvParameters)
{
Serial.print("Task3 running on core ");
Serial.println(xPortGetCoreID());
for (;;)
{
if( connected == 1){
if (xSemaphoreTake(xSerialSem, (TickType_t)5 == pdTRUE)){
Serial.println("Task 3");
Serial.println("Temp: " + String(dht.readTemperature(), 1) + " \260C");
Serial.println("Hum: " + String(dht.readHumidity(), 1) + " %");
if (xSemaphoreTake(xSerialSem2, (TickType_t)10 == pdTRUE)){
String minhaString = String(dht.readTemperature(), 1) + " \260C";
xQueueSend(xFila, (void *)&minhaString, portMAX_DELAY);
xSemaphoreGive(xSerialSem2);
}
printLocalTime();
vTaskDelay(1000);
xSemaphoreGive(xSerialSem);
}
}else{
vTaskDelay(700);
}
}
}
// Task3code:
void Task4code(void *pvParameters)
{
Serial.print("Task4 running on core ");
Serial.println(xPortGetCoreID());
for (;;)
{
if( connected == 0){
if (xSemaphoreTake(xSerialSem, (TickType_t)5 == pdTRUE)){
Serial.println("Task 4");
LCD.setCursor(0, 0);
LCD.print("Connecting to ");
LCD.setCursor(0, 1);
LCD.print("WiFi ");
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED)
{
vTaskDelay(10);
spinner();
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Online");
LCD.setCursor(0, 1);
LCD.println("Updating time...");
connected = 1;
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
xSemaphoreGive(xSerialSem);
Serial.print("Status: ");
Serial.println(connected);
tone(SPEAKER_PIN, NOTE_E4);
vTaskDelay(150);
tone(SPEAKER_PIN, NOTE_G4);
vTaskDelay(150);
tone(SPEAKER_PIN, NOTE_E5);
vTaskDelay(150);
tone(SPEAKER_PIN, NOTE_C5);
vTaskDelay(150);
tone(SPEAKER_PIN, NOTE_D5);
vTaskDelay(150);
tone(SPEAKER_PIN, NOTE_G5);
vTaskDelay(150);
noTone(SPEAKER_PIN);
}
}
vTaskDelay(1000);
}
}
// Task5code: blinks an LED every 700 ms
void Task5code(void *pvParameters)
{
Serial.print("Task5 running on core ");
Serial.println(xPortGetCoreID());
for (;;)
{
if (xSemaphoreTake(xSerialSem2, (TickType_t)10 == pdTRUE)){
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
char buffer[50]; // Buffer para armazenar a hora formatada
char *formato = "%Y-%m-%d %H:%M:%S";
// Utilizar strftime para formatar a hora
strftime(buffer, sizeof(buffer), formato, &timeinfo);
// Imprimir a hora formatada no Serial
Serial.println(buffer);
}
Serial.println("Imprimindo e limpando a fila:");
while (uxQueueMessagesWaiting(xFila) > 0) {
String mensagem;
if (xQueueReceive(xFila, &mensagem, portMAX_DELAY) == pdPASS) {
Serial.print(mensagem);
Serial.print("|");;
}
}
Serial.println("Fila limpa!");
xSemaphoreGive(xSerialSem2);
}
vTaskDelay(15000);
}
}
void loop()
{
}
void spinner()
{
static int8_t counter = 0;
const char *glyphs = "\xa1\xa5\xdb";
LCD.setCursor(15, 1);
LCD.print(glyphs[counter++]);
if (counter == strlen(glyphs))
{
counter = 0;
}
}
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)){
LCD.setCursor(0, 1);
LCD.println("Connection Err");
connected = 0;
return;
}
LCD.setCursor(8, 0);
LCD.println(&timeinfo, "%H:%M:%S");
tone(SPEAKER_PIN, NOTE_G5);
vTaskDelay(10);
noTone(SPEAKER_PIN);
LCD.setCursor(0, 1);
LCD.println(&timeinfo, "%d/%m/%Y %Z");
}