当有多个线程可用时,无法使用GPIO PWM

时间:2019-04-26 09:25:01

标签: python multithreading raspberry-pi gpio pwm

我正在研究一个项目,该项目不断等待screen上的用户输入。一旦检测到用户输入,就需要打开servo机制,然后关闭。整个解决方案的编写方式是,只有一个主线程,而从主线程派生的其他线程很少,如下所示:

enter image description here

此设置的问题在于:

  1. 如果仅执行主线程中处理的操作-> BoxOpeningManager.py 会按预期工作。它会打开和关闭伺服器。
  2. 如果我执行一次在主线程中处理的操作,然后在派生线程中处理的操作,则下次我尝试在主线程 BoxOpeningManager.py 上执行操作时,将无法正常工作。没错,没事。只是没有打开伺服器。我需要重新启动程序。
  3. 如果首先执行在分支线程中处理的操作,然后尝试执行在主线程中处理的操作,则主线程再次无法工作。

长话短说,每当我在分支线程上执行某些操作时,便无法再在主线程中使用 BoxOpeningManager.py

这是两个脚本的代码:

from servoManager import ServoManager
from proximitySensorManager import ProximitySensorManager
from configurationWrapping import GlobalConfigurationWrapper
from loggingManager import Logger

import time

class BoxOpeningManager():

    def __init__(self):
        self.configuration = GlobalConfigurationWrapper()
        self.timeToKeepTheBoxOpen = self.configuration.box_time_to_keep_the_box_open()
        self.logger = Logger()

        self.servoManager = ServoManager()      
        self.proximitySensorManager = ProximitySensorManager();

    def start_box_opening_procedure(self):
        try:
            self.servoManager.open()

            t_end = time.time() + (int)(self.timeToKeepTheBoxOpen)
            while time.time() < t_end:
                continue

            while True:
                if not self.proximitySensorManager.object_in_front() :         
                    self.servoManager.close()
                    break;
                else :
                    time.sleep(1)
        except BaseException as e:
            self.logger.log_critical('<BoxOpeningManager.start_box_opening_procedure> => ' + str(e))

伺服管理器:

import RPi.GPIO as GPIO
from time import sleep

from patternImplementations import Singleton
from loggingManager import Logger

class ServoManager():
    __metaclass__ = Singleton

    __OUTPUT_GPIO_PIN_NUMBER = 12

    def __init__(self):
        GPIO.setmode(GPIO.BOARD)#Numbers GPIOs by physical location
        GPIO.setup(self.__OUTPUT_GPIO_PIN_NUMBER, GPIO.OUT)

        self.pwm=GPIO.PWM(self.__OUTPUT_GPIO_PIN_NUMBER,50)
        self.pwm.start(0)

        self.logger = Logger()

    def open(self):
        try:
            self.__set_angle(13)
        except BaseException as e:
            self.logger.log_critical('<ServoManager.open> => ' + str(e))

    def close(self):
        try:
            self.__set_angle(185)
        except BaseException as e:
            self.logger.log_critical('<ServoManager.close> => ' + str(e))

    def __set_angle(self, angle):
        duty = (angle/18 + 2)

        GPIO.output(self.__OUTPUT_GPIO_PIN_NUMBER, True)
        self.pwm.ChangeDutyCycle(duty)

        sleep(1)

        GPIO.output(self.__OUTPUT_GPIO_PIN_NUMBER, False)
        self.pwm.ChangeDutyCycle(0)

0 个答案:

没有答案