我正在使用一些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',无法转换成浮点数
有关如何过滤或绕过此传感器输出错误的任何想法?
答案 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
。