RANGEL SOARES SILVA
16/04/2023 23:42:43
Olá professor
Eu estava testando o serviço de email do IFTTT a fim de corrigir os emails com valores de temperatura e umidade zerados que eu estava recendo, por fim consegui corrigir, mas persiste uma dúvida com relação a execução das tasks.
Nesta ordem de posicionamento nas linhas em que a tarefa vTask_http vem primeiro que a tarefa vtask_dht então são executadas normalmente mas no email os valores chegam zerados repetidas vezes, então entendi através das mensagens no monitor serial que o email era enviado primeiro e que a leitura das variáveis era feita em seguida, o que pra mim não fez sentido, pois se são tasks executadas em paralelo não deveria ocorrer este erro.
/** * vTask_http; */ xTaskCreate(vTask_http, "vTask_http", 1024*8, NULL, 2, NULL); xTaskCreate(vtask_dht, "vtask_dht", 1024*5, NULL, 2, NULL);
Realizei então a inversão na ordem de criação das tasks e funcionou, então dei um limite de três emails para serem enviados, assim que eu os recebi verifiquei que em todos eles constava os valores das variáveis lidos
/** * vTask_http; */ xTaskCreate(vtask_dht, "vtask_dht", 1024*5, NULL, 2, NULL); xTaskCreate(vTask_http, "vTask_http", 1024*8, NULL, 2, NULL);
segue o código completo com a alteração citada anteriormente:
#include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" #include #include #include #include #include "dht.h" /* * WiFi; */ #define WIFISSID "Wokwi-GUEST" #define PASSWORD "" /* * ifttt.com; */ #define IFTTT_NAME_SERVICE "esp32_email" #define IFTTT_TOKEN "js9uH7rS07tWL2q8psZgnJeuRD-iSgsfDmFEQTkkLOl" static WiFiMulti wifiMulti; static SemaphoreHandle_t xSemaphore = NULL; int16_t temperature = 0; int16_t humidity = 0; /* * Função de inicialização da Serial e Oled; */ static void wifi_init( void ) { Serial.begin(115200); for(uint8_t t = 4; t > 0; t--) { Serial.printf("[SETUP] WAIT %d...\n", t); Serial.flush(); delay(500); } wifiMulti.addAP( WIFISSID, PASSWORD ); for(;;){ if(wifiMulti.run() != WL_CONNECTED) { Serial.println("WiFi not connected!"); delay(1000); } else {Serial.println("WiFi connected!"); break;} } } //----------------------------------------------- int temp; int umi; static int send_request(void) { char buffer[50] = {0,}; static int count = 0; /** * Verifica se o ESP32 está conectado a rede WiFi; */ if ((wifiMulti.run() == WL_CONNECTED)) //chaca se está conectada a rede wifi { Serial.println("[HTTP] begin..."); HTTPClient http; //retira o 's' de http para não requerir cert ificado http.begin("http://maker.ifttt.com/trigger/" IFTTT_NAME_SERVICE "/with/key/" IFTTT_TOKEN); //menságem formatada em json http.addHeader("HOST", "maker.ifttt.com"); //seleciona o tipo de serviço enviado http.addHeader("Content-type", "application/json"); //ao receber o resultado pode encerrar a conexão http.addHeader("Connection", "close"); //quando ocorrer o sucesso de tranmissão a variável count será incrementada //todos os caracteres especiais possuem uma barra antes para informar ao compilador que ele faz parte da string então usa-e '\' antes de cada aspa //snprintf(buffer, sizeof(buffer)-1, "{\"value1\": \"%d\"}", count); //o comprimento da mensagem muda snprintf(buffer, sizeof(buffer)-1, "{\"value1\": \"%dC\",\"value2\": \"%d\"}", temp, umi); int httpCode = http.POST(buffer); /** * Verifica se houve erro ou não durante o POST; */ if (httpCode > 0) //se for maios que 0 ele segue para verificar se foi com sucesso { Serial.print("[HTTP] Request Code="); Serial.println(httpCode); /** * Caso receba o código 200 é porque o POST foi realizado com sucesso. */ if (httpCode == HTTP_CODE_OK) { count++; /** * Esta função " http.getString()" só pode ser utilizada caso a mensagem recebida * tenha poucos bytes, pois ela faz o uso da função "reserve()" do Arduino, que por * ventura reserva bytes via Malloc. */ String payload = http.getString(); /** * Esta é outra função complicada do Arduino, pois para converter uma Objeto String * para uma "string da linguagem C" é necessário alocar dinamicamente todo o vetor * novamente. Portanto, payload tem que possuir poucos bytes. */ Serial.println(payload.c_str()); http.end(); //encerra o serviço socket após a requisição concluída, para uma nova requisição começa tudo de novo return 0; } } else { /** * Imprime os possíveis códigos de erros do http; */ Serial.println("[HTTP] POST... failed, error"); } /** * Encerra o socket; */ http.end(); } } //-------------------------- fim request -------------------------- static void vTask_http( void *pvParameters ) { char flag = 0; Serial.println( "vTask_http Init...\n" ); for (;;) { if(flag != 3) //realiza aprenas 3 envios de emails { send_request(); flag++; } /** * Realiza uma requisição POST a cada 10s */ vTaskDelay(10000/portTICK_PERIOD_MS); } } static const dht_sensor_type_t sensor_type = DHT_TYPE_AM2301;//DHT_TYPE_DHT11; static const gpio_num_t dht_gpio = (gpio_num_t)17; void vtask_dht(void *pvParameters) { gpio_set_pull_mode(dht_gpio, GPIO_PULLUP_ONLY); while (1) { if (dht_read_data(sensor_type, dht_gpio, &humidity, &temperature) == ESP_OK) { printf("Humidity: %d%% Temp: %dC\n", humidity / 10, temperature / 10); temp = temperature/10; umi = humidity/10; } else printf("Could not read data from sensor\n"); vTaskDelay(2000/portTICK_PERIOD_MS); } } void setup (void) { /** * Cria uma variável do tipo Mutex; */ xSemaphore = xSemaphoreCreateMutex(); /** * No FreeRTOS 9 e 10 os Semáforos iniciam em zero, portanto após sua alocação * convém, inicialmente, libera-lo. */ xSemaphoreGive( xSemaphore ); /** * Inicializa WiFi; */ wifi_init(); /** * vTask_http; */ xTaskCreate(vtask_dht, "vtask_dht", 1024*5, NULL, 2, NULL); xTaskCreate(vTask_http, "vTask_http", 1024*8, NULL, 2, NULL); } /** * Task loop; */ void loop (void) { vTaskDelay( 1000 / portTICK_PERIOD_MS ); }
O que pode está acontecendo com as tasks, as prioridades estão interferindo? Elas estão ou não sendo executadas em paralelo? Este é um caso para se usar o método do semáforo?