Arduino,Python,Serial和Unpacking值:“ValueError:需要多于1个值才能解包”

2024-10-06 12:37:23 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的第一个问题,而且我对python还比较陌生,所以请耐心听我说。我们将非常感谢您对这个问题的指导!在

我有一个pulse oximeter,它和particular Arduino shield一起使用,产生两个简单的信号:脉搏率和氧饱和度。参见Arduino代码:

#include <PinChangeInt.h>
#include <eHealth.h>

int cont = 0;

void setup() {
  Serial.begin(115200);  
  eHealth.initPulsioximeter();

  //Attach the inttruptions for using the pulsioximeter.   
  PCintPort::attachInterrupt(6, readPulsioximeter, RISING);
}

void loop() {

  //BPM
  Serial.print(eHealth.getBPM());
  Serial.print(",");

  //SP02
  Serial.print(eHealth.getOxygenSaturation());  

  //NEW LINE
  Serial.print('\n');  
  delay(500);
}


//=========================================================================
void readPulsioximeter(){  

  cont ++;

  if (cont == 50) { //Get only of one 50 measures to reduce the latency
    eHealth.readPulsioximeter();  
    cont = 0;
  }
}

因此,输出到串行监视器,换句话说,当调用pySerial readline()时,逗号分隔的行如下所示:

^{pr2}$

很简单,对吧?在

好吧,我使用python程序和pySerial来读取这些值,将它们分配给一个向量,在图形上实时打印,并将其保存到一个.csv文件中。在

以下是程序供您参考:

import serial
import time 
import matplotlib.pyplot as plt
import numpy as np
import sys
import os
import csv

#time load
timestr = time.strftime("%Y_%m_%d")

#spacer
spacer = "_"

#user inputs name
name = raw_input('Enter full name:  ')
file_name = name + spacer + timestr
file_name_str = file_name+'.csv'

#change directory
path = '/home/pi/Desktop/pulseox/data'
os.chdir(path)
text_file = open(file_name, "w")
full_path = path + "/" + file_name_str

#check
print full_path

#establish serial connection with ACM0
ser = serial.Serial('/dev/ttyACM0', 115200)

#establish vectors
thymeL = [ ]
bpmL = [ ]
sp02L = [ ]
array_data = thymeL, bpmL, sp02L


#declare time
thyme = 1

#establish plot values
#plt.axis([0,50,0,120])
plt.ion()
plt.title("Pulse [BPM] & SPo2 [%] v. Time [s]", fontsize = "16")
plt.xlabel("Time [s]", fontsize = "14")
plt.ylabel("Pulse (red) [BPM] & SPo2 (blue) [%]", fontsize = "14")

#print data to terminal, define time
while True:         
    data_in = ser.readline()
    bpm, sp02 = data_in.split(",")
    thyme = float(thyme)
    bpm = float(bpm)
    sp02 = float(sp02)
    print "Time [s]: %s" % (thyme)
    print "HR [BPM]: %s" % (bpm)
    print "SPO2 [%%]: %s" % (sp02)  
    print 

    thymeL.append(thyme)
    bpmL.append(bpm)
    sp02L.append(sp02)

    plt.scatter(thyme,bpm,color="red")
    plt.scatter(thyme,sp02,color="blue")
    plt.pause(0.1)
    time.sleep(0.05)

    thyme = thyme + 1

    with open(full_path, 'w') as f:
        writer = csv.writer(f)
        for t, b, s in zip(array_data[0], array_data[1], array_data[2]):
            writer.writerow([t, b, s])

25%的时候一切都很好。但在另外75%的情况下,程序会随机返回以下错误:

Traceback (most recent call last)L
    File "pulseox.py", line 74, in <module>
        bpm, sp02 = data_in.split(",")
ValueError: need more than 1 value to unpack

所以忽略程序的其余部分,除了以下几行:

data_in = ser.readline()
spm,sp02 = data_in.split(",")

如果串行监视器实际上只是输出2个逗号分隔的值,例如:

67, 95
71, 95

那么为什么在程序被如此简单地指令解包两个变量并将它们分配给数组时会出现解包错误呢?这是一个问题,正在发生在我的另一个程序,我想得到它的底部!非常感谢任何帮助!在


Tags: pathnameinimport程序datatimeserial
1条回答
网友
1楼 · 发布于 2024-10-06 12:37:23

问题是,当Arduino只打印了部分内容时,python代码可能会从缓冲区读取。在python代码中,Arduino和while True: data_in = ser.readline()使用了4个单打印。因此,可能会发生以下情况:

void loop() {

  //BPM
  Serial.print(eHealth.getBPM());
  Serial.print(",");

  // *** At this point the python code may read what has been written so far, i.e. it receives an invalid data set and thus the ValueError. ***

  //SP02
  Serial.print(eHealth.getOxygenSaturation());  

  //NEW LINE
  Serial.print('\n');  
  delay(500);
}

您应该首先构造一个x,y\n格式的字符串,然后使用single打印来打印这个字符串。然后python部分要么读取数据元组,要么不读取,但不会读取导致解包失败的不完整元组。在

所以下面的方法可以:

^{pr2}$

相关问题 更多 >