Arduino trying to get DHT senosors to work
This commit is contained in:
parent
5fd432ee4c
commit
eff019c012
7 changed files with 196 additions and 120 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/////// SENSORS
|
||||
#include "SensorBH1750.h"
|
||||
#include "SensorDHT11.h"
|
||||
#include "SensorDHT.h"
|
||||
#include "SensorPhotocell.h"
|
||||
|
||||
//////// PROTOCOLS
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public:
|
|||
struct TemperatureData
|
||||
{
|
||||
float temperature;
|
||||
short humidity;
|
||||
float humidity;
|
||||
};
|
||||
class SensorTemperature : public Sensor
|
||||
{
|
||||
|
|
|
|||
159
arduino/HalMultiSensor/SensorDHT.cpp
Executable file
159
arduino/HalMultiSensor/SensorDHT.cpp
Executable 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!");
|
||||
}
|
||||
}
|
||||
33
arduino/HalMultiSensor/SensorDHT.h
Executable file
33
arduino/HalMultiSensor/SensorDHT.h
Executable 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
|
||||
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue