mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			188 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from time import sleep
 | |
| from threading import Lock
 | |
| from itertools import repeat
 | |
| 
 | |
| from RPi import GPIO
 | |
| 
 | |
| from .devices import GPIODeviceError, GPIODevice, GPIOThread
 | |
| 
 | |
| 
 | |
| class OutputDeviceError(GPIODeviceError):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class OutputDevice(GPIODevice):
 | |
|     """
 | |
|     Generic GPIO Output Device (on/off).
 | |
|     """
 | |
|     def __init__(self, pin=None):
 | |
|         super(OutputDevice, self).__init__(pin)
 | |
|         GPIO.setup(pin, GPIO.OUT)
 | |
| 
 | |
|     def on(self):
 | |
|         """
 | |
|         Turns the device on.
 | |
|         """
 | |
|         GPIO.output(self.pin, True)
 | |
| 
 | |
|     def off(self):
 | |
|         """
 | |
|         Turns the device off.
 | |
|         """
 | |
|         GPIO.output(self.pin, False)
 | |
| 
 | |
| 
 | |
| class DigitalOutputDevice(OutputDevice):
 | |
|     """
 | |
|     Generic Digital GPIO Output Device (on/off/toggle/blink).
 | |
|     """
 | |
|     def __init__(self, pin=None):
 | |
|         super(DigitalOutputDevice, self).__init__(pin)
 | |
|         self._blink_thread = None
 | |
|         self._lock = Lock()
 | |
| 
 | |
|     def on(self):
 | |
|         """
 | |
|         Turns the device on.
 | |
|         """
 | |
|         self._stop_blink()
 | |
|         super(DigitalOutputDevice, self).on()
 | |
| 
 | |
|     def off(self):
 | |
|         """
 | |
|         Turns the device off.
 | |
|         """
 | |
|         self._stop_blink()
 | |
|         super(DigitalOutputDevice, self).off()
 | |
| 
 | |
|     def toggle(self):
 | |
|         """
 | |
|         Reverse the state of the device.
 | |
|         If it's on, turn it off; if it's off, turn it on.
 | |
|         """
 | |
|         with self._lock:
 | |
|             if self.is_active:
 | |
|                 self.off()
 | |
|             else:
 | |
|                 self.on()
 | |
| 
 | |
|     def blink(self, on_time=1, off_time=1, n=None, background=True):
 | |
|         """
 | |
|         Make the device turn on and off repeatedly.
 | |
| 
 | |
|         on_time: 1
 | |
|             Number of seconds on
 | |
| 
 | |
|         off_time: 1
 | |
|             Number of seconds 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).
 | |
|         """
 | |
|         self._stop_blink()
 | |
|         self._blink_thread = GPIOThread(
 | |
|             target=self._blink_led, args=(on_time, off_time, n)
 | |
|         )
 | |
|         self._blink_thread.start()
 | |
|         if not background:
 | |
|             self._blink_thread.join()
 | |
|             self._blink_thread = None
 | |
| 
 | |
|     def _stop_blink(self):
 | |
|         if self._blink_thread:
 | |
|             self._blink_thread.stop()
 | |
|             self._blink_thread = None
 | |
| 
 | |
|     def _blink_led(self, on_time, off_time, n):
 | |
|         iterable = repeat(0) if n is None else repeat(0, n)
 | |
|         for i in iterable:
 | |
|             super(DigitalOutputDevice, self).on()
 | |
|             if self._blink_thread.stopping.wait(on_time):
 | |
|                 break
 | |
|             super(DigitalOutputDevice, self).off()
 | |
|             if self._blink_thread.stopping.wait(off_time):
 | |
|                 break
 | |
| 
 | |
| 
 | |
| class LED(DigitalOutputDevice):
 | |
|     """
 | |
|     An LED (Light Emmitting Diode) component.
 | |
|     """
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class Buzzer(DigitalOutputDevice):
 | |
|     """
 | |
|     A digital Buzzer component.
 | |
|     """
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class Motor(OutputDevice):
 | |
|     """
 | |
|     Generic single-direction motor.
 | |
|     """
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class Robot(object):
 | |
|     """
 | |
|     Generic single-direction dual-motor Robot.
 | |
|     """
 | |
|     def __init__(self, left=None, right=None):
 | |
|         if not all([left, right]):
 | |
|             raise GPIODeviceError('left and right pins must be provided')
 | |
| 
 | |
|         self._left = Motor(left)
 | |
|         self._right = Motor(right)
 | |
| 
 | |
|     def left(self, seconds=None):
 | |
|         """
 | |
|         Turns left for a given number of seconds.
 | |
| 
 | |
|         seconds: None
 | |
|             Number of seconds to turn left for
 | |
|         """
 | |
|         self._left.on()
 | |
|         if seconds is not None:
 | |
|             sleep(seconds)
 | |
|             self._left.off()
 | |
| 
 | |
|     def right(self, seconds=None):
 | |
|         """
 | |
|         Turns right for a given number of seconds.
 | |
| 
 | |
|         seconds: None
 | |
|             Number of seconds to turn right for
 | |
|         """
 | |
|         self._right.on()
 | |
|         if seconds is not None:
 | |
|             sleep(seconds)
 | |
|             self._right.off()
 | |
| 
 | |
|     def forwards(self, seconds=None):
 | |
|         """
 | |
|         Drives forward for a given number of seconds.
 | |
| 
 | |
|         seconds: None
 | |
|             Number of seconds to drive forward for
 | |
|         """
 | |
|         self.left()
 | |
|         self.right()
 | |
|         if seconds is not None:
 | |
|             sleep(seconds)
 | |
|             self.stop()
 | |
| 
 | |
|     def stop(self):
 | |
|         """
 | |
|         Stops both motors.
 | |
|         """
 | |
|         self._left.off()
 | |
|         self._right.off()
 |