PySerial 和值拆分错误

Posted

技术标签:

【中文标题】PySerial 和值拆分错误【英文标题】:PySerial and Value Splitting Error 【发布时间】:2015-08-26 13:42:37 【问题描述】:

我遇到了一个严重困扰我的错误,我一直找不到解决方法。我有一个 python 程序,它利用 PySerial 从脉搏血氧仪导入串行端口值。问题是,当函数 ser.readline() 被调用时(换句话说,当 python 程序被告知从 Arduino 的串行监视器读取值时,Arduino 的串行值变得失真并且程序返回值解包错误。

这是python程序。


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

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

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

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

#declare time
thyme = 1

#graph attributes
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")

while True:         
    data_in = ser.readline()
    print data_in
    data_in = data_in.strip('\n')
    bpm,sp02 = data_in.split(",") 

#convert string vals to float
    thyme = float(thyme)
    bpm = float(bpm)
    sp02 = float(sp02)

#print to terminal
    print "Time [s]: %s" % (thyme)
    print "HR [BPM]: %s" % (bpm)
    print "SPO2 [%%]: %s" % (sp02)  
    print 

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

#print values to plot
    plt.scatter(thyme,bpm,color="red")
    plt.scatter(thyme,sp02,color="blue")
    plt.pause(0.1)
    time.sleep(0.05)

#update time
    thyme = thyme + 0.5

#write to .csv
    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])

最重要的sn-p是:


while True:         
    data_in = ser.readline()
    print data_in
    data_in = data_in.strip('\n')
    bpm,sp02 = data_in.split(",") 

Arduino程序如下:

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

int cont = 0;

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

  PCintPort::attachInterrupt(6, readPulsioximeter, RISING);


void loop() 

  char buffer[32]; // make sure buffer is large enough
  sprintf(buffer,"%d,%d \n",eHealth.getBPM(),eHealth.getOxygenSaturation());
  Serial.print(buffer);
  delay(500);



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

  cont ++;

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

所以,串口监视器输出的值是这样的:

67,95
66,95
67,96

等等。

在调用 ser.readline() 时,值会出现偏差,无法通过 split(',') 函数解包。在下面的照片(1) 和(2) 中,您可以在调用 ser.readline() 时看到值的失真。

我如何改写 python OR Arduino 程序以规避这种失真并允许拆分和解压缩值而不会出现任何错误?

【问题讨论】:

截图显示的是python端打印data_in的结果,还是别的什么?在 Arduino 端,我看不到什么调用循环 - 我希望看到一个 while (1) loop();某处。 你怎么知道 ser.readline() 是在数据明显损坏时(即在那一刻)被调用的? 巴尼,感谢您的询问。截图是我在启动 python 程序时运行的 Arduino IDE 串行监视器。实际上,屏幕截图中值的失真正是调用 ser.readline() 的实例。我知道这一点是因为我还指示程序在尝试拆分之前打印 ser.readline() 。每次失败(90% 的时间),它都会在串行监视器中显示损坏的行(因此无法拆分)。 听起来问题出在 Arduino 端。什么叫循环()? 我的理由是,除非您发明了心灵感应 Arduino,或者还有其他您没有提到的事情,否则 Arduino 无法知道 python 脚本是否是听。此外,如果来自 Arduino 的数据有一个额外的逗号,那么您当前的代码当然会打嗝。该打嗝是由损坏的串行数据引起的,而不是导致损坏。 【参考方案1】:

那么有没有可能其他东西异步调用循环(),例如来自中断例程,它可能会在 arduino 调用循环函数的“主线”的同时尝试同时传输另一串读数?顺便说一句:如果在主线 loop() 函数在 eHealth.getBPM() 和 eHealth.getOxygenSaturation() 调用之间调用了中断例程 readPulsioximeter() 并更新了 Pulsioximeter 属性,那么您的代码是否保证从串口上的读数一样吗?

【讨论】:

以上是关于PySerial 和值拆分错误的主要内容,如果未能解决你的问题,请参考以下文章

如何修复“[错误 6] 句柄无效。”使用 PySerial

Pyserial错误:无法打开端口

带有 cx_Freeze 的 Pyserial 运行时错误

使用pyserial发送二进制数据

Python PySerial,如何打开串口?

Pyserial 可以与隐藏设备一起使用吗?