Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit version 0.3

  • Loading branch information...
commit 027d2de6116f6215e92d781b7f6e269b2d936099 0 parents
@nethoncho authored
233 DHT22.cpp
@@ -0,0 +1,233 @@
+/*
+ DHT22.cpp - DHT22 sensor library
+ Developed by Ben Adams - 2011
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Humidity and Temperature Sensor DHT22 info found at
+http://www.sparkfun.com/products/10167
+
+Version 0.3: 17-Jan-2011 by Ben Adams
+This version reads data
+Needs check sum code added at the end of readData
+
+Version 0.2: 16-Jan-2011 by Ben Adams
+Changed coding style to match other Arduino libraries.
+This version will not read data either!
+
+Version 0.1: 10-Jan-2011 by Ben Adams nethoncho AT gmail.com
+First Version is a skeleton. This version will not read data!
+Code adapted from the following sources:
+The Arduino OneWire lib
+http://sheepdogguides.com/arduino/ar3ne1humDHT11.htm
+
+*/
+
+#include "DHT22.h"
+#include "pins_arduino.h"
+
+extern "C" {
+#include "WConstants.h"
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+}
+
+#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask) ((*(base+1)) &= ~(mask))
+#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) |= (mask))
+#define DIRECT_WRITE_LOW(base, mask) ((*(base+2)) &= ~(mask))
+//#define DIRECT_WRITE_HIGH(base, mask) ((*(base+2)) |= (mask))
+
+// This should be 40, but the sensor is adding an extra bit at the start
+#define DHT22_DATA_BIT_COUNT 41
+
+DHT22::DHT22(uint8_t pin)
+{
+ _bitmask = digitalPinToBitMask(pin);
+ _baseReg = portInputRegister(digitalPinToPort(pin));
+ _lastReadTime = millis();
+ _lastHumidity = DHT22_ERROR_VALUE;
+ _lastTemperature = DHT22_ERROR_VALUE;
+}
+
+//
+// Read the 40 bit data stream from the DHT 22
+// Store the results in private member data to be read by public member functions
+//
+DHT22_ERROR_t DHT22::readData()
+{
+ uint8_t bitmask = _bitmask;
+ volatile uint8_t *reg asm("r30") = _baseReg;
+ uint8_t retryCount;
+ uint8_t bitTimes[DHT22_DATA_BIT_COUNT];
+ int currentHumidity;
+ int currentTemperature;
+ uint8_t checkSum;
+ unsigned long currentTime;
+ int i;
+
+ currentHumidity = 0;
+ currentTemperature = 0;
+ checkSum = 0;
+ currentTime = millis();
+ for(i = 0; i < DHT22_DATA_BIT_COUNT; i++)
+ {
+ bitTimes[i] = 0;
+ }
+
+ if(currentTime - _lastReadTime < 2000)
+ {
+ // Caller needs to wait 2 seconds between each call to readData
+ return DHT_ERROR_TOOQUICK;
+ }
+ _lastReadTime = currentTime;
+
+ // Pin needs to start HIGH, wait until it is HIGH with a timeout
+ cli();
+ DIRECT_MODE_INPUT(reg, bitmask);
+ sei();
+ retryCount = 0;
+ do
+ {
+ if (retryCount > 125)
+ {
+ return DHT_BUS_HUNG;
+ }
+ retryCount++;
+ delayMicroseconds(2);
+ } while(!DIRECT_READ(reg, bitmask));
+ // Send the activate pulse
+ cli();
+ DIRECT_WRITE_LOW(reg, bitmask);
+ DIRECT_MODE_OUTPUT(reg, bitmask); // Output Low
+ sei();
+ delayMicroseconds(1100); // 1.1 ms
+ cli();
+ DIRECT_MODE_INPUT(reg, bitmask); // Switch back to input so pin can float
+ sei();
+ // Find the start of the ACK Pulse
+ retryCount = 0;
+ do
+ {
+ if (retryCount > 25) //(Spec is 20 to 40 us, 25*2 == 50 us)
+ {
+ return DHT_ERROR_NOT_PRESENT;
+ }
+ retryCount++;
+ delayMicroseconds(2);
+ } while(!DIRECT_READ(reg, bitmask));
+ // Find the end of the ACK Pulse
+ retryCount = 0;
+ do
+ {
+ if (retryCount > 50) //(Spec is 80 us, 50*2 == 100 us)
+ {
+ return DHT_ERROR_ACK_TOO_LONG;
+ }
+ retryCount++;
+ delayMicroseconds(2);
+ } while(DIRECT_READ(reg, bitmask));
+ // Read the 40 bit data stream
+ for(i = 0; i < DHT22_DATA_BIT_COUNT; i++)
+ {
+ // Find the start of the sync pulse
+ retryCount = 0;
+ do
+ {
+ if (retryCount > 35) //(Spec is 50 us, 35*2 == 70 us)
+ {
+ return DHT_ERROR_SYNC_TIMEOUT;
+ }
+ retryCount++;
+ delayMicroseconds(2);
+ } while(!DIRECT_READ(reg, bitmask));
+ // Measure the width of the data pulse
+ retryCount = 0;
+ do
+ {
+ if (retryCount > 50) //(Spec is 80 us, 50*2 == 100 us)
+ {
+ return DHT_ERROR_DATA_TIMEOUT;
+ }
+ retryCount++;
+ delayMicroseconds(2);
+ } while(DIRECT_READ(reg, bitmask));
+ bitTimes[i] = retryCount;
+ }
+ // Now bitTimes have the number of retries (us *2)
+ // that were needed to find the end of each data bit
+ // Spec: 0 is 26 to 28 us
+ // Spec: 1 is 70 us
+ // bitTimes[x] <= 11 is a 0
+ // bitTimes[x] > 11 is a 1
+ // Note: the bits are offset by one from the data sheet, not sure why
+ for(i = 0; i < 16; i++)
+ {
+ if(bitTimes[i + 1] > 11)
+ {
+ currentHumidity |= (1 << (15 - i));
+ }
+ }
+ for(i = 0; i < 16; i++)
+ {
+ if(bitTimes[i + 17] > 11)
+ {
+ currentTemperature |= (1 << (15 - i));
+ }
+ }
+ for(i = 0; i < 8; i++)
+ {
+ if(bitTimes[i + 33] > 11)
+ {
+ checkSum |= (1 << (7 - i));
+ }
+ }
+
+ _lastHumidity = (float(currentHumidity & 0x7FFF) / 10.0);
+ if(currentTemperature & 0x8000)
+ {
+ // Below zero, non standard way of encoding negative numbers!
+ currentTemperature &= 0x7FFF;
+ _lastTemperature = (float(currentTemperature) / 10.0) * -1.0;
+ }
+ else
+ {
+ _lastTemperature = float(currentTemperature) / 10.0;
+ }
+
+ // TODO: Test the checksum and return DHT_ERROR_CHECKSUM if bad
+
+ return DHT_ERROR_NONE;
+}
+
+float DHT22::getHumidity()
+{
+ return _lastHumidity;
+}
+
+float DHT22::getTemperatureC()
+{
+ return _lastTemperature;
+}
+
+//
+// This is used when the millis clock rolls over to zero
+//
+void DHT22::clockReset()
+{
+ _lastReadTime = millis();
+}
37 DHT22.h
@@ -0,0 +1,37 @@
+#ifndef _DHT22_H_
+#define _DHT22_H_
+
+#include <inttypes.h>
+
+#define DHT22_ERROR_VALUE -99.5
+
+typedef enum
+{
+ DHT_ERROR_NONE = 0,
+ DHT_BUS_HUNG,
+ DHT_ERROR_NOT_PRESENT,
+ DHT_ERROR_ACK_TOO_LONG,
+ DHT_ERROR_SYNC_TIMEOUT,
+ DHT_ERROR_DATA_TIMEOUT,
+ DHT_ERROR_CHECKSUM,
+ DHT_ERROR_TOOQUICK
+} DHT22_ERROR_t;
+
+class DHT22
+{
+ private:
+ uint8_t _bitmask;
+ volatile uint8_t *_baseReg;
+ unsigned long _lastReadTime;
+ float _lastHumidity;
+ float _lastTemperature;
+
+ public:
+ DHT22(uint8_t pin);
+ DHT22_ERROR_t readData(void);
+ float getHumidity();
+ float getTemperatureC();
+ void clockReset();
+};
+
+#endif /*_DHT22_H_*/
19 README
@@ -0,0 +1,19 @@
+ DHT22.cpp - DHT22 sensor library
+ Developed by Ben Adams - 2011
+
+Humidity and Temperature Sensor DHT22 info found at
+http://www.sparkfun.com/products/10167
+
+Version 0.3: 17-Jan-2011 by Ben Adams
+This version reads data
+Needs check sum code added at the end of readData
+
+Version 0.2: 16-Jan-2011 by Ben Adams
+Changed coding style to match other Arduino libraries.
+This version will not read data either!
+
+Version 0.1: 10-Jan-2011 by Ben Adams nethoncho AT gmail.com
+First Version is a skeleton. This version will not read data!
+Code adapted from the following sources:
+The Arduino OneWire lib
+http://sheepdogguides.com/arduino/ar3ne1humDHT11.htm
38 examples/Serial/Serial.pde
@@ -0,0 +1,38 @@
+#include <DHT22.h>
+
+// Data wire is plugged into port 7 on the Arduino
+// Connect a 4.7K resistor between VCC and the data pin (strong pullup)
+#define DHT22_PIN 7
+
+// Setup a DHT22 instance
+DHT22 myDHT22(DHT22_PIN);
+
+void setup(void)
+{
+ // start serial port
+ Serial.begin(9600);
+ Serial.println("DHT22 Library Demo");
+}
+
+void loop(void)
+{
+ DHT22_ERROR_t errorCode;
+
+ delay(2000);
+ Serial.print("Requesting data...");
+ errorCode = myDHT22.readData();
+ if(errorCode == DHT_ERROR_NONE)
+ {
+ Serial.print("Got Data ");
+ Serial.print(myDHT22.getTemperatureC());
+ Serial.print("C ");
+ Serial.print(myDHT22.getHumidity());
+ Serial.println("%");
+ }
+ else
+ {
+ Serial.print("Error Code ");
+ Serial.print(errorCode);
+ Serial.println(" readData Failed");
+ }
+}
27 keywords.txt
@@ -0,0 +1,27 @@
+#######################################
+# Syntax Coloring Map For DHT22
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+DHT22 KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+readData KEYWORD2
+getHumidity KEYWORD2
+getTemperatureC KEYWORD2
+clockReset KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+
+#######################################
+# Constants (LITERAL1)
+#######################################
Please sign in to comment.
Something went wrong with that request. Please try again.