从pyserial解析数据 [英] Parsing data from pyserial

查看:209
本文介绍了从pyserial解析数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从CMUcam通过我的串口获取数据。

这个Gizmo跟踪颜色并返回一个数据包。

数据包有9个数据点(好吧,因为第一个

点只是一个数据包标题,实际上只有8个数据点),用空格分隔如下:M

xxx xxx xxx xxx xxx xxx xxx xxx


这是我正在使用的代码(python v24):


import serial


ser = serial.Serial(''com1'',baudrate = 115200,bytesize = 8,

parity =''N'',stopbits = 1, xonxoff = 0,超时= 1)

ser.write(" PM 1")#This将CMUcam设置为轮询模式


我在范围内(0,100,1):

ser.write(" TC 016 240 100 240 016 240 \\ n) 

reading = ser .read(40)

打印阅读

components = reading.split()

打印组件

ser。关闭


以下是一个示例输出:


M 37 79 3 4 59 124 86 25

[' 59,123,87,25,M,37,79, 3,4,59,

''124'',''86'',''25'',''M

'']

M 38 77 3 2 59 124 86 25

[''39'',''85'',''26'' ,M,38,77,3,2,59,124,86,

''25'',''M'',''38''

,''7'']


我的问题是我试图将

数据包的每个数据点都放到一个单独的变量中。通常,这很容易,因为我只是解析数据包,读取数组并将每个

元素分配给变量,例如。 mx =组件[1]。但是,

在这里不起作用,因为我使用split()方法得到的原始数据包和数组是不同的。如果我要用
尝试读取在第一个示例输出中创建的数组,mx将

为123而不是37,就像它在数据包中一样。在第二个

示例中,数组是85而数据包是38.


尽管我可以理解,pyserial正在读取

数据并有助于重新排列它以使其符合原始的

数据包格式M xxx xxx xxx xxx xxx xxx xxx xxx。我想

认为我在原始数据包上使用的split()方法(即

读取变量)将刚刚返回一个带有

九个元素就像数据包一样。情况并非如此,而且我不知道如何解决这个问题。


我在这里和其他地方搜索了存档运气。任何

帮助真的很感激!


狼:)


________________________________________________

获取你自己的800号码

语音邮件,传真,电子邮件等等
http://www.ureach.com/reg/tag

解决方案

Lone Wolf写道:
< blockquote class =post_quotes>
我正试图从CMUcam通过我的串口获取数据。

这个Gizmo跟踪颜色并返回一个数据包。

数据包有9个数据点(好吧,因为第一个

点只是一个数据包标题,实际上只有8个数据点),用空格分隔如下:M

xxx xxx xxx xxx xxx xxx xxx xxx


这是我正在使用的代码(python v24):


import serial


ser = serial.Serial(''com1'',baudrate = 115200,bytesize = 8,

parity =''N'',stopbits = 1, xonxoff = 0,超时= 1)

ser.write(" PM 1")#This将CMUcam设置为轮询模式


我在范围内(0,100,1):

ser.write(" TC 016 240 100 240 016 240 \\ n) 

reading = ser .read(40)



您要求的是40个字节的数据。您将获得40个字节的数据。


但是您的数据包(可能)可变长度,(大概)

由CR和/或LF终止。该设备的文档是什么

告诉你什么?


打印阅读



你从print语句中看到的并不一定是你b
$ b得到的结果。

改变它来打印repr(阅读)并向我们展示你看到的内容。


components = reading.split()

打印组件

ser.close


这是一个示例输出:


M 37 79 3 4 59 124 86 25

[''59'',' '123'',''87'',''25'',''M'',''37'',''79'',''3'',''4'',''59 '',

''124'',''86'',''25'',''M

'']

M 38 77 3 2 59 124 86 25

[''39'',''85'',''26'',''M'',''38'',' 77,3,2,59,124 ,''86'',

''25'',''M'',''38''

,''7'']



让我们尝试重建阅读:


| >> a = [''59'',''123'',''87'',''25'',''M'',''37'',''79'',' 3,4,59,

| ......'''124''''''86''''''''''''''''''' >> astrg =''''。join(a)

| >> astrg

| '59 123 87 25 M 37 79 3 4 59 124 86 25 M''

| >> len(astrg)

| 39<<<<< ====哦!差不多40 !!

| >> b = [''''''''''''','''''''''''''''''''''''''''''''''' '2'',''59'',''124'',

''86'',

| ......'''25'',''M'',''38''

| ......,''7'']

| >> bstrg =''''。join(b)

| >> bstrg

| ''39 85 26 M 38 77 3 2 59 124 86 25 M 38 7''

| >> len(bstrg)

| 40<<<<< ====哦!正好是40 !!!


我的猜测:设备输出的数据包速度超过你能处理的数量

。所以你得到40字节的字节抢占。抓举很长

足以覆盖整个数据包,每个数据包可能包含两个数据包。您需要丢弃碎片。如果您需要所有

数据,您最好获得一些如何实施流量控制的帮助 -

我从未使用过pyserial而且我是''我不打算阅读_all_文件

你:-)


我很想知道什么是打印repr(阅读)实际显示。我是

强烈怀疑每个数据包末尾有一个CR(无LF);在显示的两个案例中,这将导致打印读数。显示为

只有一个数据包...想一想:回车,没有换行,

会导致覆盖。与这两个样本

巧合的是,该行的第一部分看起来并不奇怪,有一个4,5或

的6位数字显示尾随片段结束的位置


我的问题是我试图将

数据包的每个数据点放入一个单独的变量。通常,这很容易,因为我只是解析数据包,读取数组并将每个

元素分配给变量,例如。 mx =组件[1]。



更好的是:


mx,foo,bar,......,eight_vbl = components [start :开始+ 8]

一旦你弄清楚应该是什么开始,例如start =

components.index(''M'')+ 1


然而,那个

没有在这里工作是因为我使用split()方法得到的原始数据包和数组是不同的。如果我要用
尝试读取在第一个示例输出中创建的数组,mx将

为123而不是37,就像它在数据包中一样。在第二个

示例中,数组是85而数据包是38.


尽管我可以理解,pyserial正在读取

数据并有助于重新排列它以使其符合原始的

数据包格式M xxx xxx xxx xxx xxx xxx xxx xxx。



如果您已经阅读了Serial.read()方法的文档字符串,那么您是否已经得出结论?


pyserial对你的数据包格式一无所知。


我会有

认为分裂我在原始数据包上使用的方法(即

的读取变量)将刚刚返回一个数组,其中包含数据包的九个元素。情况并非如此,而且我不知道如何解决这个问题。


我在这里和其他地方搜索了存档运气。任何

帮助真的很感激!



有了一点repr()和一点RTFM,人们通常可以在没有

帮助:-)


干杯,

John


Lone Wolf写道:


reading = ser.read(40)



只需尝试ser.readline ()这里,或者也许是ser.readline(eol =" \r")。


-

Giovanni Bajo


2006-12-03,Lone Wolf< lo ******* @ ureach.comwrote:


import序列号


ser = serial.Serial(''com1'',baudrate = 115200,bytesize = 8,

parity =''N'',stopbits = 1,xonxoff = 0,超时= 1)

ser.write(" PM 1")#This将CMUcam设置为轮询模式


for i in range(0,100,1):

ser.write(" TC 016 240 100 240 016 240 \\ nn)

阅读= ser.read(40)

打印阅读

components = reading.split()

打印组件

ser.close


这是一个示例输出:


M 37 79 3 4 59 124 86 25

[''59'',''123'',''87'',''25'',''M'',''37'',''79'',''3'', ''4'',''59'',

''124'',''86'',''25'',''M

' ']

M 38 77 3 2 59 124 86 25

[''39'',''85'',''26'',''M' ','''38'',''77'',''3'',''''''''''''''''''''''''''''''''''''''' $ b''25'',''M'',''38''

,''7'']


我的问题是那个我试图将

数据包的每个数据点都放到一个单独的变量中。通常,这将是简单的,因为我只是解析数据包,读取数组和

将每个元素分配给变量,例如。 mx = components [1]。

然而,这不起作用,因为原始数据包

不同。



我对此表示怀疑。尝试打印阅读而不是阅读。我怀疑你从ser.read()获得的字符串有一个

carraige-return,你没看到什么时候打印

阅读。


如果我尝试读取第一个例子中创建的数组

输出,mx将是123而不是37,就像在

包中一样。在第二个例子中,数组是85,而

数据包是38.


尽管我可以理解,pyserial正在读取

数据并有助于重新排列它以使其符合原始的

数据包格式M xxx xxx xxx xxx xxx xxx xxx xxx。



不,不是。我编写了Posix低级代码,它位于

pyserial中。我已经在Windows和

Linux上广泛使用了pyserial。它没有重新排列任何东西。


我会想到我在

原始数据包上使用的split()方法(即读取变量)只会返回一个包含九个元素的数组。这个

不是这样的,我对如何解决这个问题感到茫然。



当字符串出现奇怪的情况时,总是

打印`what`而不是


我已经在这里和其他地方搜索了档案而没有运气。任何

帮助真的很感激!



-

Grant Edwards grante哇! STRETCH SOCKS的售价为



visi.com" 7-11" !!

I''m trying to get data through my serial port from a CMUcam.
This gizmo tracks a color and returns a packet of data. The
packet has nine data points (well, really eight since the first
point is just a packet header) separated by spaces as follows: M
xxx xxx xxx xxx xxx xxx xxx xxx

Here is the code I am using (python v24):

import serial

ser=serial.Serial(''com1'',baudrate=115200, bytesize=8,
parity=''N'', stopbits=1,xonxoff=0, timeout=1)

ser.write("PM 1") #This sets the CMUcam to poll mode

for i in range(0,100,1):
ser.write("TC 016 240 100 240 016 240\r\n")
reading = ser.read(40)
print reading
components = reading.split()
print components
ser.close

Here is an example output:

M 37 79 3 4 59 124 86 25
[''59'', ''123'', ''87'', ''25'', ''M'', ''37'', ''79'', ''3'', ''4'', ''59'',
''124'', ''86'', ''25'', ''M
'']
M 38 77 3 2 59 124 86 25
[''39'', ''85'', ''26'', ''M'', ''38'', ''77'', ''3'', ''2'', ''59'', ''124'', ''86'',
''25'', ''M'', ''38''
, ''7'']

My problem is that I am trying to get each data point of the
packet into a separate variable. Ordinarily, this would be easy,
as I would just parse the packet, read the array and assign each
element to a variable eg. mx = components[1]. However, that
doesn''t work here because the original packet and the array that
I got from using the split() method are different. If I were to
try read the array created in the first example output, mx would
be 123 instead of 37 like it is in the packet. In the second
example, the array is 85 while the packet is 38.

As near as I can figure out, pyserial is reading a stream of
data and helpfully rearranging it so that it fits the original
packet format M xxx xxx xxx xxx xxx xxx xxx xxx. I would have
thought the split() method that I used on original packet (ie
the "reading" variable) would have just returned an array with
nine elements like the packet has. This is not the case, and I
am at a loss about how to fix this.

I''ve searched the archive here and elsewhere with no luck. Any
help REALLY appreciated!

Wolf :)

________________________________________________
Get your own "800" number
Voicemail, fax, email, and a lot more
http://www.ureach.com/reg/tag

解决方案

Lone Wolf wrote:

I''m trying to get data through my serial port from a CMUcam.
This gizmo tracks a color and returns a packet of data. The
packet has nine data points (well, really eight since the first
point is just a packet header) separated by spaces as follows: M
xxx xxx xxx xxx xxx xxx xxx xxx

Here is the code I am using (python v24):

import serial

ser=serial.Serial(''com1'',baudrate=115200, bytesize=8,
parity=''N'', stopbits=1,xonxoff=0, timeout=1)

ser.write("PM 1") #This sets the CMUcam to poll mode

for i in range(0,100,1):
ser.write("TC 016 240 100 240 016 240\r\n")
reading = ser.read(40)

You are asking for 40 bytes of data. You will get 40 bytes of data.

However your packets are (presumably) variable length, (presumably)
terminated by CR and/or LF. What does the documentation for the device
tell you?

print reading

What you see from the print statement is not necessarily what you''ve
got.
Change that to print repr(reading) and show us what you then see.

components = reading.split()
print components
ser.close

Here is an example output:

M 37 79 3 4 59 124 86 25
[''59'', ''123'', ''87'', ''25'', ''M'', ''37'', ''79'', ''3'', ''4'', ''59'',
''124'', ''86'', ''25'', ''M
'']
M 38 77 3 2 59 124 86 25
[''39'', ''85'', ''26'', ''M'', ''38'', ''77'', ''3'', ''2'', ''59'', ''124'', ''86'',
''25'', ''M'', ''38''
, ''7'']

Let''s try to reconstruct "reading":

| >>a = [''59'', ''123'', ''87'', ''25'', ''M'', ''37'', ''79'', ''3'', ''4'', ''59'',
| ... ''124'', ''86'', ''25'', ''M'']
| >>astrg = '' ''.join(a)
| >>astrg
| ''59 123 87 25 M 37 79 3 4 59 124 86 25 M''
| >>len(astrg)
| 39 <<<<<==== ooh! almost 40!!
| >>b = [''39'', ''85'', ''26'', ''M'', ''38'', ''77'', ''3'', ''2'', ''59'', ''124'',
''86'',
| ... ''25'', ''M'', ''38''
| ... , ''7'']
| >>bstrg = '' ''.join(b)
| >>bstrg
| ''39 85 26 M 38 77 3 2 59 124 86 25 M 38 7''
| >>len(bstrg)
| 40 <<<<<==== ooh! exactly 40!!!

My guess: the device is pumping out packets faster than you can handle
them. So you are getting 40-byte snatches of bytes. A snatch is long
enough to cover a whole packet with possible fragments of packets at
each end. You will need to discard the fragments. If you need all the
data, you''d better get some help on how to implement flow control --
I''ve never used pyserial and I''m not going to read _all_ the docs for
you :-)

I''m very interested to see what print repr(reading) actually shows. I''m
strongly suspecting there is a CR (no LF) at the end of each packet; in
the two cases shown, this would cause the "print reading" to appear as
only one packet ... think about it: carriage return, with no linefeed,
would cause overwriting. It is a coincidence with those two samples
that the first part of the line doesn''t appear strange, with a 4, 5, or
6-digit number showing up where the trailing fragment ends

My problem is that I am trying to get each data point of the
packet into a separate variable. Ordinarily, this would be easy,
as I would just parse the packet, read the array and assign each
element to a variable eg. mx = components[1].

better would be:

mx, foo, bar, ......, eighth_vbl = components[start:start + 8]
once you have worked out what start should be, e.g. start =
components.index(''M'') + 1

However, that
doesn''t work here because the original packet and the array that
I got from using the split() method are different. If I were to
try read the array created in the first example output, mx would
be 123 instead of 37 like it is in the packet. In the second
example, the array is 85 while the packet is 38.

As near as I can figure out, pyserial is reading a stream of
data and helpfully rearranging it so that it fits the original
packet format M xxx xxx xxx xxx xxx xxx xxx xxx.

How, if you''ve read the docstring for the Serial.read() method, did you
come to that conclusion?

pyserial knows nothing about your packet format.

I would have
thought the split() method that I used on original packet (ie
the "reading" variable) would have just returned an array with
nine elements like the packet has. This is not the case, and I
am at a loss about how to fix this.

I''ve searched the archive here and elsewhere with no luck. Any
help REALLY appreciated!

With a bit of repr() and a bit of RTFM, one can often manage without
help :-)

Cheers,
John


Lone Wolf wrote:

reading = ser.read(40)

Simply try ser.readline() here, or maybe ser.readline(eol="\r").

--
Giovanni Bajo


On 2006-12-03, Lone Wolf <lo*******@ureach.comwrote:

import serial

ser=serial.Serial(''com1'',baudrate=115200, bytesize=8,
parity=''N'', stopbits=1,xonxoff=0, timeout=1)

ser.write("PM 1") #This sets the CMUcam to poll mode

for i in range(0,100,1):
ser.write("TC 016 240 100 240 016 240\r\n")
reading = ser.read(40)
print reading
components = reading.split()
print components
ser.close

Here is an example output:

M 37 79 3 4 59 124 86 25
[''59'', ''123'', ''87'', ''25'', ''M'', ''37'', ''79'', ''3'', ''4'', ''59'',
''124'', ''86'', ''25'', ''M
'']
M 38 77 3 2 59 124 86 25
[''39'', ''85'', ''26'', ''M'', ''38'', ''77'', ''3'', ''2'', ''59'', ''124'', ''86'',
''25'', ''M'', ''38''
, ''7'']

My problem is that I am trying to get each data point of the
packet into a separate variable. Ordinarily, this would be
easy, as I would just parse the packet, read the array and
assign each element to a variable eg. mx = components[1].
However, that doesn''t work here because the original packet
and the array that I got from using the split() method are
different.

I doubt it. Try printing `reading` instead of reading. I
suspect that the string you''re getting from ser.read() has a
carraige-return in it that you aren''t seeing when you do print
reading.

If I were to try read the array created in the first example
output, mx would be 123 instead of 37 like it is in the
packet. In the second example, the array is 85 while the
packet is 38.

As near as I can figure out, pyserial is reading a stream of
data and helpfully rearranging it so that it fits the original
packet format M xxx xxx xxx xxx xxx xxx xxx xxx.

No, it isn''t. I wrote the Posix low-level code that''s in
pyserial. I''ve used pyserial extensively on both Windows and
Linux. It doesn''t rearrange anything.

I would have thought the split() method that I used on
original packet (ie the "reading" variable) would have just
returned an array with nine elements like the packet has. This
is not the case, and I am at a loss about how to fix this.

When something odd seems to be happening with strings, always
print `whatever` rather than whatever

I''ve searched the archive here and elsewhere with no luck. Any
help REALLY appreciated!


--
Grant Edwards grante Yow! There''s a SALE on
at STRETCH SOCKS down at the
visi.com "7-11"!!


这篇关于从pyserial解析数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆