mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
319 lines
8.3 KiB
Python
319 lines
8.3 KiB
Python
from .input_devices import Button
|
|
from .output_devices import LED, Buzzer, Motor
|
|
from .devices import GPIODeviceError
|
|
|
|
from time import sleep
|
|
|
|
|
|
class LEDBoard(object):
|
|
"""
|
|
A Generic LED Board or collection of LEDs.
|
|
"""
|
|
def __init__(self, leds):
|
|
self._leds = tuple(LED(led) for led in leds)
|
|
|
|
@property
|
|
def leds(self):
|
|
return self._leds
|
|
|
|
def on(self):
|
|
"""
|
|
Turn all the LEDs on.
|
|
"""
|
|
for led in self._leds:
|
|
led.on()
|
|
|
|
def off(self):
|
|
"""
|
|
Turn all the LEDs off.
|
|
"""
|
|
for led in self._leds:
|
|
led.off()
|
|
|
|
def toggle(self):
|
|
"""
|
|
Toggle all the LEDs. For each LED, if it's on, turn it off; if it's
|
|
off, turn it on.
|
|
"""
|
|
for led in self._leds:
|
|
led.toggle()
|
|
|
|
def blink(self, on_time=1, off_time=1, n=None, background=True):
|
|
"""
|
|
Make all the LEDs turn on and off repeatedly.
|
|
|
|
on_time: `1`
|
|
Number of seconds to be on
|
|
|
|
off_time: `1`
|
|
Number of seconds to be off
|
|
|
|
n: `None`
|
|
Number of times to blink; None means forever
|
|
|
|
background: `True`
|
|
If `True`, start a background thread to continue blinking and
|
|
return immediately. If `False`, only return when the blink is
|
|
finished (warning: the default value of `n` will result in this
|
|
method never returning).
|
|
"""
|
|
for led in self._leds:
|
|
led.blink(on_time, off_time, n, background)
|
|
|
|
|
|
class PiLiter(LEDBoard):
|
|
"""
|
|
Ciseco Pi-LITEr: strip of 8 very bright LEDs.
|
|
"""
|
|
def __init__(self):
|
|
leds = (4, 17, 27, 18, 22, 23, 24, 25)
|
|
super(PiLiter, self).__init__(leds)
|
|
|
|
|
|
class TrafficLights(LEDBoard):
|
|
"""
|
|
Generic Traffic Lights set.
|
|
|
|
red: `None`
|
|
Red LED pin
|
|
|
|
amber: `None`
|
|
Amber LED pin
|
|
|
|
green: `None`
|
|
Green LED pin
|
|
"""
|
|
def __init__(self, red=None, amber=None, green=None):
|
|
if not all([red, amber, green]):
|
|
raise GPIODeviceError('Red, Amber and Green pins must be provided')
|
|
|
|
self.red = LED(red)
|
|
self.amber = LED(amber)
|
|
self.green = LED(green)
|
|
self._leds = (self.red, self.amber, self.green)
|
|
|
|
|
|
class PiTraffic(TrafficLights):
|
|
"""
|
|
Low Voltage Labs PI-TRAFFIC: vertical traffic lights board on pins 9, 10
|
|
and 11.
|
|
"""
|
|
def __init__(self):
|
|
red, amber, green = (9, 10, 11)
|
|
super(PiTraffic, self).__init__(red, amber, green)
|
|
|
|
|
|
class FishDish(TrafficLights):
|
|
"""
|
|
Pi Supply FishDish: traffic light LEDs, a button and a buzzer.
|
|
"""
|
|
def __init__(self):
|
|
red, amber, green = (9, 22, 4)
|
|
super(FishDish, self).__init__(red, amber, green)
|
|
self.buzzer = Buzzer(8)
|
|
self.button = Button(pin=7, pull_up=False)
|
|
self._all = self._leds + (self.buzzer,)
|
|
|
|
@property
|
|
def all(self):
|
|
return self._all
|
|
|
|
def on(self):
|
|
"""
|
|
Turn all the board's components on.
|
|
"""
|
|
for thing in self._all:
|
|
thing.on()
|
|
|
|
def off(self):
|
|
"""
|
|
Turn all the board's components off.
|
|
"""
|
|
for thing in self._all:
|
|
thing.off()
|
|
|
|
def toggle(self):
|
|
"""
|
|
Toggle all the board's components. For each component, if it's on, turn
|
|
it off; if it's off, turn it on.
|
|
"""
|
|
for thing in self._all:
|
|
thing.toggle()
|
|
|
|
def blink(self, on_time=1, off_time=1, n=None, background=True):
|
|
"""
|
|
Make all the board's components turn on and off repeatedly.
|
|
|
|
on_time: `1`
|
|
Number of seconds to be on
|
|
|
|
off_time: `1`
|
|
Number of seconds to be off
|
|
|
|
n: `None`
|
|
Number of times to blink; None means forever
|
|
|
|
background: `True`
|
|
If `True`, start a background thread to continue blinking and
|
|
return immediately. If `False`, only return when the blink is
|
|
finished (warning: the default value of `n` will result in this
|
|
method never returning).
|
|
"""
|
|
for thing in self._all:
|
|
led.blink(on_time, off_time, n, background)
|
|
|
|
def lights_on(self):
|
|
"""
|
|
Turn all the board's LEDs on.
|
|
"""
|
|
super(FishDish, self).on()
|
|
|
|
def lights_off(self):
|
|
"""
|
|
Turn all the board's LEDs off.
|
|
"""
|
|
super(FishDish, self).off()
|
|
|
|
def toggle_lights(self):
|
|
"""
|
|
Toggle all the board's LEDs. For each LED, if it's on, turn
|
|
it off; if it's off, turn it on.
|
|
"""
|
|
super(FishDish, self).toggle()
|
|
|
|
def blink_lights(self, on_time=1, off_time=1, n=None, background=True):
|
|
"""
|
|
Make all the board's LEDs turn on and off repeatedly.
|
|
|
|
on_time: `1`
|
|
Number of seconds to be on
|
|
|
|
off_time: `1`
|
|
Number of seconds to be off
|
|
|
|
n: `None`
|
|
Number of times to blink; None means forever
|
|
|
|
background: `True`
|
|
If `True`, start a background thread to continue blinking and
|
|
return immediately. If `False`, only return when the blink is
|
|
finished (warning: the default value of `n` will result in this
|
|
method never returning).
|
|
"""
|
|
super(FishDish, self).blink(on_time, off_time, n, background)
|
|
|
|
|
|
class TrafficHat(FishDish):
|
|
"""
|
|
Ryanteck Traffic HAT: traffic light LEDs, a button and a buzzer.
|
|
"""
|
|
def __init__(self):
|
|
green, amber, red = (22, 23, 24)
|
|
super(FishDish, self).__init__(red, amber, green)
|
|
self.buzzer = Buzzer(5)
|
|
self.button = Button(25)
|
|
self._all = self._leds + (self.buzzer,)
|
|
|
|
|
|
class Robot(object):
|
|
"""
|
|
Generic dual-motor Robot.
|
|
"""
|
|
def __init__(self, left=None, right=None):
|
|
if not all([left, right]):
|
|
raise GPIODeviceError('left and right motor pins must be provided')
|
|
|
|
left_forward, left_back = left
|
|
right_forward, right_back = right
|
|
|
|
self._left = Motor(forward=left_forward, back=left_back)
|
|
self._right = Motor(forward=right_forward, back=right_back)
|
|
|
|
self._min_pwm = self._left._min_pwm
|
|
self._max_pwm = self._left._max_pwm
|
|
|
|
def forward(self, speed=1):
|
|
"""
|
|
Drive the robot forward.
|
|
|
|
speed: `1`
|
|
Speed at which to drive the motors, 0 to 1.
|
|
"""
|
|
self._left._backward.off()
|
|
self._right._backward.off()
|
|
|
|
self._left._forward.on()
|
|
self._right._forward.on()
|
|
if speed < 1:
|
|
sleep(0.1) # warm up the motors
|
|
self._left._forward.value = speed
|
|
self._right._forward.value = speed
|
|
|
|
def backward(self, speed=1):
|
|
"""
|
|
Drive the robot backward.
|
|
|
|
speed: `1`
|
|
Speed at which to drive the motors, 0 to 1.
|
|
"""
|
|
self._left._forward.off()
|
|
self._right._forward.off()
|
|
|
|
self._left._backward.on()
|
|
self._right._backward.on()
|
|
if speed < 1:
|
|
sleep(0.1) # warm up the motors
|
|
self._left._backward.value = speed
|
|
self._right._backward.value = speed
|
|
|
|
def left(self, speed=1):
|
|
"""
|
|
Make the robot turn left.
|
|
|
|
speed: `1`
|
|
Speed at which to drive the motors, 0 to 1.
|
|
"""
|
|
self._right._backward.off()
|
|
self._left._forward.off()
|
|
|
|
self._right._forward.on()
|
|
self._left._backward.on()
|
|
if speed < 1:
|
|
sleep(0.1) # warm up the motors
|
|
self._right._forward.value = speed
|
|
self._left._backward.value = speed
|
|
|
|
def right(self, speed=1):
|
|
"""
|
|
Make the robot turn right.
|
|
|
|
speed: `1`
|
|
Speed at which to drive the motors, 0 to 1.
|
|
"""
|
|
self._left._backward.off()
|
|
self._right._forward.off()
|
|
|
|
self._left._forward.on()
|
|
self._right._backward.on()
|
|
if speed < 1:
|
|
sleep(0.1) # warm up the motors
|
|
self._left._forward.value = speed
|
|
self._right._backward.value = speed
|
|
|
|
def stop(self):
|
|
"""
|
|
Stop the robot.
|
|
"""
|
|
self._left.stop()
|
|
self._right.stop()
|
|
|
|
|
|
class RyanteckRobot(Robot):
|
|
"""
|
|
RTK MCB Robot. Generic robot controller with pre-configured pin numbers.
|
|
"""
|
|
def __init__(self):
|
|
left = (17, 18)
|
|
right = (22, 23)
|
|
super(RyanteckRobot, self).__init__(left=left, right=right)
|