#include <DHTesp.h>
#include <WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/************************* WiFi Access Point ***************************/
#define WLAN_SSID "Wokwi-GUEST"
#define WLAN_PASS ""
/************************* Adafruit.io Setup ***************************/
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME "r9drigo"
#define AIO_KEY "aio_fYfZ06Ip8TeMijRVfAPWO12h4OlD"
#define AIO_FEED_1 "/feeds/rtos.temperature"
#define AIO_FEED_2 "/feeds/rtos.humidity"
#define AIO_FEED_3 "/feeds/rtos.level"
// Wifi and MQTT
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);
// Publishers
Adafruit_MQTT_Publish tempPublish = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_1);
Adafruit_MQTT_Publish humiPublish = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_2);
Adafruit_MQTT_Publish nivelPublish = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME AIO_FEED_3);
// Settings
static const uint16_t timer_divider = 80; // Count at 1 MHz
static const uint64_t timer_max_count = 1000000;
// Pins
static const int dht_pin = 14;
static const int pot_pin = 12;
static const int btn_pin = 2;
struct sensor {
int N_Lei;
float Lei_Temp;
float Lei_Umi;
float Lei_Nivel;
};
TaskHandle_t myTaskHandle = NULL;
TaskHandle_t myTaskHandle2 = NULL;
QueueHandle_t queue;
EventGroupHandle_t evt;
DHTesp dhtSensor;
#define USUA_EV (1<<0)
#define RELO_EV (1<<1)
static hw_timer_t *timer = NULL;
static volatile uint16_t temp;
static volatile uint16_t umi;
static volatile uint16_t nivel;
static SemaphoreHandle_t mutex;
void wifiSetup() {
// Connect to WiFi access point.
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS, 6);
while (WiFi.status() != WL_CONNECTED) {
vTaskDelay(500 / portTICK_PERIOD_MS);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi Connected!");
}
void mqttSetup() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 10 seconds...");
mqtt.disconnect();
vTaskDelay(10000 / portTICK_PERIOD_MS);
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}
//*****************************************************************************
// Interrupt Service Routines (ISRs)
// This function executes when timer reaches max (and resets)
void IRAM_ATTR onTimer() {
xEventGroupSetBits(evt, RELO_EV);
}
void ISRCallback() {
xEventGroupSetBits(evt, USUA_EV);
}
//*****************************************************************************
// Tasks
void Coleta (void *pvParameters) {
queue = xQueueCreate(5, sizeof(struct sensor));
if (queue == 0) {
printf("Failed to create queue= %p\n", queue);
}
struct sensor mySensor;
Serial.println("Fila criada para anotar os dados!");
while (1) {
//xSemaphoreTake(mutex, portMAX_DELAY);
for(int i = 0; i<5; i++){
TempAndHumidity data = dhtSensor.getTempAndHumidity();
mySensor.Lei_Temp = data.temperature;
mySensor.Lei_Umi = data.humidity;
mySensor.Lei_Nivel = analogRead(pot_pin);
Serial.println(analogRead(pot_pin));
Serial.println("Coleta realizada!");
xQueueSend(queue, &mySensor, portMAX_DELAY);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
//xSemaphoreGive(mutex);
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
void Cont_Temp (void *pvParameters) {
while (1) {
TempAndHumidity data = dhtSensor.getTempAndHumidity();
temp = data.temperature;
if (temp>=60) {
Serial.println("----------------------");
Serial.print("A Temperatura está em: ");
Serial.println(temp);
Serial.println("Abaixando Temperatura");
Serial.println("----------------------");
vTaskDelay(10 / portTICK_PERIOD_MS);
} else if (temp < 10) {
Serial.println("----------------------");
Serial.print("A Temperatura está em: ");
Serial.println(temp);
Serial.println("Aumentando Temperatura");
Serial.println("----------------------");
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void Cont_Nivel (void *pvParameters) {
while (1) {
nivel = analogRead(pot_pin);
if (nivel < 1024){
Serial.println("----------------------");
Serial.print("O Nível está em: ");
Serial.println(nivel);
Serial.println("Abrindo válvula para aumentar o Nivel");
Serial.println("----------------------");
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void Envia (void *arg) {
const EventBits_t xBitsToWaitFor = (RELO_EV | USUA_EV);
EventBits_t x;
struct sensor dados;
while(1){
//Serial.println("--- To em Envia");
x = xEventGroupWaitBits(evt, xBitsToWaitFor, pdTRUE, pdTRUE, pdMS_TO_TICKS(1000));
if ((x & RELO_EV) != 0 || (x & USUA_EV) != 0) {
if (uxQueueSpacesAvailable (queue) == 0) {
mqttSetup();
xSemaphoreTake(mutex, portMAX_DELAY);
for(int i = 0; i<5; i++){
xQueueReceive(queue, &dados, portMAX_DELAY);
Serial.print("------- Envio dos Dados ------- ");
Serial.println(i);
Serial.print("Temperatura: ");
Serial.println(dados.Lei_Temp);
if (!(dados.Lei_Temp != dados.Lei_Temp) && i == 1) tempPublish.publish(dados.Lei_Temp);
Serial.print("Umidade: ");
Serial.println(dados.Lei_Umi);
if (!(dados.Lei_Umi != dados.Lei_Umi) && i == 1) humiPublish.publish(dados.Lei_Umi);
Serial.print("Nivel: ");
Serial.println(dados.Lei_Nivel);
if (!(dados.Lei_Nivel != dados.Lei_Nivel) && i == 1) nivelPublish.publish(dados.Lei_Nivel);
Serial.println("----------------");
vTaskDelay(500/ portTICK_RATE_MS);
}
xSemaphoreGive(mutex);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
}
}
void setup() {
Serial.begin(115200);
evt = xEventGroupCreate();
// Wait a moment to start (so we don't miss Serial output)
vTaskDelay(1000 / portTICK_PERIOD_MS);
Serial.println();
Serial.println("--- Projeto Final IoT ---");
Serial.println();
pinMode(btn_pin, INPUT_PULLUP);
dhtSensor.setup(dht_pin, DHTesp::DHT22);
wifiSetup();
mutex = xSemaphoreCreateMutex();
xSemaphoreGive(mutex);
// Criação das tarefas com mesmo nível de prioridade e tamanho
xTaskCreatePinnedToCore(Coleta, "Coleta", 1024, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(Cont_Temp, "Cont_Temp", 1024, NULL, 3, NULL, 1);
xTaskCreatePinnedToCore(Cont_Nivel, "Cont_Nivel", 1024, NULL, 3, NULL, 1);
xTaskCreatePinnedToCore(Envia, "Envia", 2048, NULL, 1, NULL, 0);
// Create and start timer (num, divider, countUp)
timer = timerBegin(0, timer_divider, true);
// Provide ISR to timer (timer, function, edge)
timerAttachInterrupt(timer, &onTimer, true);
// At what count should ISR trigger (timer, count, autoreload)
timerAlarmWrite(timer, timer_max_count, true);
// Allow ISR to trigger
timerAlarmEnable(timer);
}
void loop() {
// Vazio
}