Python 根据ardunio温度传感器数据更新Kivy标签

Python 根据ardunio温度传感器数据更新Kivy标签,python,kivy,kivy-language,Python,Kivy,Kivy Language,我知道这里还有一些其他的kivy/标签更新线程,但在应用了这些线程的指导几天后,我仍然无法从ardunio获得kivy中的标签来更新温度数据。这是针对campervan控制面板的,该面板应控制执行器在按下按钮时折叠沙发床,并在屏幕上显示传感器数据 我有串行端口连接工作,因为执行器控制按钮工作,但我正在努力获得一个标签,以更新温度传感器数据。ardunio IDE串行监视器显示ardunio输出的温度正常,如果我将temp_sensor函数复制/粘贴到新脚本中,它将正常打印数据 我对编程、pyth

我知道这里还有一些其他的kivy/标签更新线程,但在应用了这些线程的指导几天后,我仍然无法从ardunio获得kivy中的标签来更新温度数据。这是针对campervan控制面板的,该面板应控制执行器在按下按钮时折叠沙发床,并在屏幕上显示传感器数据

我有串行端口连接工作,因为执行器控制按钮工作,但我正在努力获得一个标签,以更新温度传感器数据。ardunio IDE串行监视器显示ardunio输出的温度正常,如果我将temp_sensor函数复制/粘贴到新脚本中,它将正常打印数据

我对编程、python和kivy都是新手,所以如果我太笨了,请道歉

下面是python代码:

import kivy
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.properties import ObjectProperty, NumericProperty, StringProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

import serial
import webbrowser
import time

browser_launch = 'https://www.google.com'
ser= serial.Serial('/dev/cu.usbmodem14201', 9600, timeout=5) 


class MainWindow(Screen): #The home screen, that navigates to other control windows, and has the buttons controlling the actuators.

    desktop = ObjectProperty(None)
    settings = ObjectProperty(None)
    bed = ObjectProperty(None)
    sofa = ObjectProperty(None)

    def desktop_button(self):
        webbrowser.open_new(browser_launch)
        print("Desktop Pressed")

    def settings_button(self):
        print("Settings Pressed")

    def bed_button(self):
        ser.write(b'B')  #These buttons work, and interact with the ardunio as they should.
        print("Bed Pressed")

    def sofa_button(self):
        ser.write(b'S')
        print("Sofa Pressed")

    pass

class TempWindow(Screen): #Second screen that is navigated to from the main screen. This will display temperature inside the van, (and outside, plus control the heater eventually)

    temp_sensor_inside = NumericProperty(0)

    def temp_sensor(self):  #If I run this function in a seperate python script it works.
        time.sleep(2)
        while 1:
            temp_reading = ser.readline().decode('ascii')
            float_temp = float(temp_reading)
            return float_temp
    pass

class DataWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass



kv = Builder.load_file('my.kv')

class MyMainApp(App):
    def build(self):
        return kv


if __name__ == "__main__":
    MyMainApp().run()

    ser.close()

以及.kv文件的相应部分:

<TempWindow>:
    name: 'temp'

    temp_sensor_inside: temp_sensor_inside

    FloatLayout:
        canvas.before:
            Rectangle:
                pos: self.pos
                size: self.size
                source: 'background.png'

        Label:
            id: temp_sensor_inside
            text: str(root.temp_sensor())
            font_size: 50
            pos_hint: {'x': -0.15, 'y': 0.1}


:
姓名:“临时工”
内部温度传感器:内部温度传感器
浮动布局:
在以下情况之前:
矩形:
pos:self.pos
大小:self.size
来源:“background.png”
标签:
id:内部温度传感器
文本:str(根温度传感器())
字体大小:50
位置提示:{'x':-0.15,'y':0.1}
以下是一个示例(基于您的代码),应该对您有所帮助。在下面的例子中,我省略了一些不影响答案的事情。我已经用名为
float\u temp
的全局变量替换了访问温度传感器的代码,因为我没有这样的传感器:

import threading
import time
from functools import partial

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import Screen, ScreenManager

float_temp = 55.0


class TempWindow(Screen): #Second screen that is navigated to from the main screen. This will display temperature inside the van, (and outside, plus control the heater eventually)

    temp_sensor_inside = ObjectProperty(None)

    def on_enter(self, *args):
        # start polling the temperature
        threading.Thread(target=self.poll_sensor).start()


    def poll_sensor(self):
        global float_temp
        while 1:
            # temp_reading = ser.readline().decode('ascii')
            # float_temp = float(temp_reading)
            float_temp += 1.5
            Clock.schedule_once(partial(self.set_temp, float_temp))
            time.sleep(2)

    def set_temp(self, temp, dt):
        self.temp_sensor_inside.text = str(temp)

kv_str = '''
<TempWindow>:
    temp_sensor_inside: temp_sensor_inside
    name: 'temp'
    Label:
        id: temp_sensor_inside
        text: '000'
'''

class TempWindowApp(App):
    def build(self):
        kv = Builder.load_string(kv_str)
        sm = ScreenManager()
        sm.add_widget(TempWindow())
        return sm


TempWindowApp().run()
导入线程
导入时间
从functools导入部分
从kivy.app导入应用程序
从kivy.clock导入时钟
从kivy.lang导入生成器
从kivy.properties导入ObjectProperty
从kivy.uix.screenmanager导入屏幕,screenmanager
浮动温度=55.0
类临时窗口(屏幕):#从主屏幕导航到的第二个屏幕。这将显示货车内部和外部的温度,并最终控制加热器
温度传感器内部=对象属性(无)
def on_enter(自身,*参数):
#开始轮询温度
threading.Thread(target=self.poll\u sensor.start())
def轮询传感器(自身):
全局浮动温度
而1:
#temp_reading=ser.readline().decode('ascii')
#浮动温度=浮动(温度读数)
浮动温度+=1.5
时钟计划一次(部分(自设温度、浮动温度))
时间。睡眠(2)
def设置温度(自身、温度、dt):
self.temp\u sensor\u inside.text=str(温度)
kv_str=''
:
内部温度传感器:内部温度传感器
姓名:“临时工”
标签:
id:内部温度传感器
文字:“000”
'''
类TempWindowApp(应用程序):
def生成(自):
kv=建筑商负载串(kv\u串)
sm=屏幕管理器()
sm.add_小部件(TempWindow())
返回sm
TempWindowApp().run()
当显示
TempWindow
时,将执行
on_enter()
方法。该方法启动一个新线程来监视温度传感器,因为您不想将GUI与一个永远运行的循环绑定在一起。
poll\u sensor()
方法从传感器获取当前温度(在我的例子中,它只是增加
float\u temp
),并使用
Clock.schedule\u once()调用
set\u temp()
Clock.schedule_once()
在主线程上运行
set_temp()
(修改GUI的代码所需),并且
set_temp()
通过引用
kv
中的
id
对象属性更改
标签的文本