By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,179 Members | 1,144 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,179 IT Pros & Developers. It's quick & easy.

py-serial + CSV

P: n/a
Hi
I am just trying to analyze (parse) data from the serial port (I have
connected GPS receiver to the ttyS0, so I can read ASCII characters in
the CSV form on the serial port 1).
I am doing this just to understand how Python works (yes, you can call
me Python/Linux newbie :)
My environment is Fedora Core 4, Python 2.4.1

CSV alone (to read CSV data from the file) and py-serial alone (to
read data from the serial port) are working flawlessly.

Even I was trying to google through this group and through the
Internet, I am not able to read (and parse) CSV data directly from the
serial port.

data from my serial port (using py-serial) I am getting this way:
import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
s.readline()

'$GPRMC,101236.331,A,5026.1018,N,01521.6653,E,0.0, 328.1,230805,,*09\r\n'

my next intention was to do something like this:

import csv
r = csv.reader(s.readline())
for currentline in r:
if currentline[0] == '$GPRMC':
print currentline[2]
print currentline[4]

but it does not work

Thanks for your comments

Petr Jakes

Aug 23 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
McBooCzech wrote:
r = csv.reader(s.readline())


csv.reader expects an iterable, not a str.
--
Michael Hoffman
Aug 23 '05 #2

P: n/a
So do I have to save to the file first and analyze later on?

Or there is an other way how to process it (read from the serial and
analyze data) on the fly?

Petr Jakes

Aug 23 '05 #3

P: n/a
McBooCzech wrote:
So do I have to save to the file first and analyze later on?
Certainly not.
Or there is an other way how to process it (read from the serial and
analyze data) on the fly?


I've never used py-serial, so I was hoping someone else would jump in
with the best way to do this (or perhaps you can find it in the
documentation). One way would be to use the iter() built-in to make it
into an iterable, like this:

iterable = iter(s.readline, "")

Note that you do not call s.readline() here; you are only supplying the
bound method itself as an argument. iter() will call it later. I'm
assuming that s.readline returns an empty string when there is no more
input. Please replace that with whatever end sentinel it actually uses.
(None?)

Another way would be to use s.readlines(), which returns a list, which
is iterable, but you would have to wait until the entire list were
collected before beginning processing.
--
Michael Hoffman
Aug 23 '05 #4

P: n/a
On 2005-08-23, McBooCzech <pe**@tpc.cz> wrote:
import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
s.readline()

'$GPRMC,101236.331,A,5026.1018,N,01521.6653,E,0.0, 328.1,230805,,*09\r\n'

my next intention was to do something like this:

import csv
r = csv.reader(s.readline())
for currentline in r:
if currentline[0] == '$GPRMC':
print currentline[2]
print currentline[4]

but it does not work


For something that simple (the data itself doesn't contain any
commas), it's probably easier to use the string's split method
rahter than CSV. Try something like this:

line = s.readline()
words = line.split(',')

--
Grant Edwards grante Yow! Now KEN and BARBIE
at are PERMANENTLY ADDICTED to
visi.com MIND-ALTERING DRUGS...
Aug 23 '05 #5

P: n/a
On Tue, 23 Aug 2005 14:11:59 +0100, Michael Hoffman
<ca*******@mh391.invalid> declaimed the following in comp.lang.python:
Note that you do not call s.readline() here; you are only supplying the
bound method itself as an argument. iter() will call it later. I'm
assuming that s.readline returns an empty string when there is no more
input. Please replace that with whatever end sentinel it actually uses.
(None?)

Another way would be to use s.readlines(), which returns a list, which
is iterable, but you would have to wait until the entire list were
collected before beginning processing.
The latter wouldn't work in this situation -- as the only way to end
the list is to disconnect the serial port <G>

Most GPS receivers, when set to send the messages, will do so at a
rate of one message every 1 or 2 seconds, as I recall.
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Aug 23 '05 #6

P: n/a
Sorry, I did not mentioned the data flow from the serial port is
permanent/continuous (as long as the GPS receiver is connected to the
serial port). The input data are commning every second, they are comma
separated and they are looking like:

$GPGGA,174525.617,5026.1080,N,01521.6724,E,1,05,1. 8,306.5,M,,,,0000*0B
$GPGSA,A,3,02,09,05,06,14,,,,,,,,3.6,1.8,3.1*31
$GPGSV,3,1,09,30,74,294,,05,65,093,49,06,40,223,32 ,02,39,089,49*78
$GPRMC,174525.617,A,5026.1080,N,01521.6724,E,0.0,0 05.8,230805,,*0A
etc....
From the rows they are begining with $GPRMC I want to get following

data only (positions 2,4,6)
174525.617
5026.1080
01521.672

This (according to your suggestions) is my code which works for me

import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
while 1:
line = s.readline()
words = line.split(',')
if words[0]=="$GPRMC":
print words[1], words[3], words[5]

I just wonder if there is some beter (or as you are saying "more
pythonic":) aproach how to write such a piece of code.
--
Petr Jakes

Aug 23 '05 #7

P: n/a
McBooCzech wrote:
Sorry, I did not mentioned the data flow from the serial port is
permanent/continuous (as long as the GPS receiver is connected to the
serial port). The input data are commning every second, they are comma
separated and they are looking like:

$GPGGA,174525.617,5026.1080,N,01521.6724,E,1,05,1. 8,306.5,M,,,,0000*0B
$GPGSA,A,3,02,09,05,06,14,,,,,,,,3.6,1.8,3.1*31
$GPGSV,3,1,09,30,74,294,,05,65,093,49,06,40,223,32 ,02,39,089,49*78
$GPRMC,174525.617,A,5026.1080,N,01521.6724,E,0.0,0 05.8,230805,,*0A
etc....
From the rows they are begining with $GPRMC I want to get following

data only (positions 2,4,6)
174525.617
5026.1080
01521.672

This (according to your suggestions) is my code which works for me

import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
while 1:
line = s.readline()
words = line.split(',')
if words[0]=="$GPRMC":
print words[1], words[3], words[5]

I just wonder if there is some beter (or as you are saying "more
pythonic":) aproach how to write such a piece of code.


That code is quite tidy. You could save yourself the split on lines that
weren't of interest, though frankly this isn't essential - this task
won't use 1% of CPU on almost any computer built in the last five years.
But, if you are interested in seeing other solutions you might consider
it, and it does avoid the split when it's not necessary.

while 1:
line = s.readline()
if line.startswith("$GPRMC"):
words = line.split(",")
print words[1], words[3], words[5]

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Aug 23 '05 #8

P: n/a
Steve Holden <st***@holdenweb.com> writes:
McBooCzech wrote:

[...]
$GPRMC,174525.617,A,5026.1080,N,01521.6724,E,0.0,0 05.8,230805,,*0A
etc....

[...]
s = serial.Serial(port=0,baudrate=4800, timeout=20)
while 1:
line = s.readline()
words = line.split(',')
if words[0]=="$GPRMC":
print words[1], words[3], words[5]
I just wonder if there is some beter (or as you are saying "more

pythonic":) aproach how to write such a piece of code.


That code is quite tidy. You could save yourself the split on lines
that weren't of interest, though frankly this isn't essential - this
task won't use 1% of CPU on almost any computer built in the last five
years. But, if you are interested in seeing other solutions you might
consider it, and it does avoid the split when it's not necessary.
while 1:
line = s.readline()
if line.startswith("$GPRMC"):


"$GPRMC," would be better, -- not to match something like "$GPRMC174...".

--
Sergei.
Aug 23 '05 #9

P: n/a
Sergei, I do not realy understand your comment??? Am I missing
something?

BTW, is there some possibility to address lists like:

print words [1; 3; 5]
instead of
print words[1], words[3], words[5]

Petr Jakes

Aug 23 '05 #10

P: n/a
On 23 Aug 2005 12:59:03 -0700, "McBooCzech" <pe**@tpc.cz> declaimed the
following in comp.lang.python:
Sergei, I do not realy understand your comment??? Am I missing
something?

BTW, is there some possibility to address lists like:

print words [1; 3; 5]
instead of
print words[1], words[3], words[5]

Mix & Matching from two messages <G>

2>$GPRMC,174525.617,A,5026.1080,N,01521.6724,E,0.0 ,005.8,230805,,*0A
2>etc....
2>
2>>From the rows they are begining with $GPRMC I want to get following
2>data only (positions 2,4,6)
2>174525.617
2>5026.1080
2>01521.672
2>
Interesting that you don't want to handle conditions crossing
Greenwich/dateline, or equator (since you ignore the N/S, E/W tags.

2>This (according to your suggestions) is my code which works for me
2>
2>import serial
2>s = serial.Serial(port=0,baudrate=4800, timeout=20)
2>while 1:
2> line = s.readline()
2> words = line.split(',')
2> if words[0]=="$GPRMC":
2> print words[1], words[3], words[5]

Well... Let's see

#open port, etc...
while True:
line = s.readline()
if line.startswith("$GPRMC"):
(msg, timestamp, junk,
raw_latitude, NS_indicator,
raw_longitude) = line.split(",")[:6]
print timestamp, raw_latitude, raw_longitude

line = "$GPRMC,174525.617,A,5026.1080,N,01521.6724,E,0.0, 005.8,230805,,*0A"
(msg, timestamp, junk, .... raw_latitude, NS_indicator,
.... raw_longitude) = line.split(",")[:6] print timestamp, raw_latitude, raw_longitude 174525.617 5026.1080 01521.6724

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Aug 24 '05 #11

P: n/a
McBooCzech enlightened us with:
This (according to your suggestions) is my code which works for me

import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
while 1:
line = s.readline()
words = line.split(',')
if words[0]=="$GPRMC":
print words[1], words[3], words[5]

I just wonder if there is some beter (or as you are saying "more
pythonic":) aproach how to write such a piece of code.


You could use regular expressions instead. And to make it even more
pythonic, replace the "while" and the "line = s.readline()" with
"for line in s:"

Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Aug 24 '05 #12

P: n/a
On 2005-08-24, Sybren Stuvel <sy*******@YOURthirdtower.com.imagination> wrote:
import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
while 1:
line = s.readline()
words = line.split(',')
if words[0]=="$GPRMC":
print words[1], words[3], words[5]

I just wonder if there is some beter (or as you are saying "more
pythonic":) aproach how to write such a piece of code.
You could use regular expressions instead.


"There is a programmer who has a problem to solve. He decides
to use regular expressions. Now he has two problems."
And to make it even more pythonic, replace the "while" and the
"line = s.readline()" with "for line in s:"


Serial port objects aren't iterable.

--
Grant Edwards grante Yow! I was making donuts
at and now I'm on a bus!
visi.com
Aug 24 '05 #13

P: n/a
McBooCzech wrote:
This (according to your suggestions) is my code which works for me

import serial
s = serial.Serial(port=0,baudrate=4800, timeout=20)
while 1:
line = s.readline()
words = line.split(',')
if words[0]=="$GPRMC":
print words[1], words[3], words[5]

I just wonder if there is some beter (or as you are saying "more
pythonic":) aproach how to write such a piece of code.


import csv

from serial import Serial

port = Serial(port=0, baudrate=4800, timeout=20)

for row in csv.reader(iter(port.readline, None)):
if row[0] == "$GPMRC":
print row[1], row[3], row[5]
--
Michael Hoffman
Aug 24 '05 #14

P: n/a
Thanks you all, guys, for your suggestions and help. Everything now
works great :)
Regards
Petr Jakes

Aug 29 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.