473,757 Members | 2,081 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Parsing data from pyserial

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.Seri al('com1',baudr ate=115200, bytesize=8,
parity='N', stopbits=1,xonx off=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
Dec 3 '06 #1
15 16870
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.Seri al('com1',baudr ate=115200, bytesize=8,
parity='N', stopbits=1,xonx off=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.inde x('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

Dec 3 '06 #2
Lone Wolf wrote:
reading = ser.read(40)
Simply try ser.readline() here, or maybe ser.readline(eo l="\r").

--
Giovanni Bajo
Dec 3 '06 #3
On 2006-12-03, Lone Wolf <lo*******@urea ch.comwrote:
import serial

ser=serial.Seri al('com1',baudr ate=115200, bytesize=8,
parity='N', stopbits=1,xonx off=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"!!
Dec 3 '06 #4
On Sat, 2 Dec 2006 23:02:06 -0500, Lone Wolf
<lo*******@urea ch.comwrote:
>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.Ser ial('com1',baud rate=115200, bytesize=8,
parity='N', stopbits=1,xonx off=0, timeout=1)

ser.write("P M 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
In my dealing with serial gizmos I have to put a delay between
the request sent to the gizmo and the reading of the serial input
buffer for returned data. Serial ports and gizmos need some time
to do their thing.
Dec 3 '06 #5
On 2006-12-03, Si Ballenger <sh**********@c omporium.netwro te:
In my dealing with serial gizmos I have to put a delay between
the request sent to the gizmo and the reading of the serial input
buffer for returned data. Serial ports and gizmos need some time
to do their thing.
I doubt that's the issue. He's reading with a 1-second timeout
value.

--
Grant Edwards grante Yow! The Korean War must
at have been fun.
visi.com
Dec 3 '06 #6
On Sun, 03 Dec 2006 16:52:33 -0000, Grant Edwards
<gr****@visi.co mwrote:
>On 2006-12-03, Si Ballenger <sh**********@c omporium.netwro te:
>In my dealing with serial gizmos I have to put a delay between
the request sent to the gizmo and the reading of the serial input
buffer for returned data. Serial ports and gizmos need some time
to do their thing.

I doubt that's the issue. He's reading with a 1-second timeout
value.
I would think a time delay would be needed between the below two
lines in the code if he expects to get a useable data string back
from the gizmo for the command sent to it.

ser.write("TC 016 240 100 240 016 240\r\n")
reading = ser.read(40)
Dec 3 '06 #7
Grant Edwards wrote:
When something odd seems to be happening with strings, always
print `whatever` rather than whatever
:-)

Unholy perlism, Batman!

For the benefit of gentle readers who are newish and might not have
seen the ` character in Python code outside a string literal, or for
those who'd forgotten, there is a cure:

| >>re.sub(r"`(.* ?)`", r"repr(\1)", "print `whatever`, `foo`, `bar`")
| 'print repr(whatever), repr(foo), repr(bar)'
:-)

Dec 3 '06 #8
On 2006-12-03, Si Ballenger <sh**********@c omporium.netwro te:
>>In my dealing with serial gizmos I have to put a delay between
the request sent to the gizmo and the reading of the serial input
buffer for returned data. Serial ports and gizmos need some time
to do their thing.

I doubt that's the issue. He's reading with a 1-second timeout
value.

I would think a time delay would be needed between the below two
lines in the code if he expects to get a useable data string back
from the gizmo for the command sent to it.

ser.write("TC 016 240 100 240 016 240\r\n")
reading = ser.read(40)
No. A delay isn't needed as long as the device responds within
1 second. The read() call will wait up to 1 second for the
first byte of the response.

--
Grant Edwards grante Yow! NEWARK has been
at REZONED!! DES MOINES has
visi.com been REZONED!!
Dec 3 '06 #9
On 2006-12-03, John Machin <sj******@lexic on.netwrote:
Grant Edwards wrote:
>When something odd seems to be happening with strings, always
print `whatever` rather than whatever

:-)

Unholy perlism, Batman!
OK, make that "print repr(whatever)" . :)

--
Grant Edwards grante Yow! I selected E5... but
at I didn't hear "Sam the Sham
visi.com and the Pharoahs"!
Dec 3 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
7160
by: alastair | last post by:
Hi, I'm using pyserial to transfer data from PC to another device - the data is either from an ASCII file or binary data file. Everything works fine up until I start using files of a particular size on Linux, around 1.3MB. When I send the data on windows everything is ok - on Linux I get the following traceback:
3
4779
by: ouz as | last post by:
hi, I want to transfer 0 bit and 1 bit in order with pyserial.But pyserial only send string data. Can anyone help me? Sorry about my english.. _________________________________________________________________ Depolama alani sikintisindan kurtulun - hemen Hotmail'e üye olun! http://odeme.hotmail.com.tr
4
5075
by: Zarathustra | last post by:
Hi, where I can find the pyserial handbook?? THanks
2
3741
by: Jon | last post by:
Hi, I wrote some code to read in info from a port using pyserial. the code reads info sent by a box that is connected to my computer by an rs232-to usb adapter. When I was writing the code and testing it on my computer it worked fine. I ran py2exe on the program (which uses wxpython for its gui) and sent the output from the py2exe to another computer. now when I try to run it on this other computer it fails to open the port. it gives...
3
3212
by: Lone Wolf | last post by:
I want to thank everybody who tried to help me, and also to post my solution, even though I don’t think it is a very good one. Many of you correctly guessed that there was an “\r” included with the packet from the CUMcam, and you were correct. The actual format of the packet is: M xxx xxx xxx xxx xxx xxx xxx xxx\r. Unfortunately, splitting the packet using \r wouldn’t help because the format of the data stream that I get with the...
3
8158
by: Ron Jackson | last post by:
I am using Python 2.5 on Windows XP. I have installed Pyserial and win32all extensions. When I try to run the example program scan.py (included below), or any other program using pyserial, as soon as it hits the statement: s = serial.Serial(i) I get the error:
0
596
by: pauland80 | last post by:
<snip> <snip> Late thanks for your both answers! (Please excuse me for that) The problem was a bug in the device firmware. But before finding this, I dugg lightly in the pyserial source and found (to take with care!) :
0
2078
by: [david] | last post by:
http://pyserial.sourceforge.net/ "port numbering starts at zero, no need to know the port name in the user program" But the implementation in SerialWin32 is just (Portnum +1)
3
11631
by: naveen.sabapathy | last post by:
Hi, I am trying to use virtual serial ports to develop/test my serial communication program. Running in to trouble... I am using com0com to create the virtual ports. The virtual ports seem to be working fine when I test it with Hyperterminal . I am using the example program that comes with pyserial, as below. --------------- import serial
0
9297
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10069
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9884
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9735
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8736
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6556
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5324
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3395
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2697
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.