473,554 Members | 3,102 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 11696
<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(returnstrin g)<expectedleng th:
if timesofar >= timeout:
raise SerialException ('Timeout')
time.sleep(chec kportinterval)
timesofar += checkpointinter val
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***@sylveste r-bradley.orgwrot e:
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(returnstrin g)<expectedleng th:
if timesofar >= timeout:
raise SerialException ('Timeout')
time.sleep(chec kportinterval)
timesofar += checkpointinter val
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.f ileno(),f.F_SET FL, 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.00 1)
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.00 1)
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
3073
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 bit by bit to another byte. They have some weird way they set this up that i have to compare these things with AND. in other words, if bit 1 is 1...
0
697
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 writing, reading, opening the com port, no errors, etc. But if I run wxTerminal.py when read from it nothing happens. It ran without error and it...
3
5029
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', '\0', '\1', 'Z', '0', '0',
4
5059
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 three hours to three days, then sometimes when I get a comms error and have to send out a nak character, it fails hard... The traceback below pops...
3
6079
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 port in a syncronious state so that it wont return before it has finished? And no - I can't use the work around to smaple until I got all 100 bytes...
13
6176
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 am sending a short message to a group of embedded boxes daisy chained via the serial port. When I send a 'global' message, all the connected units...
2
3949
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 development computer I don't have ay problem with my application.
6
6636
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 '%' to serial port and make sure it reached the serial port. 2. Once confirmed, send another character.
2
10392
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 need a promt/terminal when the device is connected to PC. If user enters a command by serial port and press "Enter" then the data is read by the device...
0
7596
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7798
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. ...
0
8039
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7560
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...
0
7887
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...
0
6140
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...
1
5431
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3556
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
838
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...

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.