mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Merge pull request #275 from waveform80/last-minute-12
Last minute changes for 1.2
This commit is contained in:
@@ -5,7 +5,7 @@ Changelog
|
||||
.. currentmodule:: gpiozero
|
||||
|
||||
|
||||
Release 1.2.0 (2016-04-??)
|
||||
Release 1.2.0 (2016-04-10)
|
||||
==========================
|
||||
|
||||
* 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
|
||||
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
|
||||
.. _#109: https://github.com/RPi-Distro/python-gpiozero/issues/109
|
||||
|
||||
@@ -51,6 +51,8 @@ from .exc import (
|
||||
GPIOZeroWarning,
|
||||
SPIWarning,
|
||||
SPISoftwareFallback,
|
||||
PinWarning,
|
||||
PinNonPhysical,
|
||||
)
|
||||
from .devices import (
|
||||
Device,
|
||||
|
||||
@@ -121,3 +121,9 @@ class SPIWarning(GPIOZeroWarning):
|
||||
class SPISoftwareFallback(SPIWarning):
|
||||
"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`.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._hold_thread = None
|
||||
super(HoldMixin, self).__init__(*args, **kwargs)
|
||||
self._when_held = 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}, ),
|
||||
'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}, ),
|
||||
#'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}, ),
|
||||
#'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}, ),
|
||||
#'a22082': ('3B', '1.2', '2016Q1', 'BCM2837', 'Embest', 1024, 'MicroSD', 4, 1, True, True, 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}, ),
|
||||
'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}, ),
|
||||
'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
|
||||
something like "GPIO9" for Broadcom GPIO pin 9.
|
||||
"""
|
||||
header, number = self.physical_pin(function)
|
||||
return self.headers[header][number].pull_up
|
||||
try:
|
||||
header, number = self.physical_pin(function)
|
||||
except PinNoPins:
|
||||
return False
|
||||
else:
|
||||
return self.headers[header][number].pull_up
|
||||
|
||||
|
||||
_PI_REVISION = None
|
||||
|
||||
@@ -12,6 +12,7 @@ import os
|
||||
import mmap
|
||||
import errno
|
||||
import struct
|
||||
import warnings
|
||||
from time import sleep
|
||||
from threading import Thread, Event, Lock
|
||||
from collections import Counter
|
||||
@@ -24,6 +25,8 @@ from ..exc import (
|
||||
PinInvalidFunction,
|
||||
PinFixedPull,
|
||||
PinSetInput,
|
||||
PinNonPhysical,
|
||||
PinNoPins,
|
||||
)
|
||||
|
||||
|
||||
@@ -213,7 +216,12 @@ class NativePin(Pin):
|
||||
return cls._PINS[number]
|
||||
except KeyError:
|
||||
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._func_offset = self._MEM.GPFSEL_OFFSET + (number // 10)
|
||||
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.bounce = None
|
||||
self.edges = 'both'
|
||||
cls._PINS[number] = self
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -6,6 +6,7 @@ from __future__ import (
|
||||
)
|
||||
str = type('')
|
||||
|
||||
import warnings
|
||||
import pigpio
|
||||
|
||||
from . import Pin
|
||||
@@ -17,6 +18,8 @@ from ..exc import (
|
||||
PinInvalidPull,
|
||||
PinInvalidBounce,
|
||||
PinInvalidState,
|
||||
PinNonPhysical,
|
||||
PinNoPins,
|
||||
)
|
||||
|
||||
|
||||
@@ -107,12 +110,17 @@ class PiGPIOPin(Pin):
|
||||
return cls._PINS[(host, port, number)]
|
||||
except KeyError:
|
||||
self = super(PiGPIOPin, cls).__new__(cls)
|
||||
cls._PINS[(host, port, number)] = self
|
||||
try:
|
||||
self._connection = cls._CONNECTIONS[(host, port)]
|
||||
except KeyError:
|
||||
self._connection = pigpio.pi(host, port)
|
||||
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._port = port
|
||||
self._number = number
|
||||
@@ -125,11 +133,11 @@ class PiGPIOPin(Pin):
|
||||
try:
|
||||
self._connection.set_mode(self._number, pigpio.INPUT)
|
||||
except pigpio.error as e:
|
||||
del cls._PINS[(host, port, number)]
|
||||
raise ValueError(e)
|
||||
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_PWM_range(self._number, 255)
|
||||
cls._PINS[(host, port, number)] = self
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -6,6 +6,7 @@ from __future__ import (
|
||||
)
|
||||
str = type('')
|
||||
|
||||
import warnings
|
||||
from RPi import GPIO
|
||||
|
||||
from . import Pin
|
||||
@@ -18,6 +19,8 @@ from ..exc import (
|
||||
PinInvalidState,
|
||||
PinInvalidBounce,
|
||||
PinPWMFixedValue,
|
||||
PinNonPhysical,
|
||||
PinNoPins,
|
||||
)
|
||||
|
||||
|
||||
@@ -84,7 +87,12 @@ class RPiGPIOPin(Pin):
|
||||
return cls._PINS[number]
|
||||
except KeyError:
|
||||
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._pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating'
|
||||
self._pwm = None
|
||||
@@ -94,6 +102,7 @@ class RPiGPIOPin(Pin):
|
||||
self._when_changed = None
|
||||
self._edges = GPIO.BOTH
|
||||
GPIO.setup(self._number, GPIO.IN, self.GPIO_PULL_UPS[self._pull])
|
||||
cls._PINS[number] = self
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -7,6 +7,7 @@ from __future__ import (
|
||||
str = type('')
|
||||
|
||||
|
||||
import warnings
|
||||
import RPIO
|
||||
import RPIO.PWM
|
||||
from RPIO.Exceptions import InvalidChannelException
|
||||
@@ -21,6 +22,8 @@ from ..exc import (
|
||||
PinInvalidBounce,
|
||||
PinInvalidState,
|
||||
PinPWMError,
|
||||
PinNonPhysical,
|
||||
PinNoPins,
|
||||
)
|
||||
|
||||
|
||||
@@ -81,7 +84,12 @@ class RPIOPin(Pin):
|
||||
return cls._PINS[number]
|
||||
except KeyError:
|
||||
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._pull = 'up' if cls.PI_INFO.pulled_up('GPIO%d' % number) else 'floating'
|
||||
self._pwm = False
|
||||
@@ -93,6 +101,7 @@ class RPIOPin(Pin):
|
||||
RPIO.setup(self._number, RPIO.IN, self.GPIO_PULL_UPS[self._pull])
|
||||
except InvalidChannelException as e:
|
||||
raise ValueError(e)
|
||||
cls._PINS[number] = self
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -16,7 +16,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
from itertools import cycle
|
||||
from math import sin, cos, radians
|
||||
from math import sin, cos, pi
|
||||
try:
|
||||
from statistics import mean
|
||||
except ImportError:
|
||||
@@ -285,12 +285,11 @@ def random_values():
|
||||
yield random()
|
||||
|
||||
|
||||
def sin_values():
|
||||
def sin_values(period=360):
|
||||
"""
|
||||
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
|
||||
that increments by one for each requested value. For example, to produce a
|
||||
"siren" effect with a couple of LEDs::
|
||||
+1) which repeats every *period* values. For example, to produce a "siren"
|
||||
effect with a couple of LEDs that repeats once a second::
|
||||
|
||||
from gpiozero import PWMLED
|
||||
from gpiozero.tools import sin_values, scaled, inverted
|
||||
@@ -300,22 +299,22 @@ def sin_values():
|
||||
blue = PWMLED(3)
|
||||
red.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)
|
||||
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)):
|
||||
yield sin(radians(d))
|
||||
angles = (2 * pi * i / period for i in range(period))
|
||||
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
|
||||
to +1), calculated as the result of applying sign to a simple degrees
|
||||
counter that increments by one for each requested value. For example, to
|
||||
produce a "siren" effect with a couple of LEDs::
|
||||
to +1) which repeats every *period* values. For example, to produce a
|
||||
"siren" effect with a couple of LEDs that repeats once a second::
|
||||
|
||||
from gpiozero import PWMLED
|
||||
from gpiozero.tools import cos_values, scaled, inverted
|
||||
@@ -325,12 +324,13 @@ def cos_values():
|
||||
blue = PWMLED(3)
|
||||
red.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)
|
||||
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)):
|
||||
yield cos(radians(d))
|
||||
angles = (2 * pi * i / period for i in range(period))
|
||||
for a in cycle(angles):
|
||||
yield cos(a)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user