From b89bc8cb03f0534805c2112d5fa4253f82ab616f Mon Sep 17 00:00:00 2001
From: geremy@pubnub.com
Date: Sun, 28 Dec 2014 17:06:19 -0800
Subject: adding open/close files for door, new humid/temp sensor
---
 python/examples/Adafruit_Python_DHT/.gitignore     |   5 +
 .../Adafruit_DHT/Beaglebone_Black.py               | 217 ++++++++++++++
 .../Adafruit_DHT/Raspberry_Pi.py                   |  38 +++
 .../Adafruit_Python_DHT/Adafruit_DHT/Test.py       |  33 ++
 .../Adafruit_Python_DHT/Adafruit_DHT/__init__.py   |  21 ++
 .../Adafruit_Python_DHT/Adafruit_DHT/common.py     |  86 ++++++
 .../Adafruit_DHT/platform_detect.py                |  56 ++++
 python/examples/Adafruit_Python_DHT/LICENSE        |  21 ++
 python/examples/Adafruit_Python_DHT/README.md      |  29 ++
 .../dist/Adafruit_DHT-1.0.0-py2.7-linux-armv6l.egg | Bin 0 -> 27032 bytes
 .../Adafruit_Python_DHT/examples/AdafruitDHT.py    |  50 ++++
 .../examples/google_spreadsheet.py                 |  98 ++++++
 .../Adafruit_Python_DHT/examples/simpletest.py     |  48 +++
 python/examples/Adafruit_Python_DHT/ez_setup.py    | 332 +++++++++++++++++++++
 python/examples/Adafruit_Python_DHT/setup.py       |  55 ++++
 .../source/Beaglebone_Black/bbb_dht_read.c         | 154 ++++++++++
 .../source/Beaglebone_Black/bbb_dht_read.h         |  33 ++
 .../source/Beaglebone_Black/bbb_mmio.c             |  73 +++++
 .../source/Beaglebone_Black/bbb_mmio.h             | 101 +++++++
 .../source/Raspberry_Pi/pi_dht_read.c              | 158 ++++++++++
 .../source/Raspberry_Pi/pi_dht_read.h              |  32 ++
 .../source/Raspberry_Pi/pi_mmio.c                  |  55 ++++
 .../source/Raspberry_Pi/pi_mmio.h                  |  61 ++++
 .../source/Test/test_dht_read.c                    |  34 +++
 .../source/Test/test_dht_read.h                    |  26 ++
 .../source/_Beaglebone_Black_Driver.c              |  49 +++
 .../source/_Raspberry_Pi_Driver.c                  |  49 +++
 .../Adafruit_Python_DHT/source/_Test_Driver.c      |  49 +++
 .../Adafruit_Python_DHT/source/common_dht_read.c   |  66 ++++
 .../Adafruit_Python_DHT/source/common_dht_read.h   |  51 ++++
 python/examples/close.py                           | 103 +++++++
 python/examples/open.py                            | 103 +++++++
 32 files changed, 2286 insertions(+)
 create mode 100644 python/examples/Adafruit_Python_DHT/.gitignore
 create mode 100644 python/examples/Adafruit_Python_DHT/Adafruit_DHT/Beaglebone_Black.py
 create mode 100644 python/examples/Adafruit_Python_DHT/Adafruit_DHT/Raspberry_Pi.py
 create mode 100644 python/examples/Adafruit_Python_DHT/Adafruit_DHT/Test.py
 create mode 100644 python/examples/Adafruit_Python_DHT/Adafruit_DHT/__init__.py
 create mode 100644 python/examples/Adafruit_Python_DHT/Adafruit_DHT/common.py
 create mode 100644 python/examples/Adafruit_Python_DHT/Adafruit_DHT/platform_detect.py
 create mode 100644 python/examples/Adafruit_Python_DHT/LICENSE
 create mode 100644 python/examples/Adafruit_Python_DHT/README.md
 create mode 100644 python/examples/Adafruit_Python_DHT/dist/Adafruit_DHT-1.0.0-py2.7-linux-armv6l.egg
 create mode 100755 python/examples/Adafruit_Python_DHT/examples/AdafruitDHT.py
 create mode 100755 python/examples/Adafruit_Python_DHT/examples/google_spreadsheet.py
 create mode 100644 python/examples/Adafruit_Python_DHT/examples/simpletest.py
 create mode 100644 python/examples/Adafruit_Python_DHT/ez_setup.py
 create mode 100644 python/examples/Adafruit_Python_DHT/setup.py
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.h
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.h
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.h
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.h
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.h
 create mode 100644 python/examples/Adafruit_Python_DHT/source/_Beaglebone_Black_Driver.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/_Raspberry_Pi_Driver.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/_Test_Driver.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/common_dht_read.c
 create mode 100644 python/examples/Adafruit_Python_DHT/source/common_dht_read.h
 create mode 100644 python/examples/close.py
 create mode 100644 python/examples/open.py
(limited to 'python')
diff --git a/python/examples/Adafruit_Python_DHT/.gitignore b/python/examples/Adafruit_Python_DHT/.gitignore
new file mode 100644
index 0000000..8051352
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/.gitignore
@@ -0,0 +1,5 @@
+build
+*.egg-info
+*.pyc
+setuptools-*
+
diff --git a/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Beaglebone_Black.py b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Beaglebone_Black.py
new file mode 100644
index 0000000..8716482
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Beaglebone_Black.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import re
+
+import common
+import Beaglebone_Black_Driver as driver
+
+
+# Define mapping of pin names to GPIO base and number.
+# Adapted from Adafruit_BBIO code Beaglebone Black system reference.
+pin_to_gpio = {
+	"P9_11": (0,30),
+	"P9_12": (1,28),
+	"P9_13": (0,31),
+	"P9_14": (1,18),
+	"P9_15": (1,16),
+	"P9_16": (1,19),
+	"P9_17": (0,5),
+	"P9_18": (0,4),
+	"P9_19": (0,13),
+	"P9_20": (0,12),
+	"P9_21": (0,3),
+	"P9_22": (0,2),
+	"P9_23": (1,17),
+	"P9_24": (0,15),
+	"P9_25": (3,21),
+	"P9_26": (0,14),
+	"P9_27": (3,19),
+	"P9_28": (3,17),
+	"P9_29": (3,15),
+	"P9_30": (3,16),
+	"P9_31": (3,14),
+	"P9_41": (0,20),
+	"P9_42": (0,7),
+	"UART4_RXD": (0,30),
+	"UART4_TXD": (0,31),
+	"EHRPWM1A": (1,18),
+	"EHRPWM1B": (1,19),
+	"I2C1_SCL": (0,5),
+	"I2C1_SDA": (0,4),
+	"I2C2_SCL": (0,13),
+	"I2C2_SDA": (0,12),
+	"UART2_TXD": (0,3),
+	"UART2_RXD": (0,2),
+	"UART1_TXD": (0,15),
+	"UART1_RXD": (0,14),
+	"SPI1_CS0": (3,17),
+	"SPI1_D0": (3,15),
+	"SPI1_D1": (3,16),
+	"SPI1_SCLK": (3,14),
+	"CLKOUT2": (0,20),
+	"30": (0,30),
+	"60": (1,28),
+	"31": (0,31),
+	"50": (1,18),
+	"48": (1,16),
+	"51": (1,19),
+	"5": (0,5),
+	"4": (0,4),
+	"13": (0,13),
+	"12": (0,12),
+	"3": (0,3),
+	"2": (0,2),
+	"49": (1,17),
+	"15": (0,15),
+	"117": (3,21),
+	"14": (0,14),
+	"115": (3,19),
+	"113": (3,17),
+	"111": (3,15),
+	"112": (3,16),
+	"110": (3,14),
+	"20": (0,20),
+	"7": (0,7),
+	"P8_3": (1,6),
+	"P8_4": (1,7),
+	"P8_5": (1,2),
+	"P8_6": (1,3),
+	"P8_7": (2,2),
+	"P8_8": (2,3),
+	"P8_9": (2,5),
+	"P8_10": (2,4),
+	"P8_11": (1,13),
+	"P8_12": (1,12),
+	"P8_13": (0,23),
+	"P8_14": (0,26),
+	"P8_15": (1,15),
+	"P8_16": (1,14),
+	"P8_17": (0,27),
+	"P8_18": (2,1),
+	"P8_19": (0,22),
+	"P8_20": (1,31),
+	"P8_21": (1,30),
+	"P8_22": (1,5),
+	"P8_23": (1,4),
+	"P8_24": (1,1),
+	"P8_25": (1,0),
+	"P8_26": (1,29),
+	"P8_27": (2,22),
+	"P8_28": (2,24),
+	"P8_29": (2,23),
+	"P8_30": (2,25),
+	"P8_31": (0,10),
+	"P8_32": (0,11),
+	"P8_33": (0,9),
+	"P8_34": (2,17),
+	"P8_35": (0,8),
+	"P8_36": (2,16),
+	"P8_37": (2,14),
+	"P8_38": (2,15),
+	"P8_39": (2,12),
+	"P8_40": (2,13),
+	"P8_41": (2,10),
+	"P8_42": (2,11),
+	"P8_43": (2,8),
+	"P8_44": (2,9),
+	"P8_45": (2,6),
+	"P8_46": (2,7),
+	"TIMER4": (2,2),
+	"TIMER7": (2,3),
+	"TIMER5": (2,5),
+	"TIMER6": (2,4),
+	"EHRPWM2B": (0,23),
+	"EHRPWM2A": (0,22),
+	"UART5_CTSN": (0,10),
+	"UART5_RTSN": (0,11),
+	"UART4_RTSN": (0,9),
+	"UART3_RTSN": (2,17),
+	"UART4_CTSN": (0,8),
+	"UART3_CTSN": (2,16),
+	"UART5_TXD": (2,14),
+	"UART5_RXD": (2,15),
+	"38": (1,6),
+	"39": (1,7),
+	"34": (1,2),
+	"35": (1,3),
+	"66": (2,2),
+	"67": (2,3),
+	"69": (2,5),
+	"68": (2,4),
+	"45": (1,13),
+	"44": (1,12),
+	"23": (0,23),
+	"26": (0,26),
+	"47": (1,15),
+	"46": (1,14),
+	"27": (0,27),
+	"65": (2,1),
+	"22": (0,22),
+	"63": (1,31),
+	"62": (1,30),
+	"37": (1,5),
+	"36": (1,4),
+	"33": (1,1),
+	"32": (1,0),
+	"61": (1,29),
+	"86": (2,22),
+	"88": (2,24),
+	"87": (2,23),
+	"89": (2,25),
+	"10": (0,10),
+	"11": (0,11),
+	"9": (0,9),
+	"81": (2,17),
+	"8": (0,8),
+	"80": (2,16),
+	"78": (2,14),
+	"79": (2,15),
+	"76": (2,12),
+	"77": (2,13),
+	"74": (2,10),
+	"75": (2,11),
+	"72": (2,8),
+	"73": (2,9),
+	"70": (2,6),
+	"71": (2,7)
+}
+
+def read(sensor, pin):
+	# Validate GPIO and map it to GPIO base and number.
+	gpio = pin_to_gpio.get(str(pin).upper(), None)
+	if gpio is None:
+		# Couldn't find in mapping, check if pin looks like GPIO_
+		match = re.match('GPIO([0123])_(\d+)', pin, re.IGNORECASE)
+		if match is not None:
+			gpio = (int(match.group(1)), int(match.group(2)))
+	if gpio is None or gpio[0] < 0 or gpio[0] > 3 or gpio[1] < 0 or gpio[1] > 31:
+		raise ValueError('Pin must be a valid GPIO identifier like P9_12 or GPIO1_28.')
+	# Get a reading from C driver code.
+	result, humidity, temp = driver.read(sensor, gpio[0], gpio[1])
+	if result in common.TRANSIENT_ERRORS:
+		# Signal no result could be obtained, but the caller can retry.
+		return (None, None)
+	elif result == common.DHT_ERROR_GPIO:
+		raise RuntimeError('Error accessing GPIO. Make sure program is run as root with sudo!')
+	elif result != common.DHT_SUCCESS:
+		# Some kind of error occured.
+		raise RuntimeError('Error calling DHT test driver read: {0}'.format(result))
+	return (humidity, temp)
diff --git a/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Raspberry_Pi.py b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Raspberry_Pi.py
new file mode 100644
index 0000000..eaf4488
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Raspberry_Pi.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import common
+import Raspberry_Pi_Driver as driver
+
+def read(sensor, pin):
+	# Validate pin is a valid GPIO.
+	if pin is None or int(pin) < 0 or int(pin) > 31:
+		raise ValueError('Pin must be a valid GPIO number 0 to 31.')
+	# Get a reading from C driver code.
+	result, humidity, temp = driver.read(sensor, int(pin))
+	if result in common.TRANSIENT_ERRORS:
+		# Signal no result could be obtained, but the caller can retry.
+		return (None, None)
+	elif result == common.DHT_ERROR_GPIO:
+		raise RuntimeError('Error accessing GPIO. Make sure program is run as root with sudo!')
+	elif result != common.DHT_SUCCESS:
+		# Some kind of error occured.
+		raise RuntimeError('Error calling DHT test driver read: {0}'.format(result))
+	return (humidity, temp)
diff --git a/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Test.py b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Test.py
new file mode 100644
index 0000000..57db439
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/Test.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import common
+import Test_Driver as driver
+
+def read(sensor, pin):
+	# Get a reading from C driver code.
+	result, humidity, temp = driver.read(sensor, pin)
+	if result in common.TRANSIENT_ERRORS:
+		# Signal no result could be obtained, but the caller can retry.
+		return (None, None)
+	elif result != common.DHT_SUCCESS:
+		# Some kind of error occured.
+		raise RuntimeError('Error calling DHT test driver read: {0}'.format(result))
+	return (humidity, temp)
diff --git a/python/examples/Adafruit_Python_DHT/Adafruit_DHT/__init__.py b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/__init__.py
new file mode 100644
index 0000000..1c49666
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+from common import DHT11, DHT22, AM2302, read, read_retry
\ No newline at end of file
diff --git a/python/examples/Adafruit_Python_DHT/Adafruit_DHT/common.py b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/common.py
new file mode 100644
index 0000000..eec472e
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/common.py
@@ -0,0 +1,86 @@
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import time
+
+import platform_detect
+
+
+# Define error constants.
+DHT_SUCCESS        =  0
+DHT_ERROR_TIMEOUT  = -1
+DHT_ERROR_CHECKSUM = -2
+DHT_ERROR_ARGUMENT = -3
+DHT_ERROR_GPIO     = -4
+TRANSIENT_ERRORS = [DHT_ERROR_CHECKSUM, DHT_ERROR_TIMEOUT]
+
+# Define sensor type constants.
+DHT11  = 11
+DHT22  = 22
+AM2302 = 22
+SENSORS = [DHT11, DHT22, AM2302]
+
+
+def get_platform():
+	"""Return a DHT platform interface for the currently detected platform."""
+	plat = platform_detect.platform_detect()
+	if plat == platform_detect.RASPBERRY_PI:
+		import Raspberry_Pi
+		return Raspberry_Pi
+	elif plat == platform_detect.BEAGLEBONE_BLACK:
+		import Beaglebone_Black
+		return Beaglebone_Black
+	else:
+		raise RuntimeError('Unknown platform.')
+
+def read(sensor, pin, platform=None):
+	"""Read DHT sensor of specified sensor type (DHT11, DHT22, or AM2302) on 
+	specified pin and return a tuple of humidity (as a floating point value
+	in percent) and temperature (as a floating point value in Celsius). Note that
+	because the sensor requires strict timing to read and Linux is not a real
+	time OS, a result is not guaranteed to be returned!  In some cases this will
+	return the tuple (None, None) which indicates the function should be retried.
+	Also note the DHT sensor cannot be read faster than about once every 2 seconds.
+	Platform is an optional parameter which allows you to override the detected
+	platform interface--ignore this parameter unless you receive unknown platform
+	errors and want to override the detection.
+	"""
+	if sensor not in SENSORS:
+		raise ValueError('Expected DHT11, DHT22, or AM2302 sensor value.')
+	if platform is None:
+		platform = get_platform()
+	return platform.read(sensor, pin)
+
+def read_retry(sensor, pin, retries=15, delay_seconds=2, platform=None):
+	"""Read DHT sensor of specified sensor type (DHT11, DHT22, or AM2302) on 
+	specified pin and return a tuple of humidity (as a floating point value
+	in percent) and temperature (as a floating point value in Celsius).
+	Unlike the read function, this read_retry function will attempt to read
+	multiple times (up to the specified max retries) until a good reading can be 
+	found. If a good reading cannot be found after the amount of retries, a tuple
+	of (None, None) is returned. The delay between retries is by default 2
+	seconds, but can be overridden.
+	"""
+	for i in range(retries):
+		humidity, temperature = read(sensor, pin, platform)
+		if humidity is not None and temperature is not None:
+			return (humidity, temperature)
+		time.sleep(delay_seconds)
+	return (None, None)
diff --git a/python/examples/Adafruit_Python_DHT/Adafruit_DHT/platform_detect.py b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/platform_detect.py
new file mode 100644
index 0000000..154e4b1
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/Adafruit_DHT/platform_detect.py
@@ -0,0 +1,56 @@
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import platform
+
+# Platform identification constants.
+UNKNOWN          = 0
+RASPBERRY_PI     = 1
+BEAGLEBONE_BLACK = 2
+
+
+def platform_detect(plat=platform.platform()):
+	"""Detect if running on the Raspberry Pi or Beaglebone Black and return the
+	platform type.  Will return RASPBERRY_PI, BEAGLEBONE_BLACK, or UNKNOWN."""
+	# Handle Raspberry Pi
+	# Platform output on Raspbian testing/jessie ~May 2014:
+	# Linux-3.10.25+-armv6l-with-debian-7.4
+	if plat.lower().find('armv6l-with-debian') > -1:
+		return RASPBERRY_PI
+	# Handle pidora distribution.
+	elif plat.lower().find('raspberry_pi') > -1:
+		return RASPBERRY_PI
+	# Handle arch distribution.
+	elif plat.lower().find('arch-armv6l') > -1:
+		return RASPBERRY_PI
+	# Handle Beaglebone Black
+	# Platform output on Debian ~May 2014:
+	# Linux-3.8.13-bone47-armv7l-with-debian-7.4
+	elif plat.lower().find('armv7l-with-debian') > -1:
+		return BEAGLEBONE_BLACK
+	# Handle Beaglebone Black
+	# Platform output on Ubuntu ~July 2014:
+	# Linux-3.8.13-bone56-armv7l-with-Ubuntu-14.04-trusty
+	elif plat.lower().find('armv7l-with-ubuntu') > -1:
+		return BEAGLEBONE_BLACK	
+	elif plat.lower().find('armv7l-with-glibc2.4') > -1:
+		return BEAGLEBONE_BLACK
+	else:
+		return UNKNOWN
diff --git a/python/examples/Adafruit_Python_DHT/LICENSE b/python/examples/Adafruit_Python_DHT/LICENSE
new file mode 100644
index 0000000..35a35d3
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Adafruit Industries
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/python/examples/Adafruit_Python_DHT/README.md b/python/examples/Adafruit_Python_DHT/README.md
new file mode 100644
index 0000000..c0cd02e
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/README.md
@@ -0,0 +1,29 @@
+Adafruit Python DHT Sensor Library
+==================================
+
+Python library to read the DHT series of humidity and temperature sensors on a Raspberry Pi or Beaglebone Black.
+
+Designed specifically to work with the Adafruit DHT series sensors ----> https://www.adafruit.com/products/385
+
+Currently the library is only tested with Python 2.6/2.7.
+
+For all platforms (Raspberry Pi and Beaglebone Black) make sure your system is able to compile Python extensions.  On Raspbian or Beaglebone Black's Debian/Ubuntu image you can ensure your system is ready by executing:
+
+````
+apt-get update
+sudo apt-get install build-essential python-dev
+````
+
+Install the library by downloading with the download link on the right, unzipping the archive, and executing:
+
+````
+sudo python setup.py install
+````
+
+See example of usage in the examples folder.
+
+Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
+
+Written by Tony DiCola for Adafruit Industries.
+
+MIT license, all text above must be included in any redistribution
diff --git a/python/examples/Adafruit_Python_DHT/dist/Adafruit_DHT-1.0.0-py2.7-linux-armv6l.egg b/python/examples/Adafruit_Python_DHT/dist/Adafruit_DHT-1.0.0-py2.7-linux-armv6l.egg
new file mode 100644
index 0000000..b0da7fa
Binary files /dev/null and b/python/examples/Adafruit_Python_DHT/dist/Adafruit_DHT-1.0.0-py2.7-linux-armv6l.egg differ
diff --git a/python/examples/Adafruit_Python_DHT/examples/AdafruitDHT.py b/python/examples/Adafruit_Python_DHT/examples/AdafruitDHT.py
new file mode 100755
index 0000000..daa9770
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/examples/AdafruitDHT.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import sys
+
+import Adafruit_DHT
+
+
+# Parse command line parameters.
+sensor_args = { '11': Adafruit_DHT.DHT11,
+				'22': Adafruit_DHT.DHT22,
+				'2302': Adafruit_DHT.AM2302 }
+if len(sys.argv) == 3 and sys.argv[1] in sensor_args:
+	sensor = sensor_args[sys.argv[1]]
+	pin = sys.argv[2]
+else:
+	print 'usage: sudo ./Adafruit_DHT.py [11|22|2302] GPIOpin#'
+	print 'example: sudo ./Adafruit_DHT.py 2302 4 - Read from an AM2302 connected to GPIO #4'
+	sys.exit(1)
+
+# Try to grab a sensor reading.  Use the read_retry method which will retry up
+# to 15 times to get a sensor reading (waiting 2 seconds between each retry).
+humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
+
+# Note that sometimes you won't get a reading and
+# the results will be null (because Linux can't
+# guarantee the timing of calls to read the sensor).  
+# If this happens try again!
+if humidity is not None and temperature is not None:
+	print 'Temp={0:0.1f}*C  Humidity={1:0.1f}%'.format(temperature, humidity)
+else:
+	print 'Failed to get reading. Try again!'
diff --git a/python/examples/Adafruit_Python_DHT/examples/google_spreadsheet.py b/python/examples/Adafruit_Python_DHT/examples/google_spreadsheet.py
new file mode 100755
index 0000000..fddda65
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/examples/google_spreadsheet.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+
+# Google Spreadsheet DHT Sensor Data-logging Example
+
+# Depends on the 'gspread' package being installed.  If you have pip installed
+# execute:
+#   sudo pip install gspread
+
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import sys
+import time
+import datetime
+
+import Adafruit_DHT
+import gspread
+
+# Type of sensor, can be Adafruit_DHT.DHT11, Adafruit_DHT.DHT22, or Adafruit_DHT.AM2302.
+DHT_TYPE = Adafruit_DHT.DHT22
+
+# Example of sensor connected to Raspberry Pi pin 23
+DHT_PIN  = 23
+# Example of sensor connected to Beaglebone Black pin P8_11
+#DHT_PIN  = 'P8_11'
+
+# Google Docs account email, password, and spreadsheet name.
+GDOCS_EMAIL            = 'your google docs account email address'
+GDOCS_PASSWORD         = 'your google docs account password'
+GDOCS_SPREADSHEET_NAME = 'your google docs spreadsheet name'
+
+# How long to wait (in seconds) between measurements.
+FREQUENCY_SECONDS      = 30
+
+
+def login_open_sheet(email, password, spreadsheet):
+	"""Connect to Google Docs spreadsheet and return the first worksheet."""
+	try:
+		gc = gspread.login(email, password)
+		worksheet = gc.open(spreadsheet).sheet1
+		return worksheet
+	except:
+		print 'Unable to login and get spreadsheet.  Check email, password, spreadsheet name.'
+		sys.exit(1)
+
+
+print 'Logging sensor measurements to {0} every {1} seconds.'.format(GDOCS_SPREADSHEET_NAME, FREQUENCY_SECONDS)
+print 'Press Ctrl-C to quit.'
+worksheet = None
+while True:
+	# Login if necessary.
+	if worksheet is None:
+		worksheet = login_open_sheet(GDOCS_EMAIL, GDOCS_PASSWORD, GDOCS_SPREADSHEET_NAME)
+
+	# Attempt to get sensor reading.
+	humidity, temp = Adafruit_DHT.read(DHT_TYPE, DHT_PIN)
+
+	# Skip to the next reading if a valid measurement couldn't be taken.
+	# This might happen if the CPU is under a lot of load and the sensor
+	# can't be reliably read (timing is critical to read the sensor).
+	if humidity is None or temp is None:
+		time.sleep(2)
+		continue
+
+	print 'Temperature: {0:0.1f} C'.format(temp)
+	print 'Humidity:    {0:0.1f} %'.format(humidity)
+ 
+	# Append the data in the spreadsheet, including a timestamp
+	try:
+		worksheet.append_row((datetime.datetime.now(), temp, humidity))
+	except:
+		# Error appending data, most likely because credentials are stale.
+		# Null out the worksheet so a login is performed at the top of the loop.
+		print 'Append error, logging in again'
+		worksheet = None
+		time.sleep(FREQUENCY_SECONDS)
+		continue
+
+	# Wait 30 seconds before continuing
+	print 'Wrote a row to {0}'.format(GDOCS_SPREADSHEET_NAME)
+	time.sleep(FREQUENCY_SECONDS)
diff --git a/python/examples/Adafruit_Python_DHT/examples/simpletest.py b/python/examples/Adafruit_Python_DHT/examples/simpletest.py
new file mode 100644
index 0000000..e8aa30d
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/examples/simpletest.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+# Copyright (c) 2014 Adafruit Industries
+# Author: Tony DiCola
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import Adafruit_DHT
+
+# Sensor should be set to Adafruit_DHT.DHT11,
+# Adafruit_DHT.DHT22, or Adafruit_DHT.AM2302.
+sensor = Adafruit_DHT.DHT11
+
+# Example using a Beaglebone Black with DHT sensor
+# connected to pin P8_11.
+pin = 'P8_11'
+
+# Example using a Raspberry Pi with DHT sensor
+# connected to pin 23.
+pin = 7
+
+# Try to grab a sensor reading.  Use the read_retry method which will retry up
+# to 15 times to get a sensor reading (waiting 2 seconds between each retry).
+humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
+
+# Note that sometimes you won't get a reading and
+# the results will be null (because Linux can't
+# guarantee the timing of calls to read the sensor).  
+# If this happens try again!
+if humidity is not None and temperature is not None:
+	print 'Temp={0:0.1f}*C  Humidity={1:0.1f}%'.format(temperature, humidity)
+else:
+	print 'Failed to get reading. Try again!'
diff --git a/python/examples/Adafruit_Python_DHT/ez_setup.py b/python/examples/Adafruit_Python_DHT/ez_setup.py
new file mode 100644
index 0000000..1bcd3e9
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/ez_setup.py
@@ -0,0 +1,332 @@
+#!/usr/bin/env python
+"""Bootstrap setuptools installation
+
+To use setuptools in your package's setup.py, include this
+file in the same directory and add this to the top of your setup.py::
+
+    from ez_setup import use_setuptools
+    use_setuptools()
+
+To require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, simply supply
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import shutil
+import sys
+import tempfile
+import zipfile
+import optparse
+import subprocess
+import platform
+import textwrap
+import contextlib
+
+from distutils import log
+
+try:
+    from urllib.request import urlopen
+except ImportError:
+    from urllib2 import urlopen
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+DEFAULT_VERSION = "4.0.1"
+DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
+
+def _python_cmd(*args):
+    """
+    Return True if the command succeeded.
+    """
+    args = (sys.executable,) + args
+    return subprocess.call(args) == 0
+
+
+def _install(archive_filename, install_args=()):
+    with archive_context(archive_filename):
+        # installing
+        log.warn('Installing Setuptools')
+        if not _python_cmd('setup.py', 'install', *install_args):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+            # exitcode will be 2
+            return 2
+
+
+def _build_egg(egg, archive_filename, to_dir):
+    with archive_context(archive_filename):
+        # building an egg
+        log.warn('Building a Setuptools egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+class ContextualZipFile(zipfile.ZipFile):
+    """
+    Supplement ZipFile class to support context manager for Python 2.6
+    """
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.close()
+
+    def __new__(cls, *args, **kwargs):
+        """
+        Construct a ZipFile or ContextualZipFile as appropriate
+        """
+        if hasattr(zipfile.ZipFile, '__exit__'):
+            return zipfile.ZipFile(*args, **kwargs)
+        return super(ContextualZipFile, cls).__new__(cls)
+
+
+@contextlib.contextmanager
+def archive_context(filename):
+    # extracting the archive
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        with ContextualZipFile(filename) as archive:
+            archive.extractall()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+        yield
+
+    finally:
+        os.chdir(old_wd)
+        shutil.rmtree(tmpdir)
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        archive = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, archive, to_dir)
+    sys.path.insert(0, egg)
+
+    # Remove previously-imported pkg_resources if present (see
+    # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details).
+    if 'pkg_resources' in sys.modules:
+        del sys.modules['pkg_resources']
+
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+        to_dir=os.curdir, download_delay=15):
+    to_dir = os.path.abspath(to_dir)
+    rep_modules = 'pkg_resources', 'setuptools'
+    imported = set(sys.modules).intersection(rep_modules)
+    try:
+        import pkg_resources
+    except ImportError:
+        return _do_download(version, download_base, to_dir, download_delay)
+    try:
+        pkg_resources.require("setuptools>=" + version)
+        return
+    except pkg_resources.DistributionNotFound:
+        return _do_download(version, download_base, to_dir, download_delay)
+    except pkg_resources.VersionConflict as VC_err:
+        if imported:
+            msg = textwrap.dedent("""
+                The required version of setuptools (>={version}) is not available,
+                and can't be installed while this script is running. Please
+                install a more recent version first, using
+                'easy_install -U setuptools'.
+
+                (Currently using {VC_err.args[0]!r})
+                """).format(VC_err=VC_err, version=version)
+            sys.stderr.write(msg)
+            sys.exit(2)
+
+        # otherwise, reload ok
+        del pkg_resources, sys.modules['pkg_resources']
+        return _do_download(version, download_base, to_dir, download_delay)
+
+def _clean_check(cmd, target):
+    """
+    Run the command to download target. If the command fails, clean up before
+    re-raising the error.
+    """
+    try:
+        subprocess.check_call(cmd)
+    except subprocess.CalledProcessError:
+        if os.access(target, os.F_OK):
+            os.unlink(target)
+        raise
+
+def download_file_powershell(url, target):
+    """
+    Download the file at url to target using Powershell (which will validate
+    trust). Raise an exception if the command cannot complete.
+    """
+    target = os.path.abspath(target)
+    ps_cmd = (
+        "[System.Net.WebRequest]::DefaultWebProxy.Credentials = "
+        "[System.Net.CredentialCache]::DefaultCredentials; "
+        "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)"
+        % vars()
+    )
+    cmd = [
+        'powershell',
+        '-Command',
+        ps_cmd,
+    ]
+    _clean_check(cmd, target)
+
+def has_powershell():
+    if platform.system() != 'Windows':
+        return False
+    cmd = ['powershell', '-Command', 'echo test']
+    with open(os.path.devnull, 'wb') as devnull:
+        try:
+            subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+        except Exception:
+            return False
+    return True
+
+download_file_powershell.viable = has_powershell
+
+def download_file_curl(url, target):
+    cmd = ['curl', url, '--silent', '--output', target]
+    _clean_check(cmd, target)
+
+def has_curl():
+    cmd = ['curl', '--version']
+    with open(os.path.devnull, 'wb') as devnull:
+        try:
+            subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+        except Exception:
+            return False
+    return True
+
+download_file_curl.viable = has_curl
+
+def download_file_wget(url, target):
+    cmd = ['wget', url, '--quiet', '--output-document', target]
+    _clean_check(cmd, target)
+
+def has_wget():
+    cmd = ['wget', '--version']
+    with open(os.path.devnull, 'wb') as devnull:
+        try:
+            subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
+        except Exception:
+            return False
+    return True
+
+download_file_wget.viable = has_wget
+
+def download_file_insecure(url, target):
+    """
+    Use Python to download the file, even though it cannot authenticate the
+    connection.
+    """
+    src = urlopen(url)
+    try:
+        # Read all the data in one block.
+        data = src.read()
+    finally:
+        src.close()
+
+    # Write all the data in one block to avoid creating a partial file.
+    with open(target, "wb") as dst:
+        dst.write(data)
+
+download_file_insecure.viable = lambda: True
+
+def get_best_downloader():
+    downloaders = (
+        download_file_powershell,
+        download_file_curl,
+        download_file_wget,
+        download_file_insecure,
+    )
+    viable_downloaders = (dl for dl in downloaders if dl.viable())
+    return next(viable_downloaders, None)
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+        to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader):
+    """
+    Download setuptools from a specified location and return its filename
+
+    `version` should be a valid setuptools version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+
+    ``downloader_factory`` should be a function taking no arguments and
+    returning a function for downloading a URL to a target.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    zip_name = "setuptools-%s.zip" % version
+    url = download_base + zip_name
+    saveto = os.path.join(to_dir, zip_name)
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        log.warn("Downloading %s", url)
+        downloader = downloader_factory()
+        downloader(url, saveto)
+    return os.path.realpath(saveto)
+
+def _build_install_args(options):
+    """
+    Build the arguments to 'python setup.py install' on the setuptools package
+    """
+    return ['--user'] if options.user_install else []
+
+def _parse_args():
+    """
+    Parse the command line for options
+    """
+    parser = optparse.OptionParser()
+    parser.add_option(
+        '--user', dest='user_install', action='store_true', default=False,
+        help='install in user site package (requires Python 2.6 or later)')
+    parser.add_option(
+        '--download-base', dest='download_base', metavar="URL",
+        default=DEFAULT_URL,
+        help='alternative URL from where to download the setuptools package')
+    parser.add_option(
+        '--insecure', dest='downloader_factory', action='store_const',
+        const=lambda: download_file_insecure, default=get_best_downloader,
+        help='Use internal, non-validating downloader'
+    )
+    parser.add_option(
+        '--version', help="Specify which version to download",
+        default=DEFAULT_VERSION,
+    )
+    options, args = parser.parse_args()
+    # positional arguments are ignored
+    return options
+
+def main():
+    """Install or upgrade setuptools and EasyInstall"""
+    options = _parse_args()
+    archive = download_setuptools(
+        version=options.version,
+        download_base=options.download_base,
+        downloader_factory=options.downloader_factory,
+    )
+    return _install(archive, _build_install_args(options))
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/python/examples/Adafruit_Python_DHT/setup.py b/python/examples/Adafruit_Python_DHT/setup.py
new file mode 100644
index 0000000..8f99751
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/setup.py
@@ -0,0 +1,55 @@
+from ez_setup import use_setuptools
+use_setuptools()
+from setuptools import setup, find_packages, Extension
+import sys
+
+import Adafruit_DHT.platform_detect as platform_detect
+
+
+# Check if an explicit platform was chosen with a command line parameter.
+# Kind of hacky to manipulate the argument list before calling setup, but it's
+# the best simple option for adding optional config to the setup.
+platform = platform_detect.UNKNOWN
+if '--force-pi' in sys.argv:
+	platform = platform_detect.RASPBERRY_PI
+	sys.argv.remove('--force-pi')
+elif '--force-bbb' in sys.argv:
+	platform = platform_detect.BEAGLEBONE_BLACK
+	sys.argv.remove('--force-bbb')
+elif '--force-test' in sys.argv:
+	platform = 'TEST'
+	sys.argv.remove('--force-test')
+else:
+	# No explicit platform chosen, detect the current platform.
+	platform = platform_detect.platform_detect()
+
+# Pick the right extension to compile based on the platform.
+extensions = []
+if platform == platform_detect.RASPBERRY_PI:
+	extensions.append(Extension("Adafruit_DHT.Raspberry_Pi_Driver", 
+								["source/_Raspberry_Pi_Driver.c", "source/common_dht_read.c", "source/Raspberry_Pi/pi_dht_read.c", "source/Raspberry_Pi/pi_mmio.c"], 
+								libraries=['rt'],
+								extra_compile_args=['-std=gnu99']))
+elif platform == platform_detect.BEAGLEBONE_BLACK:
+	extensions.append(Extension("Adafruit_DHT.Beaglebone_Black_Driver",
+								["source/_Beaglebone_Black_Driver.c", "source/common_dht_read.c", "source/Beaglebone_Black/bbb_dht_read.c", "source/Beaglebone_Black/bbb_mmio.c"],
+								libraries=['rt'],
+								extra_compile_args=['-std=gnu99']))
+elif platform == 'TEST':
+	extensions.append(Extension("Adafruit_DHT.Test_Driver",
+								["source/_Test_Driver.c", "source/Test/test_dht_read.c"],
+								extra_compile_args=['-std=gnu99']))
+else:
+	print 'Could not detect if running on the Raspberry Pi or Beaglebone Black.  If this failure is unexpected, you can run again with --force-pi or --force-bbb parameter to force using the Raspberry Pi or Beaglebone Black respectively.'
+	sys.exit(1)
+
+# Call setuptools setup function to install package.
+setup(name              = 'Adafruit_DHT',
+	  version           = '1.0.0',
+	  author            = 'Tony DiCola',
+	  author_email      = 'tdicola@adafruit.com',
+	  description       = 'Library to get readings from the DHT11, DHT22, and AM2302 humidity and temperature sensors on a Raspberry Pi or Beaglebone Black.',
+	  license           = 'MIT',
+	  url               = 'https://github.com/adafruit/Adafruit_Python_DHT/',
+	  packages          = find_packages(),
+	  ext_modules       = extensions)
diff --git a/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.c b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.c
new file mode 100644
index 0000000..0fa2761
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.c
@@ -0,0 +1,154 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+#include 
+
+#include "bbb_dht_read.h"
+#include "bbb_mmio.h"
+
+// This is the only processor specific magic value, the maximum amount of time to
+// spin in a loop before bailing out and considering the read a timeout.  This should
+// be a high value, but if you're running on a much faster platform than a Raspberry
+// Pi or Beaglebone Black then it might need to be increased.
+#define DHT_MAXCOUNT 32000
+
+// Number of bit pulses to expect from the DHT.  Note that this is 41 because
+// the first pulse is a constant 50 microsecond pulse, with 40 pulses to represent
+// the data afterwards.
+#define DHT_PULSES 41
+
+int bbb_dht_read(int type, int gpio_base, int gpio_number, float* humidity, float* temperature) {
+  // Validate humidity and temperature arguments and set them to zero.
+  if (humidity == NULL || temperature == NULL) {
+    return DHT_ERROR_ARGUMENT;
+  }
+  *temperature = 0.0f;
+  *humidity = 0.0f;
+
+  // Store the count that each DHT bit pulse is low and high.
+  // Make sure array is initialized to start at zero.
+  int pulseCounts[DHT_PULSES*2] = {0};
+
+  // Get GPIO pin and set it as an output.
+  gpio_t pin;
+  if (bbb_mmio_get_gpio(gpio_base, gpio_number, &pin) < 0) {
+    return DHT_ERROR_GPIO;
+  }
+  bbb_mmio_set_output(pin);
+
+  // Bump up process priority and change scheduler to try to try to make process more 'real time'.
+  set_max_priority();
+
+  // Set pin high for ~500 milliseconds.
+  bbb_mmio_set_high(pin);
+  sleep_milliseconds(500);
+
+  // The next calls are timing critical and care should be taken
+  // to ensure no unnecssary work is done below.
+
+  // Set pin low for ~20 milliseconds.
+  bbb_mmio_set_low(pin);
+  busy_wait_milliseconds(20);
+
+  // Set pin as input.
+  bbb_mmio_set_input(pin);
+
+  // Wait for DHT to pull pin low.
+  uint32_t count = 0;
+  while (bbb_mmio_input(pin)) {
+    if (++count >= DHT_MAXCOUNT) {
+      // Timeout waiting for response.
+      set_default_priority();
+      return DHT_ERROR_TIMEOUT;
+    }
+  }
+
+  // Record pulse widths for the expected result bits.
+  for (int i=0; i < DHT_PULSES*2; i+=2) {
+    // Count how long pin is low and store in pulseCounts[i]
+    while (!bbb_mmio_input(pin)) {
+      if (++pulseCounts[i] >= DHT_MAXCOUNT) {
+        // Timeout waiting for response.
+        set_default_priority();
+        return DHT_ERROR_TIMEOUT;
+      }
+    }
+    // Count how long pin is high and store in pulseCounts[i+1]
+    while (bbb_mmio_input(pin)) {
+      if (++pulseCounts[i+1] >= DHT_MAXCOUNT) {
+        // Timeout waiting for response.
+        set_default_priority();
+        return DHT_ERROR_TIMEOUT;
+      }
+    }
+  }
+
+  // Done with timing critical code, now interpret the results.
+
+  // Drop back to normal priority.
+  set_default_priority();
+
+  // Compute the average low pulse width to use as a 50 microsecond reference threshold.
+  // Ignore the first two readings because they are a constant 80 microsecond pulse.
+  uint32_t threshold = 0;
+  for (int i=2; i < DHT_PULSES*2; i+=2) {
+    threshold += pulseCounts[i];
+  }
+  threshold /= DHT_PULSES-1;
+
+  // Interpret each high pulse as a 0 or 1 by comparing it to the 50us reference.
+  // If the count is less than 50us it must be a ~28us 0 pulse, and if it's higher
+  // then it must be a ~70us 1 pulse.
+  uint8_t data[5] = {0};
+  for (int i=3; i < DHT_PULSES*2; i+=2) {
+    int index = (i-3)/16;
+    data[index] <<= 1;
+    if (pulseCounts[i] >= threshold) {
+      // One bit for long pulse.
+      data[index] |= 1;
+    }
+    // Else zero bit for short pulse.
+  }
+
+  // Useful debug info:
+  //printf("Data: 0x%x 0x%x 0x%x 0x%x 0x%x\n", data[0], data[1], data[2], data[3], data[4]);
+
+  // Verify checksum of received data.
+  if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
+    if (type == DHT11) {
+      // Get humidity and temp for DHT11 sensor.
+      *humidity = (float)data[0];
+      *temperature = (float)data[2];
+    }
+    else if (type == DHT22) {
+      // Calculate humidity and temp for DHT22 sensor.
+      *humidity = (data[0] * 256 + data[1]) / 10.0f;
+      *temperature = ((data[2] & 0x7F) * 256 + data[3]) / 10.0f;
+      if (data[2] & 0x80) {
+        *temperature *= -1.0f;
+      }
+    }
+    return DHT_SUCCESS;
+  }
+  else {
+    return DHT_ERROR_CHECKSUM;
+  }
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.h b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.h
new file mode 100644
index 0000000..949ad2c
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_dht_read.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#ifndef BBB_DHT_READ_H
+#define BBB_DHT_READ_H
+
+#include "../common_dht_read.h"
+
+// Read DHT sensor connected to GPIO bin GPIO_, for example P8_11 is GPIO1_13 with
+// base = 1 and number = 13.  Humidity and temperature will be returned in the provided parameters.
+// If a successfull reading could be made a value of 0 (DHT_SUCCESS) will be returned.  If there
+// was an error reading the sensor a negative value will be returned.  Some errors can be ignored
+// and retried, specifically DHT_ERROR_TIMEOUT or DHT_ERROR_CHECKSUM.
+int bbb_dht_read(int type, int gpio_base, int gpio_number, float* humidity, float* temperature);
+
+#endif
diff --git a/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.c b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.c
new file mode 100644
index 0000000..fda1beb
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.c
@@ -0,0 +1,73 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "bbb_mmio.h"
+
+#define GPIO_LENGTH 4096
+#define GPIO0_ADDR 0x44E07000
+#define GPIO1_ADDR 0x4804C000
+#define GPIO2_ADDR 0x481AC000
+#define GPIO3_ADDR 0x481AF000
+
+// Store mapping of GPIO base number to GPIO address.
+static uint32_t gpio_addresses[4] = { GPIO0_ADDR, GPIO1_ADDR, GPIO2_ADDR, GPIO3_ADDR };
+
+// Cache memory-mapped GPIO addresses.
+static volatile uint32_t* gpio_base[4] = { NULL };
+
+int bbb_mmio_get_gpio(int base, int number, gpio_t* gpio) {
+  // Validate input parameters.
+  if (gpio == NULL) {
+    return MMIO_ERROR_ARGUMENT;
+  }
+  if (base < 0 || base > 3) {
+    return MMIO_ERROR_ARGUMENT;
+  }
+  if (number < 0 || number > 31) {
+    return MMIO_ERROR_ARGUMENT;
+  }
+  // Map GPIO memory if its hasn't been mapped already.
+  if (gpio_base[base] == NULL) {
+    int fd = open("/dev/mem", O_RDWR | O_SYNC);
+    if (fd == -1) {
+      // Error opening /dev/mem.  Probably not running as root.
+      return MMIO_ERROR_DEVMEM;
+    }
+    // Map GPIO memory to location in process space.
+    gpio_base[base] = (uint32_t*)mmap(NULL, GPIO_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, gpio_addresses[base]);
+    if (gpio_base[base] == MAP_FAILED) {
+      // Don't save the result if the memory mapping failed.
+      gpio_base[base] = NULL;
+      return MMIO_ERROR_MMAP;
+    }
+  }
+  // Initialize and set GPIO fields.
+  memset(gpio, 0, sizeof(gpio));
+  gpio->base = gpio_base[base];
+  gpio->number = number;
+  return MMIO_SUCCESS;
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.h b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.h
new file mode 100644
index 0000000..b6d5faa
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Beaglebone_Black/bbb_mmio.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Simple fast memory-mapped GPIO library for the Beaglebone Black.
+// Allows reading and writing GPIO at very high speeds, up to ~2.6mhz!
+
+/*
+  // Example usage:
+
+  #include 
+  #include "bbb_mmio.h"
+
+  int main(int argc, char* argv[]) {
+    // Get GPIO pin.  
+    // See the giant table of of pins in the system reference manual for details 
+    // on the base and number for a given GPIO:
+    //  https://github.com/CircuitCo/BeagleBone-Black/blob/master/BBB_SRM.pdf?raw=true
+    // Section 7 Connectors, table 12 shows P8_11 maps to GPIO1_13, so 1 is the 
+    // gpio base and 13 is the gpio number.
+    gpio_t p8_11;
+    if (bbb_mmio_get_gpio(1, 13, &p8_11) < 0) {
+      printf("Couldn't get requested GPIO pin!\n");
+      return 1;
+    }
+    // Set pin as output.
+    bbb_mmio_set_output(p8_11);
+    // Toggle the pin high and low as fast as possible.
+    // This generates a signal at about 2.6mhz in my tests.
+    // Each pulse high/low is only about 200 nanoseconds long!
+    while (1) {
+      bbb_mmio_set_high(p8_11);
+      bbb_mmio_set_low(p8_11);
+    }
+    return 0;
+  }
+
+*/
+
+#ifndef BBB_MMIO_H
+#define BBB_MMIO_H
+
+#include 
+
+#define MMIO_SUCCESS 0
+#define MMIO_ERROR_ARGUMENT -1
+#define MMIO_ERROR_DEVMEM -2
+#define MMIO_ERROR_MMAP -3
+
+#define MMIO_OE_ADDR 0x134
+#define MMIO_GPIO_DATAOUT 0x13C
+#define MMIO_GPIO_DATAIN 0x138
+#define MMIO_GPIO_CLEARDATAOUT 0x190
+#define MMIO_GPIO_SETDATAOUT 0x194
+
+// Define struct to represent a GPIO pin based on its base memory address and number.
+typedef struct {
+  volatile uint32_t* base;
+  int number;
+} gpio_t;
+
+int bbb_mmio_get_gpio(int base, int number, gpio_t* gpio);
+
+static inline void bbb_mmio_set_output(gpio_t gpio) {
+  gpio.base[MMIO_OE_ADDR/4] &= (0xFFFFFFFF ^ (1 << gpio.number));
+}
+
+static inline void bbb_mmio_set_input(gpio_t gpio) {
+  gpio.base[MMIO_OE_ADDR/4] |= (1 << gpio.number);
+}
+
+static inline void bbb_mmio_set_high(gpio_t gpio) {
+  gpio.base[MMIO_GPIO_SETDATAOUT/4] = 1 << gpio.number;
+}
+
+static inline void bbb_mmio_set_low(gpio_t gpio) {
+  gpio.base[MMIO_GPIO_CLEARDATAOUT/4] = 1 << gpio.number;
+}
+
+static inline uint32_t bbb_mmio_input(gpio_t gpio) {
+  return gpio.base[MMIO_GPIO_DATAIN/4] & (1 << gpio.number);
+}
+
+#endif
diff --git a/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.c b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.c
new file mode 100644
index 0000000..0789e60
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.c
@@ -0,0 +1,158 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+#include 
+
+#include "pi_dht_read.h"
+#include "pi_mmio.h"
+
+// This is the only processor specific magic value, the maximum amount of time to
+// spin in a loop before bailing out and considering the read a timeout.  This should
+// be a high value, but if you're running on a much faster platform than a Raspberry
+// Pi or Beaglebone Black then it might need to be increased.
+#define DHT_MAXCOUNT 32000
+
+// Number of bit pulses to expect from the DHT.  Note that this is 41 because
+// the first pulse is a constant 50 microsecond pulse, with 40 pulses to represent
+// the data afterwards.
+#define DHT_PULSES 41
+
+int pi_dht_read(int type, int pin, float* humidity, float* temperature) {
+  // Validate humidity and temperature arguments and set them to zero.
+  if (humidity == NULL || temperature == NULL) {
+    return DHT_ERROR_ARGUMENT;
+  }
+  *temperature = 0.0f;
+  *humidity = 0.0f;
+
+  // Initialize GPIO library.
+  if (pi_mmio_init() < 0) {
+    return DHT_ERROR_GPIO;
+  }
+
+  // Store the count that each DHT bit pulse is low and high.
+  // Make sure array is initialized to start at zero.
+  int pulseCounts[DHT_PULSES*2] = {0};
+
+  // Set pin to output.
+  pi_mmio_set_output(pin);
+
+  // Bump up process priority and change scheduler to try to try to make process more 'real time'.
+  set_max_priority();
+
+  // Set pin high for ~500 milliseconds.
+  pi_mmio_set_high(pin);
+  sleep_milliseconds(500);
+
+  // The next calls are timing critical and care should be taken
+  // to ensure no unnecssary work is done below.
+
+  // Set pin low for ~20 milliseconds.
+  pi_mmio_set_low(pin);
+  busy_wait_milliseconds(20);
+
+  // Set pin at input.
+  pi_mmio_set_input(pin);
+  // Need a very short delay before reading pins or else value is sometimes still low.
+  for (volatile int i = 0; i < 50; ++i) {
+  }
+
+  // Wait for DHT to pull pin low.
+  uint32_t count = 0;
+  while (pi_mmio_input(pin)) {
+    if (++count >= DHT_MAXCOUNT) {
+      // Timeout waiting for response.
+      set_default_priority();
+      return DHT_ERROR_TIMEOUT;
+    }
+  }
+
+  // Record pulse widths for the expected result bits.
+  for (int i=0; i < DHT_PULSES*2; i+=2) {
+    // Count how long pin is low and store in pulseCounts[i]
+    while (!pi_mmio_input(pin)) {
+      if (++pulseCounts[i] >= DHT_MAXCOUNT) {
+        // Timeout waiting for response.
+        set_default_priority();
+        return DHT_ERROR_TIMEOUT;
+      }
+    }
+    // Count how long pin is high and store in pulseCounts[i+1]
+    while (pi_mmio_input(pin)) {
+      if (++pulseCounts[i+1] >= DHT_MAXCOUNT) {
+        // Timeout waiting for response.
+        set_default_priority();
+        return DHT_ERROR_TIMEOUT;
+      }
+    }
+  }
+
+  // Done with timing critical code, now interpret the results.
+
+  // Drop back to normal priority.
+  set_default_priority();
+
+  // Compute the average low pulse width to use as a 50 microsecond reference threshold.
+  // Ignore the first two readings because they are a constant 80 microsecond pulse.
+  uint32_t threshold = 0;
+  for (int i=2; i < DHT_PULSES*2; i+=2) {
+    threshold += pulseCounts[i];
+  }
+  threshold /= DHT_PULSES-1;
+
+  // Interpret each high pulse as a 0 or 1 by comparing it to the 50us reference.
+  // If the count is less than 50us it must be a ~28us 0 pulse, and if it's higher
+  // then it must be a ~70us 1 pulse.
+  uint8_t data[5] = {0};
+  for (int i=3; i < DHT_PULSES*2; i+=2) {
+    int index = (i-3)/16;
+    data[index] <<= 1;
+    if (pulseCounts[i] >= threshold) {
+      // One bit for long pulse.
+      data[index] |= 1;
+    }
+    // Else zero bit for short pulse.
+  }
+
+  // Useful debug info:
+  //printf("Data: 0x%x 0x%x 0x%x 0x%x 0x%x\n", data[0], data[1], data[2], data[3], data[4]);
+
+  // Verify checksum of received data.
+  if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
+    if (type == DHT11) {
+      // Get humidity and temp for DHT11 sensor.
+      *humidity = (float)data[0];
+      *temperature = (float)data[2];
+    }
+    else if (type == DHT22) {
+      // Calculate humidity and temp for DHT22 sensor.
+      *humidity = (data[0] * 256 + data[1]) / 10.0f;
+      *temperature = ((data[2] & 0x7F) * 256 + data[3]) / 10.0f;
+      if (data[2] & 0x80) {
+        *temperature *= -1.0f;
+      }
+    }
+    return DHT_SUCCESS;
+  }
+  else {
+    return DHT_ERROR_CHECKSUM;
+  }
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.h b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.h
new file mode 100644
index 0000000..9132e96
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_dht_read.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#ifndef PI_DHT_READ_H
+#define PI_DHT_READ_H
+
+#include "../common_dht_read.h"
+
+// Read DHT sensor connected to GPIO pin (using BCM numbering).  Humidity and temperature will be 
+// returned in the provided parameters. If a successfull reading could be made a value of 0 
+// (DHT_SUCCESS) will be returned.  If there was an error reading the sensor a negative value will
+// be returned.  Some errors can be ignored and retried, specifically DHT_ERROR_TIMEOUT or DHT_ERROR_CHECKSUM.
+int pi_dht_read(int sensor, int pin, float* humidity, float* temperature);
+
+#endif
diff --git a/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.c b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.c
new file mode 100644
index 0000000..6755230
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.c
@@ -0,0 +1,55 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+// Based on code from Gert van Loo & Dom: http://elinux.org/RPi_Low-level_peripherals#GPIO_Code_examples
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pi_mmio.h"
+
+#define BASE 0x20000000
+#define GPIO_BASE (BASE + 0x200000)
+#define GPIO_LENGTH 4096
+
+volatile uint32_t* pi_mmio_gpio = NULL;
+
+int pi_mmio_init(void) {
+  if (pi_mmio_gpio == NULL) {
+    int fd = open("/dev/mem", O_RDWR | O_SYNC);
+    if (fd == -1) {
+      // Error opening /dev/mem.  Probably not running as root.
+      return MMIO_ERROR_DEVMEM;
+    }
+    // Map GPIO memory to location in process space.
+    pi_mmio_gpio = (uint32_t*)mmap(NULL, GPIO_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
+    close(fd);
+    if (pi_mmio_gpio == MAP_FAILED) {
+      // Don't save the result if the memory mapping failed.
+      pi_mmio_gpio = NULL;
+      return MMIO_ERROR_MMAP;
+    }
+  }
+  return MMIO_SUCCESS;
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.h b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.h
new file mode 100644
index 0000000..d47a9c3
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Raspberry_Pi/pi_mmio.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+// Based on code from Gert van Loo & Dom: http://elinux.org/RPi_Low-level_peripherals#GPIO_Code_examples
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Simple fast memory-mapped GPIO library for the Raspberry Pi.
+#ifndef PI_MMIO_H
+#define PI_MMIO_H
+
+#include 
+
+#define MMIO_SUCCESS 0
+#define MMIO_ERROR_DEVMEM -1
+#define MMIO_ERROR_MMAP -2
+
+volatile uint32_t* pi_mmio_gpio;
+
+int pi_mmio_init(void);
+
+static inline void pi_mmio_set_input(const int gpio_number) {
+  // Set GPIO register to 000 for specified GPIO number.
+  *(pi_mmio_gpio+((gpio_number)/10)) &= ~(7<<(((gpio_number)%10)*3));
+}
+
+static inline void pi_mmio_set_output(const int gpio_number) {
+  // First set to 000 using input function.
+  pi_mmio_set_input(gpio_number);
+  // Next set bit 0 to 1 to set output.
+  *(pi_mmio_gpio+((gpio_number)/10)) |=  (1<<(((gpio_number)%10)*3));
+}
+
+static inline void pi_mmio_set_high(const int gpio_number) {
+  *(pi_mmio_gpio+7) = 1 << gpio_number;
+}
+
+static inline void pi_mmio_set_low(const int gpio_number) {
+  *(pi_mmio_gpio+10) = 1 << gpio_number;
+}
+
+static inline uint32_t pi_mmio_input(const int gpio_number) {
+  return *(pi_mmio_gpio+13) & (1 << gpio_number);
+}
+
+#endif
diff --git a/python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.c b/python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.c
new file mode 100644
index 0000000..be06744
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.c
@@ -0,0 +1,34 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+
+#include "test_dht_read.h"
+
+int test_dht_read(int type, int pin, float* humidity, float* temperature) {
+  // Validate humidity and temperature arguments and set them to zero.
+  if (humidity == NULL || temperature == NULL) {
+    return -1;
+  }
+  *temperature = 42.0f;
+  *humidity = 50.0f;
+
+  return 0;
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.h b/python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.h
new file mode 100644
index 0000000..b4d2601
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/Test/test_dht_read.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#ifndef TEST_DHT_READ_H
+#define TEST_DHT_READ_H
+
+int test_dht_read(int sensor, int pin, float* humidity, float* temperature);
+
+#endif
diff --git a/python/examples/Adafruit_Python_DHT/source/_Beaglebone_Black_Driver.c b/python/examples/Adafruit_Python_DHT/source/_Beaglebone_Black_Driver.c
new file mode 100644
index 0000000..329aead
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/_Beaglebone_Black_Driver.c
@@ -0,0 +1,49 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+
+#include "Beaglebone_Black/bbb_dht_read.h"
+
+// Wrap calling dht_read function and expose it as a DHT.read Python module & function.
+static PyObject* Beaglebone_Black_Driver_read(PyObject *self, PyObject *args)
+{
+	// Parse sensor and pin integer arguments.
+    int sensor, base, number;
+    if (!PyArg_ParseTuple(args, "iii", &sensor, &base, &number)) {
+        return NULL;
+    }
+    // Call dht_read and return result code, humidity, and temperature.
+    float humidity = 0, temperature = 0;
+    int result = bbb_dht_read(sensor, base, number, &humidity, &temperature);
+    return Py_BuildValue("iff", result, humidity, temperature);
+}
+
+// Boilerplate python module method list and initialization functions below.
+
+static PyMethodDef module_methods[] = {
+    {"read", Beaglebone_Black_Driver_read, METH_VARARGS, "Read DHT sensor value on a Beaglebone Black."},
+    {NULL, NULL, 0, NULL}
+};
+
+PyMODINIT_FUNC initBeaglebone_Black_Driver(void)
+{
+    Py_InitModule("Beaglebone_Black_Driver", module_methods);
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/_Raspberry_Pi_Driver.c b/python/examples/Adafruit_Python_DHT/source/_Raspberry_Pi_Driver.c
new file mode 100644
index 0000000..a867597
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/_Raspberry_Pi_Driver.c
@@ -0,0 +1,49 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+
+#include "Raspberry_Pi/pi_dht_read.h"
+
+// Wrap calling dht_read function and expose it as a DHT.read Python module & function.
+static PyObject* Raspberry_Pi_Driver_read(PyObject *self, PyObject *args)
+{
+	// Parse sensor and pin integer arguments.
+    int sensor, pin;
+    if (!PyArg_ParseTuple(args, "ii", &sensor, &pin)) {
+        return NULL;
+    }
+    // Call dht_read and return result code, humidity, and temperature.
+    float humidity = 0, temperature = 0;
+    int result = pi_dht_read(sensor, pin, &humidity, &temperature);
+    return Py_BuildValue("iff", result, humidity, temperature);
+}
+
+// Boilerplate python module method list and initialization functions below.
+
+static PyMethodDef module_methods[] = {
+    {"read", Raspberry_Pi_Driver_read, METH_VARARGS, "Read DHT sensor value on a Raspberry Pi."},
+    {NULL, NULL, 0, NULL}
+};
+
+PyMODINIT_FUNC initRaspberry_Pi_Driver(void)
+{
+    Py_InitModule("Raspberry_Pi_Driver", module_methods);
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/_Test_Driver.c b/python/examples/Adafruit_Python_DHT/source/_Test_Driver.c
new file mode 100644
index 0000000..36257e5
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/_Test_Driver.c
@@ -0,0 +1,49 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+
+#include "Test/test_dht_read.h"
+
+// Wrap calling dht_read function and expose it as a DHT.read Python module & function.
+static PyObject* Test_Driver_read(PyObject *self, PyObject *args)
+{
+	// Parse sensor and pin integer arguments.
+    int sensor, pin;
+    if (!PyArg_ParseTuple(args, "ii", &sensor, &pin)) {
+        return NULL;
+    }
+    // Call dht_read and return result code, humidity, and temperature.
+    float humidity = 0, temperature = 0;
+    int result = test_dht_read(sensor, pin, &humidity, &temperature);
+    return Py_BuildValue("iff", result, humidity, temperature);
+}
+
+// Boilerplate python module method list and initialization functions below.
+
+static PyMethodDef module_methods[] = {
+    {"read", Test_Driver_read, METH_VARARGS, "Mock DHT read function."},
+    {NULL, NULL, 0, NULL}
+};
+
+PyMODINIT_FUNC initTest_Driver(void)
+{
+    Py_InitModule("Test_Driver", module_methods);
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/common_dht_read.c b/python/examples/Adafruit_Python_DHT/source/common_dht_read.c
new file mode 100644
index 0000000..3bbb663
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/common_dht_read.c
@@ -0,0 +1,66 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "common_dht_read.h"
+
+void busy_wait_milliseconds(uint32_t millis) {
+  // Set delay time period.
+  struct timeval deltatime;
+  deltatime.tv_sec = millis / 1000;
+  deltatime.tv_usec = (millis % 1000) * 1000;
+  struct timeval walltime;
+  // Get current time and add delay to find end time.
+  gettimeofday(&walltime, NULL);
+  struct timeval endtime;
+  timeradd(&walltime, &deltatime, &endtime);
+  // Tight loop to waste time (and CPU) until enough time as elapsed.
+  while (timercmp(&walltime, &endtime, <)) {
+    gettimeofday(&walltime, NULL);
+  }
+}
+
+void sleep_milliseconds(uint32_t millis) {
+  struct timespec sleep;
+  sleep.tv_sec = millis / 1000;
+  sleep.tv_nsec = (millis % 1000) * 1000000L;
+  while (clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep, &sleep) && errno == EINTR);
+}
+
+void set_max_priority(void) {
+  struct sched_param sched;
+  memset(&sched, 0, sizeof(sched));
+  // Use FIFO scheduler with highest priority for the lowest chance of the kernel context switching.
+  sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
+  sched_setscheduler(0, SCHED_FIFO, &sched);
+}
+
+void set_default_priority(void) {
+  struct sched_param sched;
+  memset(&sched, 0, sizeof(sched));
+  // Go back to default scheduler with default 0 priority.
+  sched.sched_priority = 0;
+  sched_setscheduler(0, SCHED_OTHER, &sched);
+}
diff --git a/python/examples/Adafruit_Python_DHT/source/common_dht_read.h b/python/examples/Adafruit_Python_DHT/source/common_dht_read.h
new file mode 100644
index 0000000..bb56c67
--- /dev/null
+++ b/python/examples/Adafruit_Python_DHT/source/common_dht_read.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2014 Adafruit Industries
+// Author: Tony DiCola
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+#ifndef COMMON_DHT_READ_H
+#define COMMON_DHT_READ_H
+
+#include 
+
+// Define errors and return values.
+#define DHT_ERROR_TIMEOUT -1
+#define DHT_ERROR_CHECKSUM -2
+#define DHT_ERROR_ARGUMENT -3
+#define DHT_ERROR_GPIO -4
+#define DHT_SUCCESS 0
+
+// Define sensor types.
+#define DHT11 11
+#define DHT22 22
+#define AM2302 22
+
+// Busy wait delay for most accurate timing, but high CPU usage.
+// Only use this for short periods of time (a few hundred milliseconds at most)!
+void busy_wait_milliseconds(uint32_t millis);
+
+// General delay that sleeps so CPU usage is low, but accuracy is potentially bad.
+void sleep_milliseconds(uint32_t millis);
+
+// Increase scheduling priority and algorithm to try to get 'real time' results.
+void set_max_priority(void);
+
+// Drop scheduling priority back to normal/default.
+void set_default_priority(void);
+
+#endif
diff --git a/python/examples/close.py b/python/examples/close.py
new file mode 100644
index 0000000..72dd340
--- /dev/null
+++ b/python/examples/close.py
@@ -0,0 +1,103 @@
+#-----------------------------------
+# Name: Stepper Motor
+#
+# Author: matt.hawkins
+#
+# Created: 11/07/2012
+# Copyright: (c) matt.hawkins 2012
+#-----------------------------------
+#!/usr/bin/env python
+ 
+# Import required libraries
+import time
+import sys
+import RPi.GPIO as GPIO
+
+# Use BCM GPIO references
+# instead of physical pin numbers
+GPIO.setmode(GPIO.BOARD)
+ 
+# Define GPIO signals to use
+# Pins 19,22,24,26
+# GPIO10,GPIO25,GPIO8,GPIO7
+
+StepPins = [26,24,22,19]
+#StepPins = [24,22,26,19]
+ 
+# Set all pins as output
+for pin in StepPins:
+  print "Setup pins"
+  GPIO.setup(pin,GPIO.OUT)
+  GPIO.output(pin, False)
+ 
+# Define some settings
+StepCounter = 0
+WaitTime = 0.000001
+#WaitTime = 0.001
+ 
+# Define simple sequence
+StepCount1 = 4
+Seq1 = []
+Seq1 = range(0, StepCount1)
+
+Seq1[0] = [1,0,0,0]
+Seq1[1] = [0,1,0,0]
+Seq1[2] = [0,0,1,0]
+Seq1[3] = [0,0,0,1]
+
+#Seq1[3] = [1,0,0,0]
+#Seq1[2] = [0,1,0,0]
+#Seq1[1] = [0,0,1,0]
+#Seq1[0] = [0,0,0,1]
+ 
+# Define advanced sequence
+# as shown in manufacturers datasheet
+StepCount2 = 8
+Seq2 = []
+Seq2 = range(0, StepCount2)
+Seq2[7] = [1,0,0,0]
+Seq2[6] = [1,1,0,0]
+Seq2[5] = [0,1,0,0]
+Seq2[4] = [0,1,1,0]
+Seq2[3] = [0,0,1,0]
+Seq2[2] = [0,0,1,1]
+Seq2[1] = [0,0,0,1]
+Seq2[0] = [1,0,0,1]
+ 
+# Choose a sequence to use
+Seq = Seq2
+StepCount = StepCount2
+GlobalCount = 1600
+Cycles = 0
+ 
+# Start main loop
+while 1==1:
+ 
+  for pin in range(0, 4):
+    xpin = StepPins[pin]
+
+    pinVal = Seq[StepCounter][pin]
+
+    if pinVal!=0:
+      #print " Step %i Enable %i" %(StepCounter,xpin)
+      GPIO.output(xpin, True)
+    else:
+      GPIO.output(xpin, False)
+ 
+  StepCounter += 1
+  Cycles +=1
+
+  print " Stepcounter: %i" %(StepCounter) 
+  # If we reach the end of the sequence
+  # start again
+  if (StepCounter==StepCount):
+    StepCounter = 0
+
+  if (StepCounter<0):
+    StepCounter = StepCount
+
+  if (GlobalCount == Cycles):
+   sys.exit()
+
+  # Wait before moving on
+  time.sleep(WaitTime)
diff --git a/python/examples/open.py b/python/examples/open.py
new file mode 100644
index 0000000..b5518c6
--- /dev/null
+++ b/python/examples/open.py
@@ -0,0 +1,103 @@
+#-----------------------------------
+# Name: Stepper Motor
+#
+# Author: matt.hawkins
+#
+# Created: 11/07/2012
+# Copyright: (c) matt.hawkins 2012
+#-----------------------------------
+#!/usr/bin/env python
+ 
+# Import required libraries
+import time
+import sys
+import RPi.GPIO as GPIO
+
+# Use BCM GPIO references
+# instead of physical pin numbers
+GPIO.setmode(GPIO.BOARD)
+ 
+# Define GPIO signals to use
+# Pins 19,22,24,26
+# GPIO10,GPIO25,GPIO8,GPIO7
+
+StepPins = [26,24,22,19]
+#StepPins = [24,22,26,19]
+ 
+# Set all pins as output
+for pin in StepPins:
+  print "Setup pins"
+  GPIO.setup(pin,GPIO.OUT)
+  GPIO.output(pin, False)
+ 
+# Define some settings
+StepCounter = 0
+WaitTime = 0.000001
+#WaitTime = 0.001
+ 
+# Define simple sequence
+StepCount1 = 4
+Seq1 = []
+Seq1 = range(0, StepCount1)
+
+Seq1[0] = [1,0,0,0]
+Seq1[1] = [0,1,0,0]
+Seq1[2] = [0,0,1,0]
+Seq1[3] = [0,0,0,1]
+
+#Seq1[3] = [1,0,0,0]
+#Seq1[2] = [0,1,0,0]
+#Seq1[1] = [0,0,1,0]
+#Seq1[0] = [0,0,0,1]
+ 
+# Define advanced sequence
+# as shown in manufacturers datasheet
+StepCount2 = 8
+Seq2 = []
+Seq2 = range(0, StepCount2)
+Seq2[0] = [1,0,0,0]
+Seq2[1] = [1,1,0,0]
+Seq2[2] = [0,1,0,0]
+Seq2[3] = [0,1,1,0]
+Seq2[4] = [0,0,1,0]
+Seq2[5] = [0,0,1,1]
+Seq2[6] = [0,0,0,1]
+Seq2[7] = [1,0,0,1]
+ 
+# Choose a sequence to use
+Seq = Seq2
+StepCount = StepCount2
+GlobalCount = 1600
+Cycles = 0
+ 
+# Start main loop
+while 1==1:
+ 
+  for pin in range(0, 4):
+    xpin = StepPins[pin]
+
+    pinVal = Seq[StepCounter][pin]
+
+    if pinVal!=0:
+      #print " Step %i Enable %i" %(StepCounter,xpin)
+      GPIO.output(xpin, True)
+    else:
+      GPIO.output(xpin, False)
+ 
+  StepCounter += 1
+  Cycles +=1
+
+  print " Stepcounter: %i" %(StepCounter) 
+  # If we reach the end of the sequence
+  # start again
+  if (StepCounter==StepCount):
+    StepCounter = 0
+
+  if (StepCounter<0):
+    StepCounter = StepCount
+
+  if (GlobalCount == Cycles):
+   sys.exit()
+
+  # Wait before moving on
+  time.sleep(WaitTime)
-- 
cgit v1.2.3