Dúvida no uso da função sprintf

Bug do sprintf?

Olá pessoal!!!

Gostaria de saber por que quando eu executo essa instrução:

sprintf(TempUmid,"%.1f,%.1f", TemperaturaLida,UmidadeLida);
comunicacaoESP.println(TempUmid); // envio do valor da temperatura para o módulo ESP
Serial.println(TempUmid);

Ela me retorna: - Temperatura: 27.70C

  • Umidade: 59.70%
    ?,?

por que está vindo ?,? e não a temperatura e a umidade juntas, tipo 27.7059.70?

Só para ficar mais claro é que eu estou fazendo uma estação remota de temperatura e umidade então eu preciso enviar a temperatura e a umidade juntas para o ESP8266, assim sendo, eu resolvi usar o sprintf para formatar e enviar os dados(temperatura e umidade) juntos. Abaixo está o código completo.

#include "DHT.h"
#include <SoftwareSerial.h> // Biblioteca SoftwareSerial

//defines gerais
#define DHTPIN 4 //pino do Arduino que está conectado ao pino de dados do sensor
#define DHTTYPE DHT22 //estabelece que o sensor utilizado é o DHT22 (é possível selecionar entre DHT11, DHT22 e DHT21)
#define TEMPO_LEITURA_SENSOR 10000 //tempo entre leituras de temperatura

//variáveis globais
DHT dht(DHTPIN, DHTTYPE); //objeto para comunicar com sensor de temperatura DHT22
SoftwareSerial comunicacaoESP(2, 3); // objeto para comunicação serial com o ESP8266 nas Portas 2(RX) e 3(TX)

//Função setup (inicializações do programa)
void setup()
{
Serial.begin(9600);
Serial.println("======Leitor de temperatura E umidade======");
comunicacaoESP.begin(9600); // inicia a comunicação serial com o ESP8266

//inicia a comunicação com o sensor DHT22
dht.begin();
}

//loop (programa principal)
void loop()
{
float TemperaturaLida;
float UmidadeLida;
char TempUmid[100];

//le a temperatura (em graus Celsius) e a umidade (em %)
TemperaturaLida = dht.readTemperature();
UmidadeLida = dht.readHumidity();
//checa se a leitura da temperatura foi bem sucedida ou não
if (isnan(TemperaturaLida) || isnan(UmidadeLida)){
Serial.println("- Falha ao ler a temperatura e a umidade medida pelo sensor DHT22");
comunicacaoESP.println('0'); // caso o valor seja nulo ou indefinido, o valor '0' é enviado para o ESP
}else
{
Serial.print("- Temperatura: ");
Serial.print(TemperaturaLida);
Serial.println("C");
Serial.print("- Umidade: ");
Serial.print(UmidadeLida);
Serial.println("%");

comunicacaoESP.println(TemperaturaLida); // envio do valor da temperatura para o módulo ESP
delay(10);
comunicacaoESP.println(UmidadeLida);

sprintf(TempUmid,"%.1f,%.1f", TemperaturaLida,UmidadeLida);
comunicacaoESP.println(TempUmid); // envio do valor da temperatura para o módulo ESP
Serial.println(TempUmid);
}

delay(TEMPO_LEITURA_SENSOR);
}

O sprintf usando float/double não está habilitado por padrão no Arduino, foi uma decisão dos desenvolvedores para reduzir o uso da memória flash, pois habilitar esta possibilidade consumia bastante.

Para contornar facilmente, use a função dtostrf.

No lugar de:

sprintf(TempUmid,"%.2f,%.2f", TemperaturaLida, UmidadeLida);

use:

dtostrf(TemperaturaLida,3,2,TempUmid);
TempUmid[strlen(TempUmid)] = ',';
dtostrf(UmidadeLida,3,2,&TempUmid[strlen(TempUmid)]);

Recomendo deixar a declaração da variável TempUmid exatamente antes de usá-la, diminui o escopo e acho que fica mais fácil achar problemas.
Não esqueça de inicializar a variável TempUmid utilizando o memset, pois pode dar problema ao usar print(...):

memset(TempUmid,0,sizeof(TempUmid));

Por que não inicializar já atribuindo?
Em vez de:

  float TemperaturaLida;
  float UmidadeLida;
  ...
  TemperaturaLida = dht.readTemperature();  
  UmidadeLida = dht.readHumidity();

use:

  float TemperaturaLida = dht.readTemperature();  
  float UmidadeLida = dht.readHumidity();

Código completo:

#include "DHT.h"
#include <SoftwareSerial.h> // Biblioteca SoftwareSerial

//defines gerais
#define DHTPIN                4      //pino do Arduino que está conectado ao pino de dados do sensor
#define DHTTYPE               DHT22  //estabelece que o sensor utilizado é o DHT22 (é possível selecionar entre DHT11, DHT22 e DHT21)
#define TEMPO_LEITURA_SENSOR  10000  //tempo entre leituras de temperatura

//variáveis globais
DHT dht(DHTPIN, DHTTYPE);   //objeto para comunicar com sensor de temperatura DHT22
SoftwareSerial comunicacaoESP(2, 3); // objeto para comunicação serial com o ESP8266 nas Portas 2(RX) e 3(TX)

//Função setup (inicializações do programa)
void setup()
{
    Serial.begin(9600);
    Serial.println("======Leitor de temperatura E umidade======");
    comunicacaoESP.begin(9600); // inicia a comunicação serial com o ESP8266

    //inicia a comunicação com o sensor DHT22
    dht.begin();
}

//loop (programa principal)
void loop()
{
    //le a temperatura (em graus Celsius) e a umidade (em %)
    float TemperaturaLida = dht.readTemperature();
    float UmidadeLida = dht.readHumidity();
    //checa se a leitura da temperatura foi bem sucedida ou não
    if (isnan(TemperaturaLida) || isnan(UmidadeLida)) {
        Serial.println("- Falha ao ler a temperatura e a umidade medida pelo sensor DHT22");
        comunicacaoESP.println('0'); // caso o valor seja nulo ou indefinido, o valor '0' é enviado para o ESP
    } else
    {
        Serial.print("- Temperatura: ");
        Serial.print(TemperaturaLida);
        Serial.println("C");
        Serial.print("- Umidade: ");
        Serial.print(UmidadeLida);
        Serial.println("%");

        comunicacaoESP.println(TemperaturaLida); // envio do valor da temperatura para o módulo ESP
        delay(10);
        comunicacaoESP.println(UmidadeLida);

        char TempUmid[100];
        memset(TempUmid, 0, sizeof(TempUmid));

        dtostrf(TemperaturaLida, 3, 2, TempUmid);
        TempUmid[strlen(TempUmid)] = ',';
        dtostrf(UmidadeLida, 3, 2, &TempUmid[strlen(TempUmid)]);

        comunicacaoESP.println(TempUmid); // envio do valor da temperatura para o módulo ESP
        Serial.println(TempUmid);
    }

    delay(TEMPO_LEITURA_SENSOR);

}
1 Like