【问题标题】:Display heartbeat sensor's readings from python program in a Kivy label在 Kivy 标签中显示来自 python 程序的心跳传感器读数
【发布时间】:2019-04-24 05:09:52
【问题描述】:

我正在尝试在我的 Kivy 应用程序中显示从我的心跳传感器获得的值。我已经尝试使用应用于其他传感器的数据提取方法,但它不适用于此传感器,因为它不包含任何功能。

我尝试了多种不同的方法,但它们都没有返回所需的输出。有人可以看看传感器代码并建议一些方法来在我的 kivy 应用程序中显示输出。

Heartbeatsensot.py


import time
# Import the ADS1x15 module.
import Adafruit_ADS1x15


if __name__ == '__main__':

    adc = Adafruit_ADS1x15.ADS1015()
    # initialization 
    GAIN = 2/3  
    curState = 0
    thresh = 525  # mid point in the waveform
    P = 512
    T = 512
    stateChanged = 0
    sampleCounter = 0
    lastBeatTime = 0
    firstBeat = True
    secondBeat = False
    Pulse = False
    IBI = 600
    rate = [0]*10
    amp = 100

    lastTime = int(time.time()*1000)

    # Main loop. use Ctrl-c to stop the code
    while True:
        # read from the ADC
        Signal = adc.read_adc(0, gain=GAIN)   #TODO: Select the correct ADC channel. I have selected A0 here
        curTime = int(time.time()*1000)

        sampleCounter += curTime - lastTime;      #                   # keep track of the time in mS with this variable
        lastTime = curTime
        N = sampleCounter - lastBeatTime;     #  # monitor the time since the last beat to avoid noise
        #print N, Signal, curTime, sampleCounter, lastBeatTime

        ##  find the peak and trough of the pulse wave
        if Signal < thresh and N > (IBI/5.0)*3.0 :  #       # avoid dichrotic noise by waiting 3/5 of last IBI
            if Signal < T :                        # T is the trough
              T = Signal;                         # keep track of lowest point in pulse wave 

        if Signal > thresh and  Signal > P:           # thresh condition helps avoid noise
            P = Signal;                             # P is the peak
                                                # keep track of highest point in pulse wave

          #  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
          # signal surges up in value every time there is a pulse
        if N > 250 :                                   # avoid high frequency noise
            if  (Signal > thresh) and  (Pulse == False) and  (N > (IBI/5.0)*3.0)  :       
              Pulse = True;                               # set the Pulse flag when we think there is a pulse
              IBI = sampleCounter - lastBeatTime;         # measure time between beats in mS
              lastBeatTime = sampleCounter;               # keep track of time for next pulse

              if secondBeat :                        # if this is the second beat, if secondBeat == TRUE
                secondBeat = False;                  # clear secondBeat flag
                for i in range(0,10):             # seed the running total to get a realisitic BPM at startup
                  rate[i] = IBI;                      

              if firstBeat :                        # if it's the first time we found a beat, if firstBeat == TRUE
                firstBeat = False;                   # clear firstBeat flag
                secondBeat = True;                   # set the second beat flag
                continue                              # IBI value is unreliable so discard it


              # keep a running total of the last 10 IBI values
              runningTotal = 0;                  # clear the runningTotal variable    

              for i in range(0,9):                # shift data in the rate array
                rate[i] = rate[i+1];                  # and drop the oldest IBI value 
                runningTotal += rate[i];              # add up the 9 oldest IBI values

              rate[9] = IBI;                          # add the latest IBI to the rate array
              runningTotal += rate[9];                # add the latest IBI to runningTotal
              runningTotal /= 10;                     # average the last 10 IBI values 
              BPM = 60000/runningTotal;               # how many beats can fit into a minute? that's BPM!
              print ('BPM: {}'.format(BPM))

        if Signal < thresh and Pulse == True :   # when the values are going down, the beat is over
            Pulse = False;                         # reset the Pulse flag so we can do it again
            amp = P - T;                           # get amplitude of the pulse wave
            thresh = amp/2 + T;                    # set thresh at 50% of the amplitude
            P = thresh;                            # reset these for next time
            T = thresh;

        if N > 2500 :                          # if 2.5 seconds go by without a beat
            thresh = 512;                          # set thresh default
            P = 512;                               # set P default
            T = 512;                               # set T default
            lastBeatTime = sampleCounter;          # bring the lastBeatTime up to date        
            firstBeat = True;                      # set these to avoid noise
            secondBeat = False;                    # when we get the heartbeat back
            print ("no beats found")

        time.sleep(0.005)

** 我正在尝试将读数添加到的 kivy 应用程序**

另一个.py 文件

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.lang import Builder






class MainScreen(Screen):
   pass

class ScreenThermo(Screen):

    def __init__(self,**kwargs):
        super(ScreenThermo, self).__init__(**kwargs)
        Clock.schedule_interval(self.displayHR, 10)


    def displayHR(self,dt):
        heartbeat = 'BPM: {}'.format(BPM)
        pulse = heartbeat
        self.manager.screen_thermo.ids.TempLabel.text = str(pulse)


    def on_enter(self, *args):
        self.__init__()
        pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("heartk.kv")

class MenuApp(App):
    def build(self):
       return presentation 

if __name__ == '__main__':
    MenuApp().run()

.kv 文件

ScreenManagement:    
    id: screen_manager
    screen_thermo: screen_thermo
    MainScreen:
    ScreenThermo:
        id: screen_thermo
        name: 'thermo'
        manager: screen_manager

<MainScreen>:
    name: "main"
    Label:
        text: "Welcome"
        font_size: 60
        halign: 'center'
        valign: 'middle'
        pos_hint: {'x': .01, 'y': .05}
        on_touch_down: app.root.current = "thermo"



<ScreenThermo>:
    Label:
        text: " Pulse rate"
        font_size: 50
        pos: (35, 100)


    Label:
        id: TempLabel
        font_size: 60
        halign: 'center'
        valign: 'middle'

【问题讨论】:

  • 我不清楚你的问题是什么——你知道如何读取你的传感器吗?是什么阻止您使用在 Kivy 应用中获得的值?
  • 是的,我可以读取传感器。 heartbeatsensot.py 中的print ('BPM: {}'.format(BPM)) 部分显示python 程序中的脉率。但是,我无法理解的是如何在我在 another.py 中创建的 kivy 应用程序中显示它。
  • 是什么阻止我使用我在 Kivy 应用程序中获得的值:我制作了一个 kivy 应用程序来显示并不断更新来自传感器的值。它适用于其他传感器,但不适用于脉搏率传感器,我不明白我做错了什么。其他传感器和心跳传感器之间的唯一区别是我通常在其他传感器中使用 python 函数提取值,但在这种情况下,我只是通过简单地打印值来完成。

标签: python kivy sensors kivy-language heartbeat


【解决方案1】:

我认为你可以通过一些小的修改来完成你想要的。首先将StringProperty 添加到您的ScreenThermo 类中,然后在on_enter() 方法中启动一个线程来运行您的Heartbeatsensot 代码:

from Heartbeatsensot import hearbeatsensot

class ScreenThermo(Screen):
    BPM_string = StringProperty('BPM: Not Detected')

    def on_enter(self, *args):
        Thread(target=hearbeatsensot, args=(self,)).start()

在您的kv 文件中,添加对新StringProperty 的引用:

<ScreenThermo>:
    Label:
        text: " Pulse rate"
        font_size: 50
        pos: (35, 100)


    Label:
        id: TempLabel
        text: root.BPM_string  # references new StringProperty
        font_size: 60
        halign: 'center'
        valign: 'middle'

现在您只需将要在TempLabel 中显示的任何内容放入BPM_string 属性中。为此,更改Heartbeatsensot.py 以定义可在Thread 中使用的方法。只需将该文件中的if __name__ == '__main__': 替换为def hearbeatsensot(screenThermo):,如下所示:

import time
# Import the ADS1x15 module.
import Adafruit_ADS1x15


def hearbeatsensot(screenThermo):

    adc = Adafruit_ADS1x15.ADS1015()
    # initialization
    GAIN = 2/3
    .
    .
    .
    screenThermo.BPM_string = 'BPM: 65'
    .
    .
    .

然后,在该方法中,只需使用 screenThermo.BPM_string = 'BPM: 65' 之类的想法(或您想要设置的任何内容)。在kv 文件中对BPM_string 的引用将自动设置一个绑定,以便在修改BPM_string 时更新TempLabel

【讨论】:

  • 感谢您抽出宝贵时间帮助我。我已经按照您的建议进行了修改。但是,它现在返回以下错误:TypeError: 'NoneType' object is not subscriptable
  • Traceback (most recent call last): File "heartsensor.py", line 140, in &lt;module&gt; presentation = Builder.load_file("heartk.kv") File "/usr/local/lib/python3.5/dist-packages/kivy/lang/builder.py", line 301, in load_file return self.load_string(data, **kwargs) File "/usr/local/lib/python3.5/dist-packages/kivy/lang/builder.py", line 368, in load_string parser = Parser(content=string, filename=fn) File "/usr/local/lib/python3.5/dist-packages/kivy/lang/parser.py", line 392, in __init__ self.parse(content)
  • File "/usr/local/lib/python3.5/dist-packages/kivy/lang/parser.py", line 501, in parse objects, remaining_lines = self.parse_level(0, lines) File "/usr/local/lib/python3.5/dist-packages/kivy/lang/parser.py", line 664, in parse_level if current_property[:3] == 'on_': TypeError: 'NoneType' object is not subscriptable
  • 看起来它在抱怨您的 kv 文件中的某些内容。
  • 通过一些小的改动,我能够让它工作。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 1970-01-01
相关资源
最近更新 更多