Это мой первый вопрос, и я относительно новичок в python, так что любезно несите меня. Ваше руководство с этой проблемой будет принята с благодарностью!Arduino, Python, Serial и Unpacking Ценности: «ValueError: требуется больше, чем 1 значение для распаковки»
У меня есть pulse oximeter, который используется с particular Arduino shield для получения 2 простых сигналов: частоты пульса и содержания насыщения кислородом. См 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() вызывается, разделенный запятыми строки выглядит следующим образом:
65,95
67,96
67,95
70,94
просто, правда?
Ну, я использую программу 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
Тогда почему нет ack, когда программе так просто поручено распаковать две переменные и назначить их массивам? Это проблема, которая возникает в другой моей программе, и я хотел бы разобраться в ней! Любая помощь очень ценится!
Действительно, моя интуиция говорит, что программа питон читает Arduino серийный на примере, в котором линия не полностью напечатанной. После внедрения кода и загрузки его в Arduino, я все равно получаю ту же ошибку на частой основе. Возможно, буфер недостаточно велик? – preacherperkins
Возможно, это связано с реализацией 'Serial.print'. Также я не знаю подробных функций функции C 'printf'.Возможно, печатные сообщения помещаются один за другим в поток, но не освобождают поток после его завершения (чтобы его можно было прочитать до завершения печати). Попробуйте модифицировать свой код python таким образом, чтобы он читал из потока, пока не встретит '' \ 0''. Если требуется несколько чтений, вы можете присоединить части к верным кортежам. Я попытаюсь обновить свой андер в ближайшее время, чтобы проиллюстрировать, что я имею в виду. –
Я вижу, что вы имеете в виду, и попытается изменить мой код на Python таким образом, чтобы он не выполнял значение unpack, пока функция readline() не вернет все три значения. Однако, обратите внимание, что я очень новичок в python, и любые предложения кода будут очень полезны. Я также извиняюсь за задержку - я был вне города на выходные. Благодаря! – preacherperkins