+ reduced # micros calls 2->1 in inner loop. => footprint -18

detection of the zero/one is doen by measuring the whole bit LOW+HIGH
+ improved wait for acknowledge
+ merged two loopCounters into one.
+ layout
+ dht22_test sketch collects statistics (every 20 reads)
This commit is contained in:
rob tillaart 2014-10-08 16:37:30 +02:00
parent e4ad65003b
commit fa681d5322
3 changed files with 90 additions and 41 deletions

View File

@ -1,11 +1,12 @@
//
// FILE: dht.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.14
// VERSION: 0.1.15
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
// URL: http://arduino.cc/playground/Main/DHTLib
//
// HISTORY:
// 0.1.15 reduced # micros calls 2->1 in inner loop.
// 0.1.14 replace digital read with faster (~3x) code => more robust low MHz machines.
// 0.1.13 fix negative temperature
// 0.1.12 support DHT33 and DHT44 initial version
@ -44,8 +45,8 @@ int dht::read11(uint8_t pin)
int rv = _readSensor(pin, DHTLIB_DHT11_WAKEUP);
if (rv != DHTLIB_OK)
{
humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
temperature = DHTLIB_INVALID_VALUE; // invalid value
humidity = DHTLIB_INVALID_VALUE;
temperature = DHTLIB_INVALID_VALUE;
return rv;
}
@ -56,8 +57,10 @@ int dht::read11(uint8_t pin)
// TEST CHECKSUM
// bits[1] && bits[3] both 0
uint8_t sum = bits[0] + bits[2];
if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
if (bits[4] != sum)
{
return DHTLIB_ERROR_CHECKSUM;
}
return DHTLIB_OK;
}
@ -123,49 +126,63 @@ int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay)
digitalWrite(pin, LOW); // T-be
delay(wakeupDelay);
digitalWrite(pin, HIGH); // T-go
delayMicroseconds(40);
pinMode(pin, INPUT);
// GET ACKNOWLEDGE or TIMEOUT
uint16_t loopCntLOW = DHTLIB_TIMEOUT;
while ((*PIR & bit) == LOW ) // T-rel
{
if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT;
}
uint16_t loopCntHIGH = DHTLIB_TIMEOUT;
while ((*PIR & bit) != LOW ) // T-reh
{
if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
}
// READ THE OUTPUT - 40 BITS => 5 BYTES
for (uint8_t i = 40; i != 0; i--)
{
loopCntLOW = DHTLIB_TIMEOUT;
while ((*PIR & bit) == LOW )
{
if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT;
}
uint32_t t = micros();
loopCntHIGH = DHTLIB_TIMEOUT;
uint16_t loopCount = DHTLIB_TIMEOUT*2; // 200uSec max
// while(digitalRead(pin) == HIGH)
while ((*PIR & bit) != LOW )
{
if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT;
}
if ((micros() - t) > 40)
// GET ACKNOWLEDGE or TIMEOUT
loopCount = DHTLIB_TIMEOUT;
// while(digitalRead(pin) == LOW)
while ((*PIR & bit) == LOW ) // T-rel
{
if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT;
}
loopCount = DHTLIB_TIMEOUT;
// while(digitalRead(pin) == HIGH)
while ((*PIR & bit) != LOW ) // T-reh
{
if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT;
}
uint8_t state = LOW;
uint8_t pstate = LOW;
loopCount = DHTLIB_TIMEOUT;
uint32_t t1 = micros();
// READ THE OUTPUT - 40 BITS => 5 BYTES
for (uint8_t i = 40; i != 0; )
{
// WAIT FOR FALLING EDGE
state = (*PIR & bit);
if (state == LOW && pstate != LOW)
{
uint32_t t2 = micros();
if ((t2-t1) > 100 ) // long -> one
{
bits[idx] |= mask;
}
mask >>= 1;
if (mask == 0) // next byte?
if (mask == 0) // next byte
{
mask = 128;
idx++;
}
// next bit
--i;
// update time admin
t1 = t2;
// reset timeout flag
loopCount = DHTLIB_TIMEOUT;
}
pstate = state;
// Check timeout
if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT;
}
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);

View File

@ -1,7 +1,7 @@
//
// FILE: dht.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.14
// VERSION: 0.1.15
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
// URL: http://arduino.cc/playground/Main/DHTLib
//
@ -18,7 +18,7 @@
#include <Arduino.h>
#endif
#define DHT_LIB_VERSION "0.1.14"
#define DHT_LIB_VERSION "0.1.15"
#define DHTLIB_OK 0
#define DHTLIB_ERROR_CHECKSUM -1

View File

@ -1,9 +1,13 @@
//
// FILE: dht22_test.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.01
// VERSION: 0.1.02
// PURPOSE: DHT library test sketch for DHT22 && Arduino
// URL:
// HISTORY:
// 0.1.02 added counters for error-regression testing.
// 0.1.01
// 0.1.00 initial version
//
// Released to the public domain
//
@ -14,10 +18,19 @@ dht DHT;
#define DHT22_PIN 5
struct
{
uint32_t total;
uint32_t ok;
uint32_t crc_error;
uint32_t time_out;
uint32_t unknown;
} stat = { 0,0,0,0,0 };
void setup()
{
Serial.begin(115200);
Serial.println("DHT TEST PROGRAM ");
Serial.println("dht22_test.ino");
Serial.print("LIBRARY VERSION: ");
Serial.println(DHT_LIB_VERSION);
Serial.println();
@ -33,18 +46,23 @@ void loop()
int chk = DHT.read22(DHT22_PIN);
uint32_t stop = micros();
stat.total++;
switch (chk)
{
case DHTLIB_OK:
stat.ok++;
Serial.print("OK,\t");
break;
case DHTLIB_ERROR_CHECKSUM:
stat.crc_error++;
Serial.print("Checksum error,\t");
break;
case DHTLIB_ERROR_TIMEOUT:
stat.time_out++;
Serial.print("Time out error,\t");
break;
default:
stat.unknown++;
Serial.print("Unknown error,\t");
break;
}
@ -56,6 +74,20 @@ void loop()
Serial.print(stop - start);
Serial.println();
if (stat.total % 20 == 0)
{
Serial.println("\nTOT\tOK\tCRC\tTO\tUNK");
Serial.print(stat.total);
Serial.print("\t");
Serial.print(stat.ok);
Serial.print("\t");
Serial.print(stat.crc_error);
Serial.print("\t");
Serial.print(stat.time_out);
Serial.print("\t");
Serial.print(stat.unknown);
Serial.println("\n");
}
delay(2000);
}
//