串行传感器数据 - 消除不需要的串

时间:2014-10-02 13:24:43

标签: python

我正在使用一些python代码对连接到串口的传感器进行采样。

大部分时间这都非常有效。但偶尔传感器的输出不正确:

['\x80', '19.38', '22.7', '649', 'w\\'] - correct
['\x80', '19.46', '22.7', '648', 'wZ'] - correct
['\x80', '19.49', '22.7', '650', 'w'] - correct
['w', '\x80', '19.45', '22.7', '650'] - error

这导致我的代码出现很多问题。我只是想知道是否有人知道如何开始用“\ x80”之后的值或其他方式分割字符串?

例如:

如果我从传感器收到的字符串被称为'receive',那么我的代码是

Var1,Var2,Var3,Var4,Var5 = receive.split()

现在我需要将Var2转换为float,以便我可以对它做一些数学

Var2float = float(Var2)

这大部分时间Var2是一个像19.38这样的值,直到传感器的输出发生变化,Var2变为'/ x80',无法转换成浮点数

有关如何过滤或绕过此传感器输出错误的任何想法?

3 个答案:

答案 0 :(得分:0)

一个简单的try except子句将解决这个问题:

my_buffer = ['\x80', '19.38', '22.7', '649', 'w\\']
converted_buffer = []
for v in my_buffer:
    try:
        converted_buffer.append(float(v))
    except ValueError:
        print "{} cannot be converted, skipping to the next".format(v)
print converted_buffer

<强>输出

� cannot be converted, skipping to the next
w\ cannot be converted, skipping to the next
[19.38, 22.7, 649.0]

你可以迭代缓冲区,当ValueError引发时只决定如何处理这个值,在这种情况下我们只是将它打印出来,你可以记录它或者随意使用它。

注意:我认为设备中的sync frame意味着\x80说这是传输的开始,很多传感器都有开始和结束同步帧。< / p>

答案 1 :(得分:0)

我能想到的最简单的方法是使用正则表达式来查找\x80子字符串的结尾,并从那里开始拆分字符串。

这是一个例子

import re

data = [
    r'\x80 19.38 22.7 649 w\\',
    r'\x80 19.46 22.7 648 wZ',
    r'\x80 19.49 22.7 650 w',
    r'w \x80 19.45 22.7 650',
]

for record in data:
    m = re.search(r' \\x80 \s+ ', record, flags=re.X)
    if m:
        values = record[m.end():].split()
        print(values)

<强>输出

['19.38', '22.7', '649', 'w\\\\']
['19.46', '22.7', '648', 'wZ']
['19.49', '22.7', '650', 'w']
['19.45', '22.7', '650']

答案 2 :(得分:0)

一般概念首先涉及缓冲数据,第二个检查是否有完整序列,第三个是提取序列。下面的类使缓冲成为可能,并且可以读取和查看单个字节。

class MySerialBuffer:
    def __init__(self):
      self.buffer = []
    def peek(self):
      return self.buffer[0]
    def read(self):
      return self.buffer.pop(0)
    def count(self):
      return len(self.buffer)
    def fill(self, new):
      self.buffer = self.buffer + new
    def extract(self):
      while self.count() > 0 and self.peek() != '\x80':
        self.read()
      if self.count() < 4:
        return None
      self.read()
      return (self.read(), self.read(), self.read())
    def __iter__(self):
      while True:
        out = self.extract()
        if out is None:
          return
        yield out

  msb = MySerialBuffer()
  msb.fill(['\x80', '19.38', '22.7', '649'])
  msb.fill(['\x80', '19.38', '22.7', '649'])
  msb.fill(['w', '\x80', '33.4', '19.38', '22.7', '649', 'f', 'w'])
  msb.fill(['\x80', '19.38', '22.7', '649', 'w'])

  for reading in msb:
    print(reading)

可以大大提高性能。此外,根据您阅读数据的方式,通过以不同方式处理数据,可以大大简化数据并提高性能,因为我编写了课程以处理您在问题中提供的内容。您可能正在读取实际的整数值,并且可以在将它们读入缓冲区时对其进行处理。如果您每秒处理大量样本以帮助您,也可以使用比list更高效的系统。该列表效率低下并附加新项目,pop操作也效率低下。但是,存在其他原始集合可以更有效地处理这些类型的操作,例如Queue