簡體   English   中英

Kivy-顯示實時傳感器數據的標簽

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM