Python Kivy Raspberrypi 错误 GPIO 通道

Python Kivy Raspberrypi Error GPIO Channel

我创建 class 以在我的布局的许多不同位置添加小部件矩形。 我正在运行 return 错误 GPIO 大多数设置 (),我在第 11 行配置端口,我的代码有什么问题?

>  Traceback (most recent call last):    File "plantadeira.py", line 50,
> in <module>
>      MainApp().run()    File "/usr/local/lib/python2.7/dist-packages/kivy/app.py", line 828, in run
>      runTouchApp()    File "/usr/local/lib/python2.7/dist-packages/kivy/base.py", line 487, in
> runTouchApp
>      EventLoop.window.mainloop()    File "/usr/local/lib/python2.7/dist-packages/kivy/core/window/window_egl_rpi.py",
> line 90, in mainloop
>      self._mainloop()    File "/usr/local/lib/python2.7/dist-packages/kivy/core/window/window_egl_rpi.py",
> line 85, in _mainloop
>      EventLoop.idle()    File "/usr/local/lib/python2.7/dist-packages/kivy/base.py", line 327, in
> idle
>      Clock.tick()    File "/usr/local/lib/python2.7/dist-packages/kivy/clock.py", line 581, in
> tick
>      self._process_events()    File "kivy/_clock.pyx", line 368, in kivy._clock.CyClockBase._process_events
> (/tmp/pip-NKJIwl-build/kivy/_clock.c:7219)    File "kivy/_clock.pyx",
> line 398, in kivy._clock.CyClockBase._process_events
> (/tmp/pip-NKJIwl-build/kivy/_clock.c:7102)    File "kivy/_clock.pyx",
> line 396, in kivy._clock.CyClockBase._process_events
> (/tmp/pip-NKJIwl-build/kivy/_clock.c:7032)    File "kivy/_clock.pyx",
> line 168, in kivy._clock.ClockEvent.tick
> (/tmp/pip-NKJIwl-build/kivy/_clock.c:3109)    File "plantadeira.py",
> line 26, in update
>      if  self.read_Sensor(pin) == False:    File "plantadeira.py", line 36, in read_Sensor
>      sensor = GPIO.wait_for_edge(int(pin), GPIO.RISING, timeout=1000)  RuntimeError: You must setup() the GPIO channel as an input first

这是我的代码python:

from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
from kivy.properties import NumericProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
import RPi.GPIO as GPIO


GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
pin_1 = 17

class MainLayout(FloatLayout):
    pass            

class bar(Widget):

    r = NumericProperty(1)
    def __init__(self, pin, p1, p2, s1, s2, **kwargs):
        super(bar, self).__init__(**kwargs)        
        Clock.schedule_interval(self.update, 0.5)

    def update(self, pin):
        if  self.read_Sensor(pin) == False:
            with self.canvas:
                Color(self.r, 0, 0, 1)
                Rectangle(pos=(p1,p2), size=(s1,s2))
        else:
            with self.canvas:
                Color(self.r, 1, 1, 1)
                Rectangle(pos=(p1,p2), size=(s1,s2))            

    def read_Sensor(self, pin):
        sensor = GPIO.wait_for_edge(int(pin), GPIO.RISING, timeout=1000)
        if sensor is None:
            return False
        else:
            return True

class MainApp(App):
    def build(self):
        self.mainlayout = Widget()
        bar1 = bar(pin_1, 1, 10, 60, 100)
        self.mainlayout.add_widget(bar1)
        return self.mainlayout

if __name__ == '__main__':
    MainApp().run()

您的代码中的问题是在您调用时:
GPIO.wait_for_edge(int(pin), GPIO.RISING, timeout=1000)
你不能使用 int(pin) 而是你在 class.
之前定义的 pin_1 所以你可以这样称呼它:
GPIO.wait_for_edge(pin_1, GPIO.RISING, timeout=1000)

如果你想在你的代码中使用pin,你必须在对象的初始化中定义为self.pin = pin。 (初始化)。然后在 class 中的任何地方将其称为 self.pin。在这种情况下,您不需要在更新 -> read_Sensor 方法中将其作为参数传递。除非你有多个引脚,但你需要将一个数字传递给 read_Sensor 方法。你不会在你的代码中这样做。您没有将任何数字传递给更新方法。
从文档 https://kivy.org/docs/api-kivy.clock.html

开始,您的情况下的 pin 变为 Clocks dt,(增量时间)

如果您查看错误,您会发现 int(pin) 从未设置为输入。如前所述,int(pin) 是 Clocks 增量时间,因此它永远不会相同。 RuntimeError: You must setup() the GPIO channel as an input first

并且只是为了展示如何重写它:

from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
from kivy.properties import NumericProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
import RPi.GPIO as GPIO


GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
pin_1 = 17

class MainLayout(FloatLayout):
    pass 

class bar(Widget):

    r = NumericProperty(1)
    def __init__(self, pin, p1, p2, s1, s2, **kwargs):
        super(bar, self).__init__(**kwargs)
        Clock.schedule_interval(self.update, 0.5)
        self.pin = pin

    def update(self, dt):
        if  self.read_Sensor() == False:
            with self.canvas:
                Color(self.r, 0, 0, 1)
                Rectangle(pos=(p1,p2), size=(s1,s2))
        else:
            with self.canvas:
                Color(self.r, 1, 1, 1)
                Rectangle(pos=(p1,p2), size=(s1,s2))            

    def read_Sensor(self, pin=self.pin):  # you dont need to pass anything to this method. It will default to self.pin. But if you need it for other sensors, you can pass an integer.                                                                                            
        sensor = GPIO.wait_for_edge(pin, GPIO.RISING, timeout=1000)                                                                   
        if sensor is None:
            return False
        else:
            return True

class MainApp(App):
    def build(self):
        self.mainlayout = Widget()
        bar1 = bar(pin_1, 1, 10, 60, 100)
        self.mainlayout.add_widget(bar1)
        return self.mainlayout

if __name__ == '__main__':
    MainApp().run()