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