[英]Kivy - Label to display real-time Sensor Data
我想在Kivy中創建兩個標簽,使用來自溫度傳感器的傳感器數據更新其文本。
溫度傳感器連接到Arduino,Arduino每兩秒鍾左右以示例格式將其值打印到串行:
A 82.4 (在線1上)
B 80.6 (第2行)
A / B包含在每個打印物中,作為python可以用來區分兩者的標識符。
問題是將此數據導入python並將其附加到標簽。
這是現有的.py文件:
import kivy
kivy.require('1.10.0')
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from digitalclock import DigitalClock
from kivy.animation import Animation
import serial
import time
import opc
class IntroScreen(Screen):
pass
class ContScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
#Disregard this, a timer is included in layout
class Timer(Label):
a = NumericProperty() # seconds
def __init__(self, root, instance, duration, bg_color, **kwargs):
super(Timer, self).__init__(**kwargs)
self.obj = instance
self.a = duration
self.root = root
self.obj.disabled = True # disable widget/button
self.obj.background_color = bg_color
self.root.add_widget(self) # add Timer/Label widget to screen, 'cont'
def animation_complete(self, animation, widget):
self.root.remove_widget(widget) # remove Timer/Label widget to screen, 'cont'
self.obj.background_color = [1, 1, 1, 1] # reset to default colour
self.obj.disabled = False # enable widget/button
def start(self):
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.animation_complete)
self.anim.start(self)
def on_a(self, instance, value):
self.text = str(round(value, 1))
class Status(FloatLayout):
_change = StringProperty()
_tnd = ObjectProperty(None)
def update(self, *args):
self.time = time.asctime()
self._change = str(self.time)
self._tnd.text = str(self.time)
print (self._change)
#Here is where I start referencing Serial Comms, this line is to identify where
#to *send* commands to via a separate identifier.
bone = serial.Serial('/dev/ttyACM0', 9600)
class XGApp(App):
time = StringProperty()
sensor1 = NumericProperty(0)
sensor2 = NumericProperty(0)
def update(self, *args):
self.time = str(time.asctime())
arduino = self.arduino
data = arduino.read(arduino.inWaiting())
for line in data.split('\n'):
try:
sensor, value = line.strip().split(' ')
except:
print("parse error!")
continue
if sensor == 'A':
self.sensor1 = float(value)
elif sensor == 'B':
self.sensor2 = float(value)
else:
print("unknown data! {}".format(line))
def build(self):
try:
self.arduino = serial.Serial('/dev/ttyACM0', 9600)
except Exception as e: print(e)
Clock.schedule_interval(self.update, 1)
return Builder.load_file("main.kv")
xApp = XGApp()
if __name__ == "__main__":
xApp.run()
和.kv:
<ContScreen>:
FloatLayout
orientation: 'vertical'
padding: [10,50,10,50]
spacing: 50
Label:
id: 'TempLabel1'
text: str(app.sensor1)
color: 1,1,1,1
font_size: 80
pos_hint: {'center_x':0.2, 'center_y':0.6}
Label:
id: 'TempLabel2'
text: str(app.sensor1)
color: 1,1,1,1
font_size: 80
pos_hint: {'center_x':0.5, 'center_y':0.6}
稍后在.kv中:
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
Timer(root, self, 10, [100, 0, 100, 1.75]).start()
bone.Write('j'.encode())
print("One Executed")
TempLabel1和TempLabel2是我想從傳感器更新的兩個標簽。
完全有可能。 但是您缺少一些東西。
您正在嘗試在運行應用程序后連接到串行端口,該操作將無法正常進行,因為您到達該位置時,應用程序將被停止。 相反,您想在應用程序運行時執行此部分。 我會做嘗試/除了連接到app.build中的arduino。
def build (self):
try:
self.arduino = serial.Serial('/dev/ttyACM0')
exept:
print("unable to connect to arduino :(")
Clock.schedule_interval(self.update, 1)
return Builder.load_file("main.kv")
然后,您要檢查update方法中的消息,但不想阻塞,因此只讀取緩沖區中等待的數據量。
def update(self, *args):
arduino = self.arduino
data = arduino.read(arduino.inWaiting())
然后您進行處理,我假設您的數據是這樣的:
A value
B value
在這種情況下,您可以解析它並更新相應的變量,例如:
def update(self, *args):
arduino = self.arduino
data = arduino.read(arduino.inWaiting())
for line in data.split('\n'):
try:
sensor, value = line.strip().split(' ')
except:
print("parse error!")
continue
if sensor == 'A':
self.sensor1 = float(value)
elif sensor == 'B':
self.sensor2 = float(value)
else:
print("unknown data! {}".format(line))
會完成這項工作,這有點簡單,因為它假定您總是會獲得完整的陣容,但是如果需要的話可以在以后進行改進(根據我的經驗,這似乎足夠了)。
現在,我們需要確保標簽注意到值的變化,為此,kivy使用properties
,它們是更聰明的屬性,您需要在app類上聲明它們。
class XGApp(App):
sensor1 = NumericProperty(0)
sensor2 = NumericProperty(0)
現在,您可以通過應用實例使更新直接顯示值。
<ContScreen>:
FloatLayout
orientation: 'vertical'
padding: [10,50,10,50]
spacing: 50
Label:
id: 'TempLabel1'
text: str(app.sensor1)
color: 1,1,1,1
font_size: 80
pos_hint: {'center_x':0.2, 'center_y':0.6}
Label:
id: 'TempLabel2'
text: str(app.sensor2)
color: 1,1,1,1
font_size: 80
pos_hint: {'center_x':0.5, 'center_y':0.6}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.