diff options
| author | geremy@pubnub.com | 2014-12-28 17:06:19 -0800 |
|---|---|---|
| committer | geremy@pubnub.com | 2014-12-28 17:06:19 -0800 |
| commit | b89bc8cb03f0534805c2112d5fa4253f82ab616f (patch) | |
| tree | 4559202652cbd265fe8a84e4933e36d127b2b465 /python | |
| parent | c2a3ee12ce2c42b05e1ee31d737d9a8703f4a580 (diff) | |
| download | pubnub-python-b89bc8cb03f0534805c2112d5fa4253f82ab616f.tar.bz2 | |
adding open/close files for door, new humid/temp sensor
Diffstat (limited to 'python')
32 files changed, 2286 insertions, 0 deletions
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<base>_<number> + 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 Binary files differnew file mode 100644 index 0000000..b0da7fa --- /dev/null +++ b/python/examples/Adafruit_Python_DHT/dist/Adafruit_DHT-1.0.0-py2.7-linux-armv6l.egg 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 <stdlib.h> +#include <string.h> + +#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<base>_<number>, 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 <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + +#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 <stdio.h> + #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 <stdint.h> + +#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 <stdbool.h> +#include <stdlib.h> + +#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 <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#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 <stdint.h> + +#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 <stdlib.h> + +#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 <Python.h> + +#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 <Python.h> + +#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 <Python.h> + +#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 <errno.h> +#include <sched.h> +#include <string.h> +#include <sys/time.h> +#include <time.h> + +#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 <stdint.h> + +// 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) |
