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:
Dave Jones
2016-04-10 19:29:46 +01:00
parent e2b8171bbb
commit f82ddad1fc
10 changed files with 88 additions and 31 deletions

View File

@@ -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

View File

@@ -51,6 +51,8 @@ from .exc import (
GPIOZeroWarning,
SPIWarning,
SPISoftwareFallback,
PinWarning,
PinNonPhysical,
)
from .devices import (
Device,

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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)