472,354 Members | 1,538 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,354 software developers and data experts.

Change serial timeout per read

I'm writing a driver in Python for an old fashioned piece of serial
equipment. Currently I'm using the USPP serial module. From what I can
see all the serial modules seem to set the timeout when you open a
serial port. This is not what I want to do. I need to change the
timeout each time I do a "read" on the serial port, depending on
which part of the protocol I've got to. Sometimes a return character
is expected within half a second, sometimes within 2 seconds, and
sometimes within 20 seconds. How do I do this in USPP, or Pyserial, or
anything else? Currently I'm working in Windows, but I'd prefer a
platform independent solution if possible...

Thanks - Rowan

May 10 '07 #1
4 11393
<r..n@syl..er-br...orgwrote:
I'm writing a driver in Python for an old fashioned piece of serial
equipment. Currently I'm using the USPP serial module. From what I can
see all the serial modules seem to set the timeout when you open a
serial port. This is not what I want to do. I need to change the
timeout each time I do a "read" on the serial port, depending on
which part of the protocol I've got to. Sometimes a return character
is expected within half a second, sometimes within 2 seconds, and
sometimes within 20 seconds. How do I do this in USPP, or Pyserial, or
anything else? Currently I'm working in Windows, but I'd prefer a
platform independent solution if possible...
Yikes!

you will probably have to make the port non blocking, and roll your own
using different time.sleep(n) values between invocations to port.read(1) calls

Unless you can afford to close and open the port each time - but that way leads
to missed characters...

- Hendrik

May 10 '07 #2
you will probably have to make the port non blocking, and roll your own
using different time.sleep(n) values between invocations to port.read(1) calls
What I actually want to do is to respond immediately if the expected
string comes in, but not raise a timeout unless it takes longer than
the maximum time. So if the device I'm communicating with usually
responds in a second, but _can_ take up to 20 seconds, I don't want to
do a sleep(20) then read the port since this will slow everything down
a lot in an average world. I want to keep checking for the expected
string, and act upon it as soon as I've got it, only raising a timeout
if I haven't got it after 20 seconds. I guess to do this using non-
blocking calls I have to do something like:
timesofar = 0
returnstring = port.read(1)
while len(returnstring)<expectedlength:
if timesofar >= timeout:
raise SerialException('Timeout')
time.sleep(checkportinterval)
timesofar += checkpointinterval
returnstring += port.read(1)

This seems rather messy. What I've tried this morning is to produce a
modified version of uspp with a second optional timeout parameter in
its read() function. If this is present, the timeout given is sent to
the port using SetCommTimeouts(). If it's not present, the timeouts
specified when the port was opened are sent. At first sight, with
minimal testing on Windows, this seems to be working, and will leave
my application code a lot cleaner than the non-blocking plus sleep
approach. Of course I don't know whether my method will work on Linux,
and there may be problems I haven't found yet.

Rowan

May 10 '07 #3

<ro***@sylvester-bradley.orgwrote:
What I actually want to do is to respond immediately if the expected
string comes in, but not raise a timeout unless it takes longer than
the maximum time. So if the device I'm communicating with usually
responds in a second, but _can_ take up to 20 seconds, I don't want to
do a sleep(20) then read the port since this will slow everything down
a lot in an average world. I want to keep checking for the expected
string, and act upon it as soon as I've got it, only raising a timeout
if I haven't got it after 20 seconds. I guess to do this using non-
blocking calls I have to do something like:
timesofar = 0
returnstring = port.read(1)
while len(returnstring)<expectedlength:
if timesofar >= timeout:
raise SerialException('Timeout')
time.sleep(checkportinterval)
timesofar += checkpointinterval
returnstring += port.read(1)

This seems rather messy. What I've tried this morning is to produce a
modified version of uspp with a second optional timeout parameter in
its read() function. If this is present, the timeout given is sent to
the port using SetCommTimeouts(). If it's not present, the timeouts
specified when the port was opened are sent. At first sight, with
minimal testing on Windows, this seems to be working, and will leave
my application code a lot cleaner than the non-blocking plus sleep
approach. Of course I don't know whether my method will work on Linux,
and there may be problems I haven't found yet.
If it works it works - no problem with that - fight the
dragons as you meet them, one at a time.

I normally put something like this in a read function
(from memory, not tested):

error = 0
k = ''
try:
k = port.read(1)
except IoError:
error = 1
return error,k

For this to work, you have to first unblock the port using fcntl:

def unblock(f):
"""given file f sets unblock flag to true"""

fcntl.fcntl(f.fileno(),f.F_SETFL, os.O_NONBLOCK)

Then you put a call to the read in a loop, and use time.time()
to do your time out, resetting a start_time variable at the start,
and every time you get a char, and using short sleeps
(millisec or so) after unsuccessful calls to make it less of a
busy loop.

The side benefit of this is that once you have received a char,
you can change gears and use a shorter time out to detect the
end of message, in a protocol and state agnostic way. - when
the device has stopped sending chars for a little while it has
finished saying what it wants to say. - so its easy to write a
get_a_reply routine with variable time out, moving the action
from the char to the message level:

start_time=time.time()
s = ''
while time.time()-start_time < time_out:
error,k = get_a_char(port)
if error:
time.sleep(0.001)
continue
s += k # keep the first char
start_time = time.time()
while time.time() - start_time < 0.005: # inter char time out
status,k = get_a_char(port)
if error:
time.sleep(0.001)
continue
s +=k
start_time = time.time()
break
return s # return empty string or what was received

Something similar works for me on Suse Linux - not sure if
fcntl works on windows.

And no it isn't pretty. - but then very little of what I write is...

- Hendrik

May 11 '07 #4
ro***@sylvester-bradley.org wrote:
I'm writing a driver in Python for an old fashioned piece of serial
equipment. Currently I'm using the USPP serial module. From what I can
see all the serial modules seem to set the timeout when you open a
serial port. This is not what I want to do. I need to change the
timeout each time I do a "read" on the serial port, depending on
which part of the protocol I've got to. Sometimes a return character
is expected within half a second, sometimes within 2 seconds, and
sometimes within 20 seconds. How do I do this in USPP, or Pyserial, or
anything else? Currently I'm working in Windows, but I'd prefer a
platform independent solution if possible...
Thanks - Rowan
I'm not familiar with the USPP serial module. However, I used
the PySerial package successfully for several months on one job
to write a full regression testing framework and suite for testing
a series of different VOIP/SIP phone models (little embedded Linux
systems) via their diagnostics/JTAG serial headers.

It had timeout and writeTimeout settings which I recall were fully
configurable to fractions of a second, None, and 0 (non-blocking).

Under Debian it's available as a simple:

apt-get -f install python-serial.

... and I seem to recall that it worked fine under MS Windows, too.
(In fact it was written in pure Python, no C-lib or .so/.DLL under it).

Ahh ... here's the URL:

http://pyserial.sourceforge.net/

... with backends for CPython (Windows and Linux/UNIX/Posix), and Jython.

Under Python just use:
>>import serial
... then use something like:
>>s0 = serial.Serial(0) # Open first serial port: default settings
... or:
>>s0 = serial.Serial('/dev/ttyS0', 38400, timeout=None) \
# port by device node/name, setting speed and no timeout
>>s1 = serial.Serial(3, 19200, timeout=0) \
# another by number, non-blocking

Then use:
>>s0.read() # or s0.readline() for '\n' terminated
... and various other methods on these ports.

BTW: you can change the timeouts on these connection objects
simply by using s0.timeout=X ... and you can set them to floating
point values --- so you can use tenths of a second.

I remember I was also able to adapt my framework classes to add
support for telnetlib in about an hour of spare time one evening; so
we could use the serial port to manage testing on one block of phones
and we could enable the optional telnet port access built-into a
bank of the other phones and use almost all the same test code with
them. (The only difference was that we couldn't capture reboot
output over the telnet interface; while I could capture and log it
via the serial ports --- in other words it was a natural limitation of
the hardware --- and their embedded system didn't enable something like
a dmesg to capture that after the fact).

The reason I mention the telnetlib angle serves some purpose other than
mere rambling and bragging ... I seem to recall that the methods
supported by the two modules were very closely matched ... so my
adaptation was extremely straightforward.

I see that USPP (univ. serial port for Python) is available at:

http://ibarona.googlepages.com/uspp

... and it's supposed to have most of the same features (from a
quick glance at the web page). However, there's much more info
available at the PySerial page ... and PySerial seems to be far
more recently maintained (with 2.2 "slots' support, for example).

In addition PySerial seems to be linked to a PyParallel package
that's "under development" (presumably by the same author).
(I'm guessing that this latter development can't be done in pure
Python, though).

--
Jim Dennis,
Starshine: Signed, Sealed, Delivered

May 13 '07 #5

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

Similar topics

21
by: nephish | last post by:
i have an interesting project at work going on. here is the challenge. i am using the serial module to read data from a serial input. it comes in as a hex. i need to make it a binary and compare it...
0
by: elcinturapartida | last post by:
Hello all, I am not sure if this question is about threading or serial i/o - it has elements of both. I'm on WinXP (desktop) and WinNT (labtop), when I run miniterm.py there is no problem both...
3
by: collinm | last post by:
hi i send a command to a led display, the led display is suppose to return me some character i write a string on a serial port void ledDisplayExist() { char msg={'\0', '\0', '\0', '\0',...
4
by: H J van Rooyen | last post by:
Hi All, I am writing a polling controller for an RS-485 line that has several addressable devices connected. It is a small access control system. All is well- the code runs for anything from...
3
by: Ole | last post by:
I got a problem with serial port read which I use like this: sp.Read (byteBuffer, 0, 100); but the problem is that it returns before it has read the 100 bytes - is there a way to set up the...
13
by: Rob | last post by:
Hi all, I am fairly new to python, but not programming and embedded. I am having an issue which I believe is related to the hardware, triggered by the software read I am doing in pySerial. I...
2
by: joaquimfpinto | last post by:
Dear All, I made an app in c# that uses several serial ports. For the serial ports I use a pnp Sunix board, some with 8 serial ports other with 4 or even 2 serial ports. Whenever I use the...
6
by: terry | last post by:
Hi, I am trying to send a character to '/dev/ttyS0' and expect the same character and upon receipt I want to send another character. I tired with Pyserial but in vain. Test Set up: 1. Send...
2
by: mmrasheed | last post by:
Hi, I am newbie in python. I am working on Telit GM862 GPS/GPRS module which has python interpreter built in. But it seems this problem is pretty much related to general python structure. I...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made but the http to https rule only works for...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...

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.