From a10b25482bd770496e2f649c037bbc68d669e554 Mon Sep 17 00:00:00 2001 From: Tim Davies Date: Sun, 4 Aug 2013 13:20:13 +0100 Subject: [PATCH 1/4] Moves parsing of sensor type to function, adds dedicated bcm2835_init function, moves variable definitions into readDHT function to allow multiple reads. --- Adafruit_DHT_Driver/Adafruit_DHT.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Adafruit_DHT_Driver/Adafruit_DHT.c b/Adafruit_DHT_Driver/Adafruit_DHT.c index 9d1746be..1e1574ee 100644 --- a/Adafruit_DHT_Driver/Adafruit_DHT.c +++ b/Adafruit_DHT_Driver/Adafruit_DHT.c @@ -34,6 +34,8 @@ #define AM2302 22 int readDHT(int type, int pin); +int parseType(char *input); +int init(void); int main(int argc, char **argv) { @@ -45,10 +47,9 @@ int main(int argc, char **argv) printf("example: %s 2302 4 - Read from an AM2302 connected to GPIO #4\n", argv[0]); return 2; } - int type = 0; - if (strcmp(argv[1], "11") == 0) type = DHT11; - if (strcmp(argv[1], "22") == 0) type = DHT22; - if (strcmp(argv[1], "2302") == 0) type = AM2302; + + int type = parseType(argv[1]); + if (type == 0) { printf("Select 11, 22, 2302 as type!\n"); return 3; @@ -69,10 +70,12 @@ int main(int argc, char **argv) } // main -int bits[250], data[100]; -int bitidx = 0; + int readDHT(int type, int pin) { + int bits[250], data[100]; + int bitidx = 0; + int counter = 0; int laststate = HIGH; int j=0; @@ -146,3 +149,16 @@ int readDHT(int type, int pin) { return 0; } + +int parseType(char *input){ + int type = 0; + if (strcmp(input, "11") == 0) type = DHT11; + if (strcmp(input, "22") == 0) type = DHT22; + if (strcmp(input, "2302") == 0) type = AM2302; + return type; +} + +int init(void){ + if (bcm2835_init()) return 1; + return 0; +} From e20e41d3a386b1965a32cebe2c733ef8d273e378 Mon Sep 17 00:00:00 2001 From: Tim Davies Date: Sun, 4 Aug 2013 15:42:30 +0100 Subject: [PATCH 2/4] readDHT returns array of two floats, printing done in main. Adds flag on readDHT to suppress printing of raw data. --- Adafruit_DHT_Driver/Adafruit_DHT.c | 52 +++++++++++++++++++----------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/Adafruit_DHT_Driver/Adafruit_DHT.c b/Adafruit_DHT_Driver/Adafruit_DHT.c index 1e1574ee..b5235af3 100644 --- a/Adafruit_DHT_Driver/Adafruit_DHT.c +++ b/Adafruit_DHT_Driver/Adafruit_DHT.c @@ -33,7 +33,7 @@ #define DHT22 22 #define AM2302 22 -int readDHT(int type, int pin); +float *readDHT(int type, int pin, int print); int parseType(char *input); int init(void); @@ -64,7 +64,15 @@ int main(int argc, char **argv) printf("Using pin #%d\n", dhtpin); - readDHT(type, dhtpin); + + float *r = readDHT(type, dhtpin, 1); + if (r[0]==-1.){ + printf("Read failed\n"); + } else { + if (type == DHT11) printf("Temp = %.0f *C, Hum = %.0f \%\n", r[0], r[1]); + if (type == DHT22) printf("Temp = %.1f *C, Hum = %.1f \%\n", r[0], r[1]); + } + return 0; } // main @@ -72,7 +80,7 @@ int main(int argc, char **argv) -int readDHT(int type, int pin) { +float *readDHT(int type, int pin, int print) { int bits[250], data[100]; int bitidx = 0; @@ -80,6 +88,9 @@ int readDHT(int type, int pin) { int laststate = HIGH; int j=0; + static float result[2]; + float t, h; + // Set GPIO pin to output bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP); @@ -127,27 +138,30 @@ int readDHT(int type, int pin) { } #endif - printf("Data (%d): 0x%x 0x%x 0x%x 0x%x 0x%x\n", j, data[0], data[1], data[2], data[3], data[4]); + if (print) printf("Data (%d): 0x%x 0x%x 0x%x 0x%x 0x%x\n", j, data[0], data[1], data[2], data[3], data[4]); - if ((j >= 39) && - (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) { + if ((j >= 39) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) { // yay! - if (type == DHT11) - printf("Temp = %d *C, Hum = %d \%\n", data[2], data[0]); + if (type == DHT11) { + t = (float)data[2]; + h = (float)data[0]; + } if (type == DHT22) { - float f, h; - h = data[0] * 256 + data[1]; - h /= 10; - - f = (data[2] & 0x7F)* 256 + data[3]; - f /= 10.0; - if (data[2] & 0x80) f *= -1; - printf("Temp = %.1f *C, Hum = %.1f \%\n", f, h); + //float f, h; + h = data[0] * 256 + data[1]; + h /= 10; + + t = (data[2] & 0x7F)* 256 + data[3]; + t /= 10.0; + if (data[2] & 0x80) t *= -1; } - return 1; + result[0] = t; + result[1] = h; + return result; } - - return 0; + result[0] = -1.; + result[1] = -1.; + return result; } int parseType(char *input){ From b239f837815ecc41f3f38ac10c7acd60f828eda4 Mon Sep 17 00:00:00 2001 From: Tim Davies Date: Sun, 4 Aug 2013 17:13:01 +0100 Subject: [PATCH 3/4] Simple ctypes wrapper for C library. --- Adafruit_DHT_Driver/DHT_Wrapper.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Adafruit_DHT_Driver/DHT_Wrapper.py diff --git a/Adafruit_DHT_Driver/DHT_Wrapper.py b/Adafruit_DHT_Driver/DHT_Wrapper.py new file mode 100644 index 00000000..99842eaa --- /dev/null +++ b/Adafruit_DHT_Driver/DHT_Wrapper.py @@ -0,0 +1,29 @@ +import ctypes +from decimal import * + + +class DHT(object): + """ + Wrapper for Adafruit DHT11/DHT22/AM2302 sensor Raspberry Pi driver. + """ + def __init__(self, sensor, pin): + """ + Initialize with sensor type as string and pin Raspberry Pi pin number as integer + """ + self.DHTlib = ctypes.CDLL("./libAdafruit_DHT.so") + if not self.DHTlib.init(): + raise IOError("Could not initialise BCM2835 - may need to run as root") + self.sensor = self.DHTlib.parseType(ctypes.c_char_p(sensor)) + self.pin = ctypes.c_int(pin) + self.DHTlib.readDHT.restype = ctypes.POINTER(ctypes.c_float) + def read(self): + """ + Returns a dict of decimals representing measured temperature and humidity + """ + r = self.DHTlib.readDHT(self.sensor, self.pin, ctypes.c_int(0)) + if r[1] > 0: + q = Decimal("0.1") + return {"temp": Decimal(r[0]).quantize(q), "hum":Decimal(r[1]).quantize(q)} + else: + return False + From b92f0c41dadb18d4b1d497bdc7191351d14d674d Mon Sep 17 00:00:00 2001 From: Tim Davies Date: Sun, 4 Aug 2013 18:06:12 +0100 Subject: [PATCH 4/4] Updates google docs example to use DHT python wrapper --- .../Adafruit_DHT_googledocs.ex.py | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py b/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py index c13d3033..caa6f87f 100755 --- a/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py +++ b/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py @@ -6,6 +6,7 @@ import time import datetime import gspread +from DHT_Wrapper import DHT # =========================================================================== # Google Account Details @@ -37,31 +38,25 @@ print "Unable to open the spreadsheet. Check your filename: %s" % spreadsheet sys.exit() +# Initialize sensor +d = DHT("2302", 4) + # Continuously append data while(True): # Run the DHT program to get the humidity and temperature readings! - - output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]); - print output - matches = re.search("Temp =\s+([0-9.]+)", output) - if (not matches): - time.sleep(3) - continue - temp = float(matches.group(1)) + r = d.read() - # search for humidity printout - matches = re.search("Hum =\s+([0-9.]+)", output) - if (not matches): - time.sleep(3) - continue - humidity = float(matches.group(1)) + if not r: + time.sleep(3) + continue + - print "Temperature: %.1f C" % temp - print "Humidity: %.1f %%" % humidity + print "Temperature: %.1f C" % r["temp"] + print "Humidity: %.1f %%" % r["hum"] # Append the data in the spreadsheet, including a timestamp try: - values = [datetime.datetime.now(), temp, humidity] + values = [datetime.datetime.now(), r["temp"], r["hum"]] worksheet.append_row(values) except: print "Unable to append data. Check your connection?"