#include <stdio.h>
#include <stdbool.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_err.h>
#include "freertos/semphr.h"
#include "esp_system.h"
#include <string.h> //strlen
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include<driver/adc.h>
#include "cJSON.h"
#include "mqtt_client.h" //provides important functions to connect with MQTT
//#include "protocol_examples_common.h" //important for running different protocols in code
#include "esp_event.h" //managing events of mqtt
//PROTÓTIPO DE FUNÇÕES=====================================================================
void app_main(void);
void setup();
void task_get_temp(void *pvParameters);
void task_send_messages(void *pvParameters);
void wifi_connect(void);
static void mqtt_event_handler(esp_mqtt_event_handle_t event);
static void mqtt_initialize(void);
//DEFINIÇÕES E CONSTATNTES=================================================================
#define delay(value) vTaskDelay(value/portTICK_PERIOD_MS)
#define CAD_TEMP GPIO_NUM_35 //Interface CAD
#define SSID "Wokwi-GUEST"
#define PASSPHARSE ""
#define ALIVE "alive"
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
static const char *TAG="LOG_MQTT";
const float BETA = 3950; // should match the Beta Coefficient of the thermistor
//VARIÁVEIS==============================================================================
static TaskHandle_t xtask_handle_temp = NULL;
static TaskHandle_t xtask_handle_send_msg = NULL;
esp_mqtt_client_handle_t client;
float temp;
int analogValue;
SemaphoreHandle_t mutex;
//FUNÇÕES E TASKS=======================================================================
void wifi_connect() {
wifi_config_t cfg = {
.sta = {
.ssid = SSID,
.password = PASSPHARSE,
},
};
ESP_ERROR_CHECK(esp_wifi_disconnect());
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &cfg));
ESP_ERROR_CHECK(esp_wifi_connect());
}
static esp_err_t event_handler(void *ctx, system_event_t *event) {
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void) {
esp_log_level_set("wifi", ESP_LOG_NONE); // disable wifi driver logging
tcpip_adapter_init();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
void task_get_temp(void *pvParameters) {
while(1) {
xSemaphoreTake(mutex, portMAX_DELAY);// pega o Mutex
analogValue = adc1_get_raw(ADC1_CHANNEL_7);
temp = 1 / (log(1.0 / (1023. / (float)analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
printf("Temperatura: %f°C\n", temp);
vTaskResume(xtask_handle_send_msg); //reativa a task de send_msg
xSemaphoreGive(mutex); //libera o Mutex
delay(5000);
}
}
static void mqtt_event_handler(esp_mqtt_event_handle_t event){ //here esp_mqtt_event_handle_t is a struct which receieves struct event from mqtt app start funtion
esp_mqtt_client_handle_t client = event->client; //making obj client of struct esp_mqtt_client_handle_t and assigning it the receieved event client
if(event->event_id == MQTT_EVENT_CONNECTED) {
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
printf("conectado... mqtt\n");
}
else if(event->event_id == MQTT_EVENT_DISCONNECTED)
{
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); //if disconnected
}
else if(event->event_id == MQTT_EVENT_SUBSCRIBED)
{
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED");
}
else if(event->event_id == MQTT_EVENT_UNSUBSCRIBED) //when subscribed
{
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED");
}
else if(event->event_id == MQTT_EVENT_DATA)//when unsubscribed
{
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("Mensagem recebida -> %s\n", event->data);
}
else if(event->event_id == MQTT_EVENT_ERROR)//when any error
{
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
}
}
static void mqtt_initialize(void) {/*Depending on your website or cloud there could be more parameters in mqtt_cfg.*/
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
const esp_mqtt_client_config_t mqtt_cfg = {
.username= "adriano_soares:2fb6ef",
//.password= "temppwd",
.host= "200.129.71.138",//"broker.hivemq.com", //Uniform Resource Identifier includes path,protocol
.port = 1883,
.transport = MQTT_TRANSPORT_OVER_TCP,
.event_handle=mqtt_event_handler //described above event handler
};
client=esp_mqtt_client_init(&mqtt_cfg); //sending struct as a parameter in init client function
esp_mqtt_client_start(client); //starting the process
}
void task_send_messages(void *pvParameters) {
while(1) {
cJSON *json = cJSON_CreateObject();
cJSON_AddNumberToObject(json, "temperatura", temp);
char *json_str = cJSON_Print(json);
int msg_pub_id = esp_mqtt_client_publish(client, "adriano_soares:2fb6ef/attrs", json_str, 0, 0, 0);
printf("Enviando Temperatura -> %.2f°C\n", temp);
cJSON_free(json_str);
cJSON_Delete(json);
delay(50);
vTaskSuspend(NULL);
}
}
void setup() {
//inicia conversor A/D
adc1_config_width(ADC_WIDTH_BIT_10); // SENSOR require it
adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0);
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_event_group = xEventGroupCreate();
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
initialise_wifi();
xEventGroupWaitBits(wifi_event_group,CONNECTED_BIT,false,true,portMAX_DELAY);
mqtt_initialize();
}
void app_main() {
setup();
mutex = xSemaphoreCreateMutex();
xTaskCreate(&task_send_messages,"send messages",4096, NULL, 5, &xtask_handle_send_msg);
xTaskCreate(&task_get_temp, "task_temp", 4096, NULL, 5, &xtask_handle_temp);
}