-
Notifications
You must be signed in to change notification settings - Fork 59
Description
Consider the sketch
#include <SimpleDHT.h>
int pinDHT22 = 2;
SimpleDHT22 dht22(pinDHT22);
void setup() { Serial.begin(9600); }
void loop() {
Serial.println("=================================");
Serial.println("Sample DHT22...");
float temperature = 0;
float humidity = 0;
int err = SimpleDHTErrSuccess;
if((err=dht22.read2(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("Read DHT22 failed, err=");
Serial.println(err);
delay(2000);
return;
}
Serial.print("Sample OK: ");
Serial.print((float)temperature);
Serial.print(" *C, ");
Serial.print((float)humidity);
Serial.println(" RH%");
delay(2500); // DHT22 sampling rate is 0.5HZ.
}And a DHT22 connected to D2 of an Arduino Uno, together with +5V and GND.
The sketch will work without a problem.
Now change Serial.begin(9600); to Serial.begin(115200);. It was observed by a user that this has a readout error rate of nearly 100%.
The two Serial.println() with long string data just before the dht22.read2() call will cause only the string data to be copied into a buffer and the first byte to be transmitted. Then, the UART interrupt will fire, interrupt the MCU, and the interrupt service routine will load the next byte from the buffer into the UART peripheral, and the code execution will continue from where it was originally interrupt.
At 115200 baud and this string data length, the timing is so perfect that the UART interrupt fires when the dht22.read2() function is in the middle of being executed, always messing up the I/O bitbanging. Giving the user a near 100% error rate.
Other libraries like the Adafruit DHT sensor library will correctly disable interrupts during the timing critical I/O bitbanging code.
This library does not use noInterrupts() and similiar. Hence, if anything in the firmware causes the dht22.read2() function to be interrupted at just the right moment for the right amount of time, the DHT22 reading will not work.
I qualify this as a bug in the library. It should be made resistant against it.
The bug was further confirmed by placing a
Serial.flush();before the dht22.read2() call, as to not cause UART interrupts during the DHT22 reading. The error rate recovered.