DHT22 возвращает неверные показания при отрицательной температуре
Нижеследующий код читает показания DHT22 на заданном параметром пине. При опущении температуры ниже 0 °C данный код возвращает неадекватные значения в диапазоне от -3200 до -3300 (чаще всего значения колеблются около -3275). При использовании библиотеки значения также неверны. Код используется отсюда.
#pragma once
#include <Arduino.h>
#include <Firmata.h>
uint64_t readingTime;
void DHTt(const uint8_t pin) {
if ((millis() - readingTime) > 2000) {
unsigned char receivedDHTData[5];
float temperature, humidity;
#define DHT_PORT PORTD
#define DHT_DDR DDRD
#define DHT_PIN PIND
#define DHT_BIT pin
int count = 32;
unsigned char i,j;
ReLoad: //метка для ошибок
//=============MCU send START
DHT_DDR|=(1<<DHT_BIT); //выход
DHT_PORT&=~(1<<DHT_BIT); //низкий уровень, подтягиваем линию, разбудим датчик
delay(18); //18 мс по условиям документации.
DHT_PORT|=(1<<DHT_BIT); //отпускаем линию
DHT_DDR&=~(1<<DHT_BIT); //пин как выход
//============= инциализация DHT
delayMicroseconds(50); //задержка по условию
if (DHT_PIN&(1<<DHT_BIT)) { //датчик должен ответить 0
if (count != 0) {
goto ReLoad;
count--;
} else {
Firmata.sendString("ERR;DHTt;INIT");
return;
}
}
delayMicroseconds(80);
if (!(DHT_PIN&(1<<DHT_BIT))) { //по истечению 80 мкс, датчик должен отпустить шину
if (count != 0) {
goto ReLoad;
count--;
} else {
Firmata.sendString("ERR;DHTt;BHVR");
return;
}
}
//===============Приём 40 бит данных
while (DHT_PIN&(1<<DHT_BIT)); //ждем пока на шине появится 1
for (j=0; j<5; j++) { //цикл для 0-4 байт
receivedDHTData[j]=0;
for(i=0; i<8; i++) { //приём битов и укладка их в байты
while (!(DHT_PIN&(1<<DHT_BIT))); //ждем когда датчик отпустит шину
delayMicroseconds(30); //задержка высокого уровня при 0 30 мкс
if (DHT_PIN&(1<<DHT_BIT)) //если по истечению времени сигнал на линии высокий, значит передается 1
receivedDHTData[j]|=1<<(7-i); //тогда i-й бит устанавливаем 1
while (DHT_PIN&(1<<DHT_BIT)); //ждем окончание 1
}
}
if ((unsigned char)(receivedDHTData[0] + receivedDHTData[1] +
receivedDHTData[2] + receivedDHTData[3])!=receivedDHTData[4]) { //checksum
Firmata.sendString("ERR;DHTt;CHSM");
return;
}
temperature = (receivedDHTData [3]*0.1) + ((receivedDHTData [2] & 0b01111111)*25.6); //нюанс расчета температуры для DHT22
if (receivedDHTData [2] & 0b10000000) temperature*= -1; //если отрицательная температура
humidity = (receivedDHTData [1]*0.1) + (receivedDHTData [0]*25.6); //нюанс расчета влажности для DHT22
char result[32], catres[8];
readingTime = millis();
strcpy(result, "OK;DHTt;");
dtostrf(temperature, 5, 2, catres);
strcat(result, catres);
strcat(result, ";");
dtostrf(humidity, 5, 2, catres);
strcat(result, catres);
Firmata.sendString(result);
return;
}
}