#include #define DHT_LIB_VERSION "0.1.14" #define DHTLIB_OK 0 #define DHTLIB_ERROR_CHECKSUM -1 #define DHTLIB_ERROR_TIMEOUT -2 #define DHTLIB_INVALID_VALUE -999 #define DHTLIB_DHT11_WAKEUP 18 #define DHTLIB_DHT_WAKEUP 1 // max timeout is 100 usec. // For a 16 Mhz proc 100 usec is 1600 clock cycles // loops using DHTLIB_TIMEOUT use at least 4 clock cycli // so 100 us takes max 400 loops // so by dividing F_CPU by 40000 we "fail" as fast as possible #define DHTLIB_TIMEOUT (F_CPU/40000) double humidity; double temperature; uint8_t bits[5]; void setup() { Serial.begin(9600); } void loop() { // READ VALUES int rv = readSensor(13, DHTLIB_DHT11_WAKEUP); if (rv != DHTLIB_OK) { Serial.print("ERROR "); Serial.println(rv); } // CONVERT AND STORE humidity = bits[0]; // bits[1] == 0; temperature = bits[2]; // bits[3] == 0; // TEST CHECKSUM // bits[1] && bits[3] both 0 uint8_t sum = bits[0] + bits[2]; if (bits[4] != sum){ Serial.print("ERROR "); Serial.println(DHTLIB_ERROR_CHECKSUM); }else{ Serial.print(int2bin(bits[0])); Serial.print(" "); Serial.print(int2bin(bits[1])); Serial.print(" "); Serial.print(int2bin(bits[2])); Serial.print(" "); Serial.print(int2bin(bits[3])); Serial.println(""); } delay(3000); } int readSensor(uint8_t pin, uint8_t wakeupDelay) { // INIT BUFFERVAR TO RECEIVE DATA uint8_t mask = 128; uint8_t idx = 0; // replace digitalRead() with Direct Port Reads. // reduces footprint ~100 bytes => portability issue? // direct port read is about 3x faster uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); volatile uint8_t *PIR = portInputRegister(port); // EMPTY BUFFER for (uint8_t i = 0; i < 5; i++) bits[i] = 0; // REQUEST SAMPLE pinMode(pin, OUTPUT); 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; while ((*PIR & bit) != LOW ) { if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT; } if ((micros() - t) > 40) { bits[idx] |= mask; } mask >>= 1; if (mask == 0) // next byte? { mask = 128; idx++; } } pinMode(pin, OUTPUT); digitalWrite(pin, HIGH); return DHTLIB_OK; } char * int2bin(uint8_t i) { size_t bits = 8; char * str = malloc(bits + 1); if(!str) return NULL; str[bits] = 0; // type punning because signed shift is implementation-defined unsigned u = *(unsigned *)&i; for(; bits--; u >>= 1) str[bits] = u & 1 ? '1' : '0'; return str; }