GPIO support based on gpiozero added. UNTESTED!
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
pip install pyqt5
|
||||
pip install opencv-python
|
||||
pip install Pillow
|
||||
pip install gpiozero
|
||||
apt install gphoto2 libgphoto2-dev
|
||||
|
||||
pip install gphoto2
|
||||
|
||||
38
photobooth/Gpio.py
Normal file
38
photobooth/Gpio.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from gpiozero import LED, Button
|
||||
|
||||
class Gpio:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self._buttons = []
|
||||
self._lamps = []
|
||||
|
||||
|
||||
def setButton(self, bcm_pin, handler):
|
||||
|
||||
self._buttons.append(Button(bcm_pin))
|
||||
self._buttons[-1].when_pressed = handler
|
||||
|
||||
|
||||
def setLamp(self, bcm_pin):
|
||||
|
||||
self._lamps.append(LED(bcm_pin))
|
||||
return len(self._lamps) - 1
|
||||
|
||||
|
||||
def lampOn(self, index):
|
||||
|
||||
self._lamps[index].on()
|
||||
|
||||
|
||||
def lampOff(self, index):
|
||||
|
||||
self._lamps[index].off()
|
||||
|
||||
|
||||
def lampToggle(self, index):
|
||||
|
||||
self._lamps[index].toggle()
|
||||
@@ -14,15 +14,21 @@ class Photobooth:
|
||||
|
||||
def __init__(self, config, camera):
|
||||
|
||||
picture_basename = strftime(config.get('Picture', 'basename'), localtime())
|
||||
self.initCamera(config, camera)
|
||||
self.initGpio(config)
|
||||
self.initTimings(config)
|
||||
|
||||
self.triggerOff()
|
||||
|
||||
|
||||
def initCamera(self, config, camera):
|
||||
|
||||
self._cap = camera
|
||||
self._pic_dims = PictureDimensions(config, self._cap.getPicture().size)
|
||||
self._pic_list = PictureList(picture_basename)
|
||||
|
||||
self._greeter_time = config.getInt('Photobooth', 'greeter_time')
|
||||
self._countdown_time = config.getInt('Photobooth', 'countdown_time')
|
||||
self._display_time = config.getInt('Photobooth', 'display_time')
|
||||
picture_basename = strftime(config.get('Picture', 'basename'), localtime())
|
||||
self._pic_list = PictureList(picture_basename)
|
||||
self._get_next_filename = self._pic_list.getNext
|
||||
|
||||
if ( config.getBool('Photobooth', 'show_preview')
|
||||
and self._cap.hasPreview ):
|
||||
@@ -30,7 +36,36 @@ class Photobooth:
|
||||
else:
|
||||
self._show_counter = self.showCounterNoPreview
|
||||
|
||||
self._get_next_filename = self._pic_list.getNext
|
||||
|
||||
def initGpio(self, config):
|
||||
|
||||
if config.getBool('Gpio', 'enable'):
|
||||
from Gpio import Gpio
|
||||
|
||||
self._gpio = Gpio()
|
||||
|
||||
lamp = self._gpio.setLamp(config.getInt('Gpio', 'lamp_pin'))
|
||||
self._lampOn = lambda : self._gpio.lampOn(lamp)
|
||||
self._lampOff = lambda : self._gpio.lampOff(lamp)
|
||||
|
||||
self._gpio.setButton(config.getInt('Gpio', 'trigger_pin'), self.gpioTrigger)
|
||||
self._gpio.setButton(config.getInt('Gpio', 'exit_pin'), self.teardown)
|
||||
else:
|
||||
self._lampOn = lambda : None
|
||||
self._lampOff = lambda : None
|
||||
|
||||
|
||||
def initTimings(self, config):
|
||||
|
||||
self._greeter_time = config.getInt('Photobooth', 'greeter_time')
|
||||
self._countdown_time = config.getInt('Photobooth', 'countdown_time')
|
||||
self._display_time = config.getInt('Photobooth', 'display_time')
|
||||
|
||||
|
||||
def teardown(self):
|
||||
|
||||
self.triggerOff()
|
||||
self.setCameraIdle()
|
||||
|
||||
|
||||
@property
|
||||
@@ -68,6 +103,7 @@ class Photobooth:
|
||||
self._send = send
|
||||
self.setCameraIdle()
|
||||
self._send.send(gui.IdleState())
|
||||
self.triggerOn()
|
||||
|
||||
while True:
|
||||
try:
|
||||
@@ -85,6 +121,7 @@ class Photobooth:
|
||||
self._send.send( gui.ErrorState('Camera error', str(e)) )
|
||||
event = recv.recv()
|
||||
if str(event) == 'cancel':
|
||||
self.teardown()
|
||||
return 1
|
||||
elif str(event) == 'ack':
|
||||
pass
|
||||
@@ -158,6 +195,7 @@ class Photobooth:
|
||||
def trigger(self):
|
||||
|
||||
self._send.send(gui.GreeterState())
|
||||
self.triggerOff()
|
||||
self.setCameraActive()
|
||||
|
||||
sleep(self.greeterTime)
|
||||
@@ -171,4 +209,21 @@ class Photobooth:
|
||||
sleep(self.displayTime)
|
||||
|
||||
self._send.send(gui.IdleState())
|
||||
self._lampOn()
|
||||
|
||||
|
||||
def gpioTrigger(self):
|
||||
|
||||
self._gpioTrigger()
|
||||
|
||||
|
||||
def triggerOff(self):
|
||||
|
||||
self._lampOff()
|
||||
self._gpioTrigger = lambda : None
|
||||
|
||||
|
||||
def triggerOn(self):
|
||||
|
||||
self._lampOn()
|
||||
self._gpioTrigger = self.trigger
|
||||
|
||||
@@ -15,12 +15,12 @@ module = python-gphoto2
|
||||
[Gpio]
|
||||
# Enable use of GPIO (True/False)
|
||||
enable = True
|
||||
# Pin 18 (Channel 24) lets you return to start screen
|
||||
exit_channel = 24
|
||||
# Pin 16 (Channel 23) triggers capturing pictures
|
||||
trigger_channel = 23
|
||||
# Pin 7 (Channel 4) switches the lamp on and off
|
||||
lamp_channel = 4
|
||||
# BOARD pin 18 (BCM pin 24) lets you return to start screen
|
||||
exit_pin = 24
|
||||
# BOARD pin 16 (BCM pin 23) triggers capturing pictures
|
||||
trigger_pin = 23
|
||||
# BOARD pin 7 (BCM pin 4) switches the lamp on and off
|
||||
lamp_pin = 4
|
||||
|
||||
[Printer]
|
||||
# Enable printing (True/False)
|
||||
@@ -40,7 +40,7 @@ greeter_time = 3
|
||||
# Countdown length in seconds (shown before every shot)
|
||||
countdown_time = 5
|
||||
# Display time of assembled picture (shown after last shot)
|
||||
display_time = 5
|
||||
display_time = 10
|
||||
|
||||
[Picture]
|
||||
# Basename of output pictures
|
||||
|
||||
@@ -59,7 +59,6 @@ class PyQt5Gui(Gui):
|
||||
if event.key() == Qt.Key_Escape:
|
||||
self.showStart()
|
||||
elif event.key() == Qt.Key_Space:
|
||||
self._p.handleKeypressEvent = self.handleKeypressEventNoTrigger
|
||||
self._transport.send('triggered')
|
||||
|
||||
|
||||
@@ -78,6 +77,7 @@ class PyQt5Gui(Gui):
|
||||
self.showIdle()
|
||||
elif isinstance(state, GreeterState):
|
||||
global cfg
|
||||
self._p.handleKeypressEvent = self.handleKeypressEventNoTrigger
|
||||
num_pictures = ( cfg.getInt('Picture', 'num_x') *
|
||||
cfg.getInt('Picture', 'num_y') )
|
||||
self._p.setCentralWidget(
|
||||
@@ -335,15 +335,15 @@ class PyQt5Settings(QFrame):
|
||||
self._value_widgets['Gpio']['enable'] = QCheckBox('Enable GPIO')
|
||||
if cfg.getBool('Gpio', 'enable'):
|
||||
self._value_widgets['Gpio']['enable'].toggle()
|
||||
self._value_widgets['Gpio']['exit_channel'] = QLineEdit(cfg.get('Gpio', 'exit_channel'))
|
||||
self._value_widgets['Gpio']['trigger_channel'] = QLineEdit(cfg.get('Gpio', 'trigger_channel'))
|
||||
self._value_widgets['Gpio']['lamp_channel'] = QLineEdit(cfg.get('Gpio', 'lamp_channel'))
|
||||
self._value_widgets['Gpio']['exit_pin'] = QLineEdit(cfg.get('Gpio', 'exit_pin'))
|
||||
self._value_widgets['Gpio']['trigger_pin'] = QLineEdit(cfg.get('Gpio', 'trigger_pin'))
|
||||
self._value_widgets['Gpio']['lamp_pin'] = QLineEdit(cfg.get('Gpio', 'lamp_pin'))
|
||||
|
||||
layout = QFormLayout()
|
||||
layout.addRow(self._value_widgets['Gpio']['enable'])
|
||||
layout.addRow(QLabel('Exit channel:'), self._value_widgets['Gpio']['exit_channel'])
|
||||
layout.addRow(QLabel('Trigger channel:'), self._value_widgets['Gpio']['trigger_channel'])
|
||||
layout.addRow(QLabel('Lamp channel:'), self._value_widgets['Gpio']['lamp_channel'])
|
||||
layout.addRow(QLabel('Exit pin (BCM numbering):'), self._value_widgets['Gpio']['exit_pin'])
|
||||
layout.addRow(QLabel('Trigger pin (BCM numbering):'), self._value_widgets['Gpio']['trigger_pin'])
|
||||
layout.addRow(QLabel('Lamp pin (BCM numbering):'), self._value_widgets['Gpio']['lamp_pin'])
|
||||
|
||||
widget = QGroupBox('GPIO settings')
|
||||
widget.setLayout(layout)
|
||||
@@ -494,9 +494,9 @@ class PyQt5Settings(QFrame):
|
||||
cfg.set('Gui', 'height', self._value_widgets['Gui']['height'].text())
|
||||
|
||||
cfg.set('Gpio', 'enable', str(self._value_widgets['Gpio']['enable'].isChecked()))
|
||||
cfg.set('Gpio', 'exit_channel', self._value_widgets['Gpio']['exit_channel'].text())
|
||||
cfg.set('Gpio', 'trigger_channel', self._value_widgets['Gpio']['trigger_channel'].text())
|
||||
cfg.set('Gpio', 'lamp_channel', self._value_widgets['Gpio']['lamp_channel'].text())
|
||||
cfg.set('Gpio', 'exit_pin', self._value_widgets['Gpio']['exit_pin'].text())
|
||||
cfg.set('Gpio', 'trigger_pin', self._value_widgets['Gpio']['trigger_pin'].text())
|
||||
cfg.set('Gpio', 'lamp_pin', self._value_widgets['Gpio']['lamp_pin'].text())
|
||||
|
||||
cfg.set('Printer', 'enable', str(self._value_widgets['Printer']['enable'].isChecked()))
|
||||
cfg.set('Printer', 'module', modules[self._value_widgets['Printer']['module'].currentIndex()][0])
|
||||
|
||||
@@ -35,9 +35,9 @@ class PrinterPyQt5(Printer):
|
||||
img = img.scaled(self._printer.pageRect().size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||||
|
||||
printable_size = self._printer.pageRect(QPrinter.DevicePixel)
|
||||
offset = ( (printable_size.width() - img.width()) // 2,
|
||||
origin = ( (printable_size.width() - img.width()) // 2,
|
||||
(printable_size.height() - img.height()) // 2 )
|
||||
|
||||
painter = QPainter(self._printer)
|
||||
painter.drawImage(QPoint(*offset), img)
|
||||
painter.drawImage(QPoint(*origin), img)
|
||||
painter.end()
|
||||
|
||||
Reference in New Issue
Block a user