Correct negative results in DHT driver (#3210)
* DHT module: fix the handling of negative temps. The macro handling the conversion from the 2 bytes buffer to a double was handling negative values by checking the sign bit and taking the negative value of the number minus the sign bit. Unfortunately this does not work as the negative values are represented in 1's complement, so for instance -1 was becoming -32767 * +1 = b0000_0000_0000_ 0001 * -1 = 1111_1111_1111_1111 This replace the spacial code with a signed 16 bits value. * Refactoring: removes some code duplication. * Fixed the conversion of the 8/16 bits values Co-authored-by: Marco Dondero <marco@dondero.eu>
This commit is contained in:
parent
2fa63a1303
commit
bf15299cea
|
@ -40,13 +40,21 @@
|
||||||
#define HIGH 1
|
#define HIGH 1
|
||||||
#endif /* ifndef HIGH */
|
#endif /* ifndef HIGH */
|
||||||
|
|
||||||
#define COMBINE_HIGH_AND_LOW_BYTE(byte_high, byte_low) (((byte_high) << 8) | (byte_low))
|
|
||||||
|
|
||||||
static double dht_humidity;
|
static double dht_humidity;
|
||||||
static double dht_temperature;
|
static double dht_temperature;
|
||||||
|
|
||||||
static uint8_t dht_bytes[5]; // buffer to receive data
|
static uint8_t dht_bytes[5]; // buffer to receive data
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Humidity = 0,
|
||||||
|
Temperature,
|
||||||
|
Humidity8,
|
||||||
|
Temperature8
|
||||||
|
} dht_Signal;
|
||||||
|
|
||||||
static int dht_readSensor(uint8_t pin, uint8_t wakeupDelay);
|
static int dht_readSensor(uint8_t pin, uint8_t wakeupDelay);
|
||||||
|
static double getValue(dht_Signal s);
|
||||||
|
static bool verifyChecksum();
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -91,19 +99,17 @@ int dht_read_universal(uint8_t pin)
|
||||||
#endif // defined(DHT_DEBUG_BYTES)
|
#endif // defined(DHT_DEBUG_BYTES)
|
||||||
|
|
||||||
// Assume it is DHT11
|
// Assume it is DHT11
|
||||||
// If it is DHT11, both bit[1] and bit[3] is 0
|
// If it is DHT11, both temp and humidity's decimal
|
||||||
if ((dht_bytes[1] == 0) && (dht_bytes[3] == 0))
|
if ((dht_bytes[1] == 0) && (dht_bytes[3] == 0))
|
||||||
{
|
{
|
||||||
// It may DHT11
|
// It may DHT11
|
||||||
// CONVERT AND STORE
|
// CONVERT AND STORE
|
||||||
DHT_DEBUG("DHT11 method\n");
|
DHT_DEBUG("DHT11 method\n");
|
||||||
dht_humidity = dht_bytes[0]; // dht_bytes[1] == 0;
|
dht_humidity = getValue(Humidity8);
|
||||||
dht_temperature = dht_bytes[2]; // dht_bytes[3] == 0;
|
dht_temperature = getValue(Temperature8);
|
||||||
|
|
||||||
// TEST CHECKSUM
|
// TEST CHECKSUM
|
||||||
// dht_bytes[1] && dht_bytes[3] both 0
|
if (!verifyChecksum())
|
||||||
uint8_t sum = dht_bytes[0] + dht_bytes[2];
|
|
||||||
if (dht_bytes[4] != sum)
|
|
||||||
{
|
{
|
||||||
// It may not DHT11
|
// It may not DHT11
|
||||||
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
|
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
|
||||||
|
@ -119,16 +125,11 @@ int dht_read_universal(uint8_t pin)
|
||||||
// Assume it is not DHT11
|
// Assume it is not DHT11
|
||||||
// CONVERT AND STORE
|
// CONVERT AND STORE
|
||||||
DHT_DEBUG("DHTxx method\n");
|
DHT_DEBUG("DHTxx method\n");
|
||||||
dht_humidity = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[0], dht_bytes[1]) * 0.1;
|
dht_humidity = getValue(Humidity);
|
||||||
dht_temperature = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[2] & 0x7F, dht_bytes[3]) * 0.1;
|
dht_temperature = getValue(Temperature);
|
||||||
if (dht_bytes[2] & 0x80) // negative dht_temperature
|
|
||||||
{
|
|
||||||
dht_temperature = -dht_temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TEST CHECKSUM
|
// TEST CHECKSUM
|
||||||
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
|
if (!verifyChecksum())
|
||||||
if (dht_bytes[4] != sum)
|
|
||||||
{
|
{
|
||||||
return DHTLIB_ERROR_CHECKSUM;
|
return DHTLIB_ERROR_CHECKSUM;
|
||||||
}
|
}
|
||||||
|
@ -151,13 +152,11 @@ int dht_read11(uint8_t pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONVERT AND STORE
|
// CONVERT AND STORE
|
||||||
dht_humidity = dht_bytes[0]; // dht_bytes[1] == 0;
|
dht_humidity = getValue(Humidity8);
|
||||||
dht_temperature = dht_bytes[2]; // dht_bytes[3] == 0;
|
dht_temperature = getValue(Temperature8);
|
||||||
|
|
||||||
// TEST CHECKSUM
|
// TEST CHECKSUM
|
||||||
// dht_bytes[1] && dht_bytes[3] both 0
|
if (!verifyChecksum()) return DHTLIB_ERROR_CHECKSUM;
|
||||||
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
|
|
||||||
if (dht_bytes[4] != sum) return DHTLIB_ERROR_CHECKSUM;
|
|
||||||
|
|
||||||
return DHTLIB_OK;
|
return DHTLIB_OK;
|
||||||
}
|
}
|
||||||
|
@ -179,16 +178,11 @@ int dht_read(uint8_t pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONVERT AND STORE
|
// CONVERT AND STORE
|
||||||
dht_humidity = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[0], dht_bytes[1]) * 0.1;
|
dht_humidity = getValue(Humidity);
|
||||||
dht_temperature = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[2] & 0x7F, dht_bytes[3]) * 0.1;
|
dht_temperature = getValue(Temperature);
|
||||||
if (dht_bytes[2] & 0x80) // negative dht_temperature
|
|
||||||
{
|
|
||||||
dht_temperature = -dht_temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TEST CHECKSUM
|
// TEST CHECKSUM
|
||||||
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
|
if (!verifyChecksum())
|
||||||
if (dht_bytes[4] != sum)
|
|
||||||
{
|
{
|
||||||
return DHTLIB_ERROR_CHECKSUM;
|
return DHTLIB_ERROR_CHECKSUM;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +236,7 @@ int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
|
||||||
// volatile uint8_t *PIR = portInputRegister(port);
|
// volatile uint8_t *PIR = portInputRegister(port);
|
||||||
|
|
||||||
// EMPTY BUFFER
|
// EMPTY BUFFER
|
||||||
for (i = 0; i < 5; i++) dht_bytes[i] = 0;
|
memset(dht_bytes, sizeof(uint8_t)*5, 0);
|
||||||
|
|
||||||
// REQUEST SAMPLE
|
// REQUEST SAMPLE
|
||||||
// pinMode(pin, OUTPUT);
|
// pinMode(pin, OUTPUT);
|
||||||
|
@ -314,6 +308,33 @@ int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
|
||||||
|
|
||||||
return DHTLIB_OK;
|
return DHTLIB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assembles the high and low byte in a signed 16bit value
|
||||||
|
static double getValue(dht_Signal s)
|
||||||
|
{
|
||||||
|
uint8_t high=0, low=0;
|
||||||
|
|
||||||
|
// the '8' variants leave the low byte set to 0
|
||||||
|
switch(s){
|
||||||
|
case Humidity:
|
||||||
|
low = dht_bytes[1];
|
||||||
|
case Humidity8:
|
||||||
|
high = dht_bytes[0];
|
||||||
|
break;
|
||||||
|
case Temperature:
|
||||||
|
low = dht_bytes[3];
|
||||||
|
case Temperature8:
|
||||||
|
high = dht_bytes[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ((high << 8) | low) * 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool verifyChecksum(){
|
||||||
|
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
|
||||||
|
return (dht_bytes[4] == sum);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// END OF FILE
|
// END OF FILE
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue