Arduino trying to get DHT senosors to work

This commit is contained in:
Ziver Koc 2016-05-29 22:23:29 +02:00
parent 5fd432ee4c
commit eff019c012
7 changed files with 196 additions and 120 deletions

View file

@ -3,7 +3,7 @@
#define ENABLE_DEBUG // comment out to disable debug
#define TIMER_MILLISECOND 60*1000 // poling in minutes
#define TIMER_MILLISECOND 10*1000 // poling in minutes
#define INDICATOR_PIN 13 // diod
// POWER CONSUMPTION SENSOR
@ -14,7 +14,7 @@
// TEMPERATURE SENSOR
#define TEMPERATURE_ENABLED // comment out to disable sensor
#define TEMPERATURE_SENSOR SensorDHT11(10)
#define TEMPERATURE_SENSOR SensorDHT(DHT22, 10)
#define TEMPERATURE_PROTOCOL ProtocolOregon(11, 100)
#define TEMPERATURE_TIMER_MULTIPLIER 1

View file

@ -3,7 +3,7 @@
/////// SENSORS
#include "SensorBH1750.h"
#include "SensorDHT11.h"
#include "SensorDHT.h"
#include "SensorPhotocell.h"
//////// PROTOCOLS

View file

@ -69,7 +69,7 @@ public:
struct TemperatureData
{
float temperature;
short humidity;
float humidity;
};
class SensorTemperature : public Sensor
{

View file

@ -0,0 +1,159 @@
/* DHT library
MIT license
written by Adafruit Industries
*/
// Modified by Ziver Koc
//
#include "SensorDHT.h"
void SensorDHT::setup()
{
// set up the pins!
pinMode(_pin, INPUT_PULLUP);
_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for
// reading pulses from DHT sensor.
}
// Expect the signal line to be at the specified level for a period of time and
// return a count of loop cycles spent at that level (this cycle count can be
// used to compare the relative time of two pulses). If more than a millisecond
// ellapses without the level changing then the call fails with a 0 response.
// This is adapted from Arduino's pulseInLong function (which is only available
// in the very latest IDE versions):
// https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
uint32_t SensorDHT::expectPulse(bool level) {
uint32_t count = 0;
// On AVR platforms use direct GPIO port access as it's much faster and better
// for catching pulses that are 10's of microseconds in length:
#ifdef __AVR
uint8_t portState = level ? _bit : 0;
while ((*portInputRegister(_port) & _bit) == portState) {
if (count++ >= _maxcycles) {
return 0; // Exceeded timeout, fail.
}
}
// Otherwise fall back to using digitalRead (this seems to be necessary on ESP8266
// right now, perhaps bugs in direct port access functions?).
#else
while (digitalRead(_pin) == level) {
if (count++ >= _maxcycles) {
return 0; // Exceeded timeout, fail.
}
}
#endif
return count;
}
void SensorDHT::read(TemperatureData& retData)
{
// Reset 40 bits of received data to zero.
static uint8_t data[5];
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// Send start signal. See DHT datasheet for full signal diagram:
// http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
// Go into high impedence state to let pull-up raise data line level and
// start the reading process.
digitalWrite(_pin, HIGH);
delay(250);
// First set data line low for 20 milliseconds.
pinMode(_pin, OUTPUT);
digitalWrite(_pin, LOW);
delay(20);
uint32_t cycles[80];
{
// Turn off interrupts temporarily because the next sections are timing critical
// and we don't want any interruptions.
noInterrupts();
// End the start signal by setting data line high for 40 microseconds.
digitalWrite(_pin, HIGH);
delayMicroseconds(40);
// Now start reading the data line to get the value from the DHT sensor.
pinMode(_pin, INPUT_PULLUP);
delayMicroseconds(10); // Delay a bit to let sensor pull data line low.
// First expect a low signal for ~80 microseconds followed by a high signal
// for ~80 microseconds again.
if (expectPulse(LOW) == 0) {
DEBUG("DHT:Timeout waiting for start signal low pulse.");
return;
}
if (expectPulse(HIGH) == 0) {
DEBUG("DHT:Timeout waiting for start signal high pulse.");
return;
}
// Now read the 40 bits sent by the sensor. Each bit is sent as a 50
// microsecond low pulse followed by a variable length high pulse. If the
// high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
// then it's a 1. We measure the cycle count of the initial 50us low pulse
// and use that to compare to the cycle count of the high pulse to determine
// if the bit is a 0 (high state cycle count < low state cycle count), or a
// 1 (high state cycle count > low state cycle count). Note that for speed all
// the pulses are read into a array and then examined in a later step.
for (int i=0; i<80; i+=2) {
cycles[i] = expectPulse(LOW);
cycles[i+1] = expectPulse(HIGH);
}
interrupts();
} // Timing critical code is now complete.
// Inspect pulses and determine which ones are 0 (high state cycle count < low
// state cycle count), or 1 (high state cycle count > low state cycle count).
for (int i=0; i<40; ++i) {
uint32_t lowCycles = cycles[2*i];
uint32_t highCycles = cycles[2*i+1];
if ((lowCycles == 0) || (highCycles == 0)) {
DEBUG("DHT:Timeout waiting for pulse.");
return;
}
data[i/8] <<= 1;
// Now compare the low and high cycle times to see if the bit is a 0 or 1.
if (highCycles > lowCycles) {
// High cycles are greater than 50us low cycle count, must be a 1.
data[i/8] |= 1;
}
// Else high cycles are less than (or equal to, a weird case) the 50us low
// cycle count so this must be a zero. Nothing needs to be changed in the
// stored data.
}
// Check we read 40 bits and that the checksum matches.
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
switch (_type) {
case DHT11:
retData.temperature = data[2];
retData.humidity = data[0];
break;
case DHT22:
case DHT21:
retData.temperature = data[2] & 0x7F;
retData.temperature *= 256;
retData.temperature += data[3];
retData.temperature *= 0.1;
if (data[2] & 0x80) {
retData.temperature *= -1;
}
retData.humidity = data[0];
retData.humidity *= 256;
retData.humidity += data[1];
retData.humidity *= 0.1;
break;
}
}
else {
DEBUG("DHT:Checksum failure!");
}
}

View file

@ -0,0 +1,33 @@
#ifndef SensorDHT_h
#define SensorDHT_h
#include <Arduino.h>
#include "HalInterfaces.h"
// Define types of sensors.
#define DHT11 11
#define DHT22 22
#define DHT21 21
class SensorDHT : public SensorTemperature
{
public:
SensorDHT(uint8_t type, uint8_t pin) : _type(type), _pin(pin) {};
virtual void setup();
virtual void read(TemperatureData& data);
private:
uint8_t _type, _pin;
uint32_t _maxcycles;
#ifdef __AVR
// Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask
// for the digital pin connected to the DHT. Other platforms will use digitalRead.
uint8_t _bit, _port;
#endif
uint32_t expectPulse(bool level);
};
#endif

View file

@ -1,97 +0,0 @@
//
// FILE: dht11.cpp
// VERSION: 0.3.2
// PURPOSE: DHT11 Temperature & Humidity Sensor library for Arduino
// LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html)
//
// DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf
//
// HISTORY:
// George Hadjikyriacou - Original version (??)
// Mod by SimKard - Version 0.2 (24/11/2010)
// Mod by Rob Tillaart - Version 0.3 (28/03/2011)
// + added comments
// + removed all non DHT11 specific code
// + added references
// Refactored by Ziver Koc
//
#include "SensorDHT11.h"
void SensorDHT11::setup(){}
void SensorDHT11::read(TemperatureData& data)
{
// BUFFER TO RECEIVE
uint8_t bits[5] = {0};
uint8_t cnt = 7;
uint8_t idx = 0;
// REQUEST SAMPLE
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delay(18);
digitalWrite(pin, HIGH);
delayMicroseconds(40);
pinMode(pin, INPUT);
// ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0)
{
DEBUG("DHT11 timeout");
return;;
}
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0)
{
DEBUG("DHT11 timeout");
return;;
}
// READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
for (int i=0; i<40; i++)
{
loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0)
{
DEBUG("DHT11 timeout");
return;;
}
unsigned long t = micros();
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0)
{
DEBUG("DHT11 timeout");
return;;
}
if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
if (cnt == 0) // next byte?
{
cnt = 7; // restart at MSB
idx++; // next byte!
}
else cnt--;
}
uint8_t sum = bits[0] + bits[2];
if (bits[4] != sum)
DEBUG("DHT11 checksum error");
// WRITE TO RIGHT VARS
// as bits[1] and bits[3] are allways zero they are omitted in formulas.
data.temperature = bits[2];
data.humidity = bits[0];
}

View file

@ -1,19 +0,0 @@
#ifndef SensorDHT11_h
#define SensorDHT11_h
#include <Arduino.h>
#include "HalInterfaces.h"
class SensorDHT11 : public SensorTemperature
{
public:
SensorDHT11(short pin) : pin(pin) {};
virtual void setup();
virtual void read(TemperatureData& data);
private:
short pin;
};
#endif