Fórum

arrow_back

Execução das tasks

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?

Este site usa cookies para melhorar sua experiência. Política de Privacidade