mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	Last minute changes for 1.2
Warnings about non-physical pins, and period specification for sin/cosine waves in tools
This commit is contained in:
		| @@ -5,7 +5,7 @@ Changelog | |||||||
| .. currentmodule:: gpiozero | .. currentmodule:: gpiozero | ||||||
|  |  | ||||||
|  |  | ||||||
| Release 1.2.0 (2016-04-??) | Release 1.2.0 (2016-04-10) | ||||||
| ========================== | ========================== | ||||||
|  |  | ||||||
| * Added :class:`Energenie` class for controlling Energenie plugs (`#69`_) | * Added :class:`Energenie` class for controlling Energenie plugs (`#69`_) | ||||||
| @@ -32,7 +32,16 @@ Release 1.2.0 (2016-04-??) | |||||||
|  |  | ||||||
| And I'll just add a note of thanks to the many people in the community who | And I'll just add a note of thanks to the many people in the community who | ||||||
| contributed to this release: we've had some great PRs, suggestions, and bug | contributed to this release: we've had some great PRs, suggestions, and bug | ||||||
| reports in this version - keep 'em coming! | reports in this version. Of particular note: | ||||||
|  |  | ||||||
|  | * Schelto van Doorn was instrumental in adding support for numerous ADC chips | ||||||
|  | * Alex Eames generously donated a RasPiO Analog board which was extremely | ||||||
|  |   useful in developing the software SPI interface (and testing the ADC support) | ||||||
|  | * Andrew Scheller squashed several dozen bugs (usually a day or so after Dave | ||||||
|  |   had introduced them ;) | ||||||
|  |  | ||||||
|  | As always, many thanks to the whole community - we look forward to hearing from | ||||||
|  | you more in 1.3! | ||||||
|  |  | ||||||
| .. _#69: https://github.com/RPi-Distro/python-gpiozero/issues/69 | .. _#69: https://github.com/RPi-Distro/python-gpiozero/issues/69 | ||||||
| .. _#109: https://github.com/RPi-Distro/python-gpiozero/issues/109 | .. _#109: https://github.com/RPi-Distro/python-gpiozero/issues/109 | ||||||
|   | |||||||
| @@ -51,6 +51,8 @@ from .exc import ( | |||||||
|     GPIOZeroWarning, |     GPIOZeroWarning, | ||||||
|     SPIWarning, |     SPIWarning, | ||||||
|     SPISoftwareFallback, |     SPISoftwareFallback, | ||||||
|  |     PinWarning, | ||||||
|  |     PinNonPhysical, | ||||||
| ) | ) | ||||||
| from .devices import ( | from .devices import ( | ||||||
|     Device, |     Device, | ||||||
|   | |||||||
| @@ -121,3 +121,9 @@ class SPIWarning(GPIOZeroWarning): | |||||||
| class SPISoftwareFallback(SPIWarning): | class SPISoftwareFallback(SPIWarning): | ||||||
|     "Warning raised when falling back to the software implementation" |     "Warning raised when falling back to the software implementation" | ||||||
|  |  | ||||||
|  | class PinWarning(GPIOZeroWarning): | ||||||
|  |     "Base class for warnings related to pin implementations" | ||||||
|  |  | ||||||
|  | class PinNonPhysical(PinWarning): | ||||||
|  |     "Warning raised when a non-physical pin is specified in a constructor" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -322,6 +322,7 @@ class HoldMixin(EventsMixin): | |||||||
|     ``True``) at internals defined by :attr:`hold_time`. |     ``True``) at internals defined by :attr:`hold_time`. | ||||||
|     """ |     """ | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
|  |         self._hold_thread = None | ||||||
|         super(HoldMixin, self).__init__(*args, **kwargs) |         super(HoldMixin, self).__init__(*args, **kwargs) | ||||||
|         self._when_held = None |         self._when_held = None | ||||||
|         self._held_from = None |         self._held_from = None | ||||||
|   | |||||||
| @@ -261,11 +261,11 @@ PI_REVISIONS = { | |||||||
|     '0013':   ('B+',   '1.2', '2015Q1', 'BCM2835', 'Egoman',    512,  'MicroSD', 4,  1,  False, False, 1,  1,  {'P1': PLUS_P1},               ), |     '0013':   ('B+',   '1.2', '2015Q1', 'BCM2835', 'Egoman',    512,  'MicroSD', 4,  1,  False, False, 1,  1,  {'P1': PLUS_P1},               ), | ||||||
|     '0014':   ('CM',   '1.1', '2014Q2', 'BCM2835', 'Sony',      512,  'eMMC',    0,  0,  False, False, 2,  2,  {'SODIMM': CM_SODIMM},         ), |     '0014':   ('CM',   '1.1', '2014Q2', 'BCM2835', 'Sony',      512,  'eMMC',    0,  0,  False, False, 2,  2,  {'SODIMM': CM_SODIMM},         ), | ||||||
|     '0015':   ('A+',   '1.1', '2014Q4', 'BCM2835', 'Sony',      256,  'MicroSD', 1,  0,  False, False, 1,  1,  {'P1': PLUS_P1},               ), |     '0015':   ('A+',   '1.1', '2014Q4', 'BCM2835', 'Sony',      256,  'MicroSD', 1,  0,  False, False, 1,  1,  {'P1': PLUS_P1},               ), | ||||||
|     #'a01041': ('2B',   '1.1', '2015Q1', 'BCM2836', 'Sony',      1024, 'MicroSD', 4,  1,  False, False, 1,  1,  {'P1': PLUS_P1},               ), |     'a01041': ('2B',   '1.1', '2015Q1', 'BCM2836', 'Sony',      1024, 'MicroSD', 4,  1,  False, False, 1,  1,  {'P1': PLUS_P1},               ), | ||||||
|     #'a21041': ('2B',   '1.1', '2015Q1', 'BCM2836', 'Embest',    1024, 'MicroSD', 4,  1,  False, False, 1,  1,  {'P1': PLUS_P1},               ), |     'a21041': ('2B',   '1.1', '2015Q1', 'BCM2836', 'Embest',    1024, 'MicroSD', 4,  1,  False, False, 1,  1,  {'P1': PLUS_P1},               ), | ||||||
|     #'900092': ('Zero', '1.2', '2015Q4', 'BCM2835', 'Sony',      512,  'MicroSD', 1,  0,  False, False, 0,  0,  {'P1': PLUS_P1},               ), |     '900092': ('Zero', '1.2', '2015Q4', 'BCM2835', 'Sony',      512,  'MicroSD', 1,  0,  False, False, 0,  0,  {'P1': PLUS_P1},               ), | ||||||
|     #'a02082': ('3B',   '1.2', '2016Q1', 'BCM2837', 'Sony',      1024, 'MicroSD', 4,  1,  True,  True,  1,  1,  {'P1': PLUS_P1},               ), |     'a02082': ('3B',   '1.2', '2016Q1', 'BCM2837', 'Sony',      1024, 'MicroSD', 4,  1,  True,  True,  1,  1,  {'P1': PLUS_P1},               ), | ||||||
|     #'a22082': ('3B',   '1.2', '2016Q1', 'BCM2837', 'Embest',    1024, 'MicroSD', 4,  1,  True,  True,  1,  1,  {'P1': PLUS_P1},               ), |     'a22082': ('3B',   '1.2', '2016Q1', 'BCM2837', 'Embest',    1024, 'MicroSD', 4,  1,  True,  True,  1,  1,  {'P1': PLUS_P1},               ), | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -479,8 +479,12 @@ class PiBoardInfo(namedtuple('PiBoardInfo', ( | |||||||
|             The pin function you wish to determine pull-up for. Usually this is |             The pin function you wish to determine pull-up for. Usually this is | ||||||
|             something like "GPIO9" for Broadcom GPIO pin 9. |             something like "GPIO9" for Broadcom GPIO pin 9. | ||||||
|         """ |         """ | ||||||
|         header, number = self.physical_pin(function) |         try: | ||||||
|         return self.headers[header][number].pull_up |             header, number = self.physical_pin(function) | ||||||
|  |         except PinNoPins: | ||||||
|  |             return False | ||||||
|  |         else: | ||||||
|  |             return self.headers[header][number].pull_up | ||||||
|  |  | ||||||
|  |  | ||||||
| _PI_REVISION = None | _PI_REVISION = None | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import os | |||||||
| import mmap | import mmap | ||||||
| import errno | import errno | ||||||
| import struct | import struct | ||||||
|  | import warnings | ||||||
| from time import sleep | from time import sleep | ||||||
| from threading import Thread, Event, Lock | from threading import Thread, Event, Lock | ||||||
| from collections import Counter | from collections import Counter | ||||||
| @@ -24,6 +25,8 @@ from ..exc import ( | |||||||
|     PinInvalidFunction, |     PinInvalidFunction, | ||||||
|     PinFixedPull, |     PinFixedPull, | ||||||
|     PinSetInput, |     PinSetInput, | ||||||
|  |     PinNonPhysical, | ||||||
|  |     PinNoPins, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -213,7 +216,12 @@ class NativePin(Pin): | |||||||
|             return cls._PINS[number] |             return cls._PINS[number] | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             self = super(NativePin, cls).__new__(cls) |             self = super(NativePin, cls).__new__(cls) | ||||||
|             cls._PINS[number] = self |             try: | ||||||
|  |                 cls.PI_INFO.physical_pin('GPIO%d' % number) | ||||||
|  |             except PinNoPins: | ||||||
|  |                 warnings.warn( | ||||||
|  |                     PinNonPhysical( | ||||||
|  |                         'no physical pins exist for GPIO%d' % number)) | ||||||
|             self._number = number |             self._number = number | ||||||
|             self._func_offset = self._MEM.GPFSEL_OFFSET + (number // 10) |             self._func_offset = self._MEM.GPFSEL_OFFSET + (number // 10) | ||||||
|             self._func_shift = (number % 10) * 3 |             self._func_shift = (number % 10) * 3 | ||||||
| @@ -238,6 +246,7 @@ class NativePin(Pin): | |||||||
|             self.pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating' |             self.pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating' | ||||||
|             self.bounce = None |             self.bounce = None | ||||||
|             self.edges = 'both' |             self.edges = 'both' | ||||||
|  |             cls._PINS[number] = self | ||||||
|             return self |             return self | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ from __future__ import ( | |||||||
|     ) |     ) | ||||||
| str = type('') | str = type('') | ||||||
|  |  | ||||||
|  | import warnings | ||||||
| import pigpio | import pigpio | ||||||
|  |  | ||||||
| from . import Pin | from . import Pin | ||||||
| @@ -17,6 +18,8 @@ from ..exc import ( | |||||||
|     PinInvalidPull, |     PinInvalidPull, | ||||||
|     PinInvalidBounce, |     PinInvalidBounce, | ||||||
|     PinInvalidState, |     PinInvalidState, | ||||||
|  |     PinNonPhysical, | ||||||
|  |     PinNoPins, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -107,12 +110,17 @@ class PiGPIOPin(Pin): | |||||||
|             return cls._PINS[(host, port, number)] |             return cls._PINS[(host, port, number)] | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             self = super(PiGPIOPin, cls).__new__(cls) |             self = super(PiGPIOPin, cls).__new__(cls) | ||||||
|             cls._PINS[(host, port, number)] = self |  | ||||||
|             try: |             try: | ||||||
|                 self._connection = cls._CONNECTIONS[(host, port)] |                 self._connection = cls._CONNECTIONS[(host, port)] | ||||||
|             except KeyError: |             except KeyError: | ||||||
|                 self._connection = pigpio.pi(host, port) |                 self._connection = pigpio.pi(host, port) | ||||||
|                 cls._CONNECTIONS[(host, port)] = self._connection |                 cls._CONNECTIONS[(host, port)] = self._connection | ||||||
|  |             try: | ||||||
|  |                 cls.PI_INFO.physical_pin('GPIO%d' % number) | ||||||
|  |             except PinNoPins: | ||||||
|  |                 warnings.warn( | ||||||
|  |                     PinNonPhysical( | ||||||
|  |                         'no physical pins exist for GPIO%d' % number)) | ||||||
|             self._host = host |             self._host = host | ||||||
|             self._port = port |             self._port = port | ||||||
|             self._number = number |             self._number = number | ||||||
| @@ -125,11 +133,11 @@ class PiGPIOPin(Pin): | |||||||
|             try: |             try: | ||||||
|                 self._connection.set_mode(self._number, pigpio.INPUT) |                 self._connection.set_mode(self._number, pigpio.INPUT) | ||||||
|             except pigpio.error as e: |             except pigpio.error as e: | ||||||
|                 del cls._PINS[(host, port, number)] |  | ||||||
|                 raise ValueError(e) |                 raise ValueError(e) | ||||||
|             self._connection.set_pull_up_down(self._number, self.GPIO_PULL_UPS[self._pull]) |             self._connection.set_pull_up_down(self._number, self.GPIO_PULL_UPS[self._pull]) | ||||||
|             self._connection.set_glitch_filter(self._number, 0) |             self._connection.set_glitch_filter(self._number, 0) | ||||||
|             self._connection.set_PWM_range(self._number, 255) |             self._connection.set_PWM_range(self._number, 255) | ||||||
|  |             cls._PINS[(host, port, number)] = self | ||||||
|             return self |             return self | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ from __future__ import ( | |||||||
|     ) |     ) | ||||||
| str = type('') | str = type('') | ||||||
|  |  | ||||||
|  | import warnings | ||||||
| from RPi import GPIO | from RPi import GPIO | ||||||
|  |  | ||||||
| from . import Pin | from . import Pin | ||||||
| @@ -18,6 +19,8 @@ from ..exc import ( | |||||||
|     PinInvalidState, |     PinInvalidState, | ||||||
|     PinInvalidBounce, |     PinInvalidBounce, | ||||||
|     PinPWMFixedValue, |     PinPWMFixedValue, | ||||||
|  |     PinNonPhysical, | ||||||
|  |     PinNoPins, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -84,7 +87,12 @@ class RPiGPIOPin(Pin): | |||||||
|             return cls._PINS[number] |             return cls._PINS[number] | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             self = super(RPiGPIOPin, cls).__new__(cls) |             self = super(RPiGPIOPin, cls).__new__(cls) | ||||||
|             cls._PINS[number] = self |             try: | ||||||
|  |                 cls.PI_INFO.physical_pin('GPIO%d' % number) | ||||||
|  |             except PinNoPins: | ||||||
|  |                 warnings.warn( | ||||||
|  |                     PinNonPhysical( | ||||||
|  |                         'no physical pins exist for GPIO%d' % number)) | ||||||
|             self._number = number |             self._number = number | ||||||
|             self._pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating' |             self._pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating' | ||||||
|             self._pwm = None |             self._pwm = None | ||||||
| @@ -94,6 +102,7 @@ class RPiGPIOPin(Pin): | |||||||
|             self._when_changed = None |             self._when_changed = None | ||||||
|             self._edges = GPIO.BOTH |             self._edges = GPIO.BOTH | ||||||
|             GPIO.setup(self._number, GPIO.IN, self.GPIO_PULL_UPS[self._pull]) |             GPIO.setup(self._number, GPIO.IN, self.GPIO_PULL_UPS[self._pull]) | ||||||
|  |             cls._PINS[number] = self | ||||||
|             return self |             return self | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ from __future__ import ( | |||||||
| str = type('') | str = type('') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import warnings | ||||||
| import RPIO | import RPIO | ||||||
| import RPIO.PWM | import RPIO.PWM | ||||||
| from RPIO.Exceptions import InvalidChannelException | from RPIO.Exceptions import InvalidChannelException | ||||||
| @@ -21,6 +22,8 @@ from ..exc import ( | |||||||
|     PinInvalidBounce, |     PinInvalidBounce, | ||||||
|     PinInvalidState, |     PinInvalidState, | ||||||
|     PinPWMError, |     PinPWMError, | ||||||
|  |     PinNonPhysical, | ||||||
|  |     PinNoPins, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -81,7 +84,12 @@ class RPIOPin(Pin): | |||||||
|             return cls._PINS[number] |             return cls._PINS[number] | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             self = super(RPIOPin, cls).__new__(cls) |             self = super(RPIOPin, cls).__new__(cls) | ||||||
|             cls._PINS[number] = self |             try: | ||||||
|  |                 cls.PI_INFO.physical_pin('GPIO%d' % number) | ||||||
|  |             except PinNoPins: | ||||||
|  |                 warnings.warn( | ||||||
|  |                     PinNonPhysical( | ||||||
|  |                         'no physical pins exist for GPIO%d' % number)) | ||||||
|             self._number = number |             self._number = number | ||||||
|             self._pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating' |             self._pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating' | ||||||
|             self._pwm = False |             self._pwm = False | ||||||
| @@ -93,6 +101,7 @@ class RPIOPin(Pin): | |||||||
|                 RPIO.setup(self._number, RPIO.IN, self.GPIO_PULL_UPS[self._pull]) |                 RPIO.setup(self._number, RPIO.IN, self.GPIO_PULL_UPS[self._pull]) | ||||||
|             except InvalidChannelException as e: |             except InvalidChannelException as e: | ||||||
|                 raise ValueError(e) |                 raise ValueError(e) | ||||||
|  |             cls._PINS[number] = self | ||||||
|             return self |             return self | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ try: | |||||||
| except ImportError: | except ImportError: | ||||||
|     pass |     pass | ||||||
| from itertools import cycle | from itertools import cycle | ||||||
| from math import sin, cos, radians | from math import sin, cos, pi | ||||||
| try: | try: | ||||||
|     from statistics import mean |     from statistics import mean | ||||||
| except ImportError: | except ImportError: | ||||||
| @@ -285,12 +285,11 @@ def random_values(): | |||||||
|         yield random() |         yield random() | ||||||
|  |  | ||||||
|  |  | ||||||
| def sin_values(): | def sin_values(period=360): | ||||||
|     """ |     """ | ||||||
|     Provides an infinite source of values representing a sine wave (from -1 to |     Provides an infinite source of values representing a sine wave (from -1 to | ||||||
|     +1), calculated as the result of applying sign to a simple degrees counter |     +1) which repeats every *period* values. For example, to produce a "siren" | ||||||
|     that increments by one for each requested value. For example, to produce a |     effect with a couple of LEDs that repeats once a second:: | ||||||
|     "siren" effect with a couple of LEDs:: |  | ||||||
|  |  | ||||||
|         from gpiozero import PWMLED |         from gpiozero import PWMLED | ||||||
|         from gpiozero.tools import sin_values, scaled, inverted |         from gpiozero.tools import sin_values, scaled, inverted | ||||||
| @@ -300,22 +299,22 @@ def sin_values(): | |||||||
|         blue = PWMLED(3) |         blue = PWMLED(3) | ||||||
|         red.source_delay = 0.01 |         red.source_delay = 0.01 | ||||||
|         blue.source_delay = 0.01 |         blue.source_delay = 0.01 | ||||||
|         red.source = scaled(sin_values(), 0, 1, -1, 1) |         red.source = scaled(sin_values(100), 0, 1, -1, 1) | ||||||
|         blue.source = inverted(red.values) |         blue.source = inverted(red.values) | ||||||
|         pause() |         pause() | ||||||
|  |  | ||||||
|     If you require a wider range than 0 to 1, see :func:`scaled`. |     If you require a different range than -1 to +1, see :func:`scaled`. | ||||||
|     """ |     """ | ||||||
|     for d in cycle(range(360)): |     angles = (2 * pi * i / period for i in range(period)) | ||||||
|         yield sin(radians(d)) |     for a in cycle(angles): | ||||||
|  |         yield sin(a) | ||||||
|  |  | ||||||
|  |  | ||||||
| def cos_values(): | def cos_values(period=360): | ||||||
|     """ |     """ | ||||||
|     Provides an infinite source of values representing a cosine wave (from -1 |     Provides an infinite source of values representing a cosine wave (from -1 | ||||||
|     to +1), calculated as the result of applying sign to a simple degrees |     to +1) which repeats every *period* values. For example, to produce a | ||||||
|     counter that increments by one for each requested value. For example, to |     "siren" effect with a couple of LEDs that repeats once a second:: | ||||||
|     produce a "siren" effect with a couple of LEDs:: |  | ||||||
|  |  | ||||||
|         from gpiozero import PWMLED |         from gpiozero import PWMLED | ||||||
|         from gpiozero.tools import cos_values, scaled, inverted |         from gpiozero.tools import cos_values, scaled, inverted | ||||||
| @@ -325,12 +324,13 @@ def cos_values(): | |||||||
|         blue = PWMLED(3) |         blue = PWMLED(3) | ||||||
|         red.source_delay = 0.01 |         red.source_delay = 0.01 | ||||||
|         blue.source_delay = 0.01 |         blue.source_delay = 0.01 | ||||||
|         red.source = scaled(cos_values(), 0, 1, -1, 1) |         red.source = scaled(cos_values(100), 0, 1, -1, 1) | ||||||
|         blue.source = inverted(red.values) |         blue.source = inverted(red.values) | ||||||
|         pause() |         pause() | ||||||
|  |  | ||||||
|     If you require a wider range than 0 to 1, see :func:`scaled`. |     If you require a different range than -1 to +1, see :func:`scaled`. | ||||||
|     """ |     """ | ||||||
|     for d in cycle(range(360)): |     angles = (2 * pi * i / period for i in range(period)) | ||||||
|         yield cos(radians(d)) |     for a in cycle(angles): | ||||||
|  |         yield cos(a) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user