Kivy PyFirmata Problem
Verfasst: Freitag 26. Februar 2016, 17:57
Hallo zusammen,
ich versuche gerade meine ersten Schritte in Kivy, Python und PyFirmata.
Was geht: mit einem Button in der GUI eine LED am Arduino anzusteuern.
Was nicht geht: mit einem Button am Arduino den zustand eines Buttons in der GUI zu ändern.
Da ich mein eigentliches Projekt bereits mit main.py und main.kv begonnen habe, habe ich zum testen das rpi-kivy-screen-master runtergeladen. Dies besteht aber nur aus der main.py in der mit build die GUI direkt aufgebaut wird. Das meiste konnte ich umschreiben, nur beim abfragen des board.digital[23].read() Zustands und damit das ändern des Zustands von Button 'input' scheitere ich total...
Hier die main.py
[Codebox=python file=main.py]
import kivy
from kivy.app import App
from kivy import platform
from kivy.uix.button import Button
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import *
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
from time import sleep
import serial
from pyfirmata import ArduinoMega, util
from pyfirmata.util import Iterator
from pyfirmata import SERVO
from pyfirmata import INPUT
from pyfirmata import OUTPUT
if platform == 'linux':
board = ArduinoMega('/dev/tty.usbserial-A6008rIF') # please check on wich serial port talks the Arduino
if platform == 'win':
board = ArduinoMega('COM5') # please check on wich serial port talks the Arduino
#for now, use a global for blink speed (better implementation TBD):
speed = 1.0
it = Iterator(board)
it.start()
# Set up GPIO:
board.digital[22].mode = OUTPUT
board.digital[23].mode = INPUT
board.digital[23].enable_reporting()
# Make the background violet:
Builder.load_string('''
<RootWidget>
canvas.before:
Color:
rgba: 1, .3, .8, .5
Rectangle:
pos: self.pos
size: self.size
''')
# Modify the Button Class to update according to board.digital input:
class InputButton(Button):
def update(self, dt):
if board.digital[23].read() == 1:
print ("button on")
self.state = 'normal'
else:
print ("button off")
self.state = 'down'
class RootWidget(FloatLayout):
'''This is the class representing your root widget.
By default it is inherited from FloatLayout,
you can use any other layout/widget depending on your usage.
'''
# debugging code to print out all my objects when I hit the switch
level = 1
def print_tree(self,my_obj):
print str(self.level) + " "*self.level + str(my_obj)
for child in (my_obj.children):
self.level += 1
self.print_tree(child)
self.level -= 1
# This callback will be bound to the LED toggle button:
def press(self):
print ("LED on")
board.digital[22].write(1)
def release(self):
print ("LED off")
board.digital[22].write(0)
pass
class MainApp(App):
def build(self):
## Original Code ##
## Instantiate the first UI object (the GPIO input indicator):
#>>> #inputDisplay = InputButton(text="Input")
## Schedule the update of the state of the GPIO input button:
#>>> #Clock.schedule_interval(inputDisplay.update, 1.0/10.0)
## Create the rest of the UI objects (and bind them to callbacks, if necessary):
#outputControl = ToggleButton(text="LED")
#outputControl.bind(on_press=press_callback)
## Add the UI elements to the layout:
#>>> #layout.add_widget(inputDisplay)
#layout.add_widget(outputControl)
print('build running')
return RootWidget()
if __name__ == '__main__':
MainApp().run()
[/Codebox]
Und hier die main.kv
[Codebox=python file=main.kv]
<RootWidget>:
# this is the rule for your root widget, defining it's look and feel.
height: 110.0
width: 190.0
Button: # outputControl
id: output
text: 'LED'
height: 50.0
width: 50.0
size_hint_x: 0.0
size_hint_y: 0.0
x: 30.0 # 0 = left to nn = right
y: 30.0 # 0 = bottom to nn = top
on_press: root.press()
on_release: root.release()
Button: # inputDisplay
id: input
text: 'Input'
height: 50.0
width: 50.0
size_hint_x: 0.0
size_hint_y: 0.0
x: 110.0
y: 30.0
[/Codebox]
Gruß
Thilo
ich versuche gerade meine ersten Schritte in Kivy, Python und PyFirmata.
Was geht: mit einem Button in der GUI eine LED am Arduino anzusteuern.
Was nicht geht: mit einem Button am Arduino den zustand eines Buttons in der GUI zu ändern.
Da ich mein eigentliches Projekt bereits mit main.py und main.kv begonnen habe, habe ich zum testen das rpi-kivy-screen-master runtergeladen. Dies besteht aber nur aus der main.py in der mit build die GUI direkt aufgebaut wird. Das meiste konnte ich umschreiben, nur beim abfragen des board.digital[23].read() Zustands und damit das ändern des Zustands von Button 'input' scheitere ich total...
Hier die main.py
[Codebox=python file=main.py]
import kivy
from kivy.app import App
from kivy import platform
from kivy.uix.button import Button
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import *
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
from time import sleep
import serial
from pyfirmata import ArduinoMega, util
from pyfirmata.util import Iterator
from pyfirmata import SERVO
from pyfirmata import INPUT
from pyfirmata import OUTPUT
if platform == 'linux':
board = ArduinoMega('/dev/tty.usbserial-A6008rIF') # please check on wich serial port talks the Arduino
if platform == 'win':
board = ArduinoMega('COM5') # please check on wich serial port talks the Arduino
#for now, use a global for blink speed (better implementation TBD):
speed = 1.0
it = Iterator(board)
it.start()
# Set up GPIO:
board.digital[22].mode = OUTPUT
board.digital[23].mode = INPUT
board.digital[23].enable_reporting()
# Make the background violet:
Builder.load_string('''
<RootWidget>
canvas.before:
Color:
rgba: 1, .3, .8, .5
Rectangle:
pos: self.pos
size: self.size
''')
# Modify the Button Class to update according to board.digital input:
class InputButton(Button):
def update(self, dt):
if board.digital[23].read() == 1:
print ("button on")
self.state = 'normal'
else:
print ("button off")
self.state = 'down'
class RootWidget(FloatLayout):
'''This is the class representing your root widget.
By default it is inherited from FloatLayout,
you can use any other layout/widget depending on your usage.
'''
# debugging code to print out all my objects when I hit the switch
level = 1
def print_tree(self,my_obj):
print str(self.level) + " "*self.level + str(my_obj)
for child in (my_obj.children):
self.level += 1
self.print_tree(child)
self.level -= 1
# This callback will be bound to the LED toggle button:
def press(self):
print ("LED on")
board.digital[22].write(1)
def release(self):
print ("LED off")
board.digital[22].write(0)
pass
class MainApp(App):
def build(self):
## Original Code ##
## Instantiate the first UI object (the GPIO input indicator):
#>>> #inputDisplay = InputButton(text="Input")
## Schedule the update of the state of the GPIO input button:
#>>> #Clock.schedule_interval(inputDisplay.update, 1.0/10.0)
## Create the rest of the UI objects (and bind them to callbacks, if necessary):
#outputControl = ToggleButton(text="LED")
#outputControl.bind(on_press=press_callback)
## Add the UI elements to the layout:
#>>> #layout.add_widget(inputDisplay)
#layout.add_widget(outputControl)
print('build running')
return RootWidget()
if __name__ == '__main__':
MainApp().run()
[/Codebox]
Und hier die main.kv
[Codebox=python file=main.kv]
<RootWidget>:
# this is the rule for your root widget, defining it's look and feel.
height: 110.0
width: 190.0
Button: # outputControl
id: output
text: 'LED'
height: 50.0
width: 50.0
size_hint_x: 0.0
size_hint_y: 0.0
x: 30.0 # 0 = left to nn = right
y: 30.0 # 0 = bottom to nn = top
on_press: root.press()
on_release: root.release()
Button: # inputDisplay
id: input
text: 'Input'
height: 50.0
width: 50.0
size_hint_x: 0.0
size_hint_y: 0.0
x: 110.0
y: 30.0
[/Codebox]
Gruß
Thilo