Python Kivy Raspberrypi错误GPIO频道

时间:2016-08-03 00:46:28

标签: python raspberry-pi kivy gpio

我创建了用于在我的布局的许多不同位置添加小部件矩形的类。 我运行返回错误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()

1 个答案:

答案 0 :(得分:0)

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

如果要在代码中使用pin,则必须在对象的启动中将其定义为self.pin = pin。 (的初始化)。然后在课堂的任何地方将其称为self.pin。您无需在更新中将其作为参数传递 - &gt;在这种情况下的read_Sensor方法。除非你有几个引脚,但是你需要将一个数字传递给read_Sensor方法。你不要在你的代码中这样做。您不会将任何数字传递给更新方法 你的案例中的pin会变成时钟dt,(增量时间),而不是文档https://kivy.org/docs/api-kivy.clock.html

如果你看错误,你会发现int(pin)从未被设置为输入。如前所述,int(pin)是时钟增量时间,因此它永远不会相同。 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()