I have connected a DHT11 sensor to a nano atmega 328.
Note that I also use an interrupt driven routine to maintain a real-time-clock. Measuring the DHT11 pulses that are just a few microseconds, I had a lot of trouble with time-outs and correct data, as the RTC clock routine interfered with the microsecond time measurement.
I fixed this by syncing the DHT11 code to a point in time where the interrupt routine really does not do anything (things happen at second roll-over in the RTC routine).
Now that I have fixed this, I still get checksum errors, which appear temperature dependent. I added debug code, and for instance found that when temp=10C, the sensor often sends 00000001 for temp byte, completely leaving bit 3 at zero (temp byte should be 00001001). The checksum is actually correct for what the temperature byte should have been.
Has anybody seen this? Seems the sensor is (somewhat) broken - a data dependent malfunction?
I only have one DHT11, so I cannot easily try another…
int dht11::read(int pin)
{
// BUFFER TO RECEIVE
uint8_t bits[5]; // 5 * 8 = 40 bits total
uint8_t cnt = 7;
uint8_t idx = 0;
int kk;
// EMPTY receive BUFFER
for (int kk=0; kk< 5; kk++) bits[kk] = 0;
// REQUEST reading from sensor
my_sync=false; //reset sync flag
while (my_sync==false) delayMicroseconds(3); //synchronize with real time clock interrrupt routine
pinMode(pin, OUTPUT); // the sensor data pin is BIDI!!
delayMicroseconds(100); // do not immediately write after pin changed to output... caused check errors when at 10C!
digitalWrite(pin, LOW);
delayMicroseconds(10000); // cannot exceed 16000.... so split in two calls
delayMicroseconds(8000);
digitalWrite(pin, HIGH);
delayMicroseconds(15);
pinMode(pin, INPUT); // change to receive data, wait for sensor data now
// ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
// READ OUTPUT, 40 BITS => 5 BYTES or TIMEOUT
// each bit starts with 50uS low, a 0 is sent with 27uS high, a 1 is sent with 70uS high:
//
// \______/------------\ one bit of 40
// 50uS 27 or 70uS
//
for (int kk=0; kk<40; kk++) //receive 40 bits total
{
loopCnt = 10000;
while(digitalRead(pin) == LOW) // is has to go low for this protocol
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
loopCnt = 10000;
while(digitalRead(pin) == HIGH) {
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
}
if ((10000-loopCnt)>10) bits[idx] |= (1 << cnt); // either 2..5 iterations (bit=0), or 13..16 iterations (bit=1)
if (cnt == 0) // next byte?
{
cnt = 7; // restart at MSB
idx++; // next byte!
}
else cnt--;
}
// WRITE TO RIGHT VARS
// as bits[1] and bits[3] are allways zero they are omitted in formulas.
uint8_t sum = bits[0] + bits[2];
if (deb_flag & (bits[4] != sum)){
Serial.print(FcurTime(str));Serial.print(" CHK: ");
for ( kk=0; kk<5; kk++){
itoa(bits[kk],str,2);
Serial.print(str);Serial.print(" ");
}
Serial.println(".");
}
if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
humidity = bits[0]; //byte 0
temperature = bits[2]; //byte 2
return DHTLIB_OK;
}