473,700 Members | 2,838 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 11760
<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
3105
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 AND bit 1 is 1 then the real value is 1... long story short. is there a good way to compare...
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 seemed to write ok, If I run the code to do the write, then I connect to the device through...
3
5052
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
5067
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 up. - the first lines are just some debug prints.
3
6084
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 read because I use the timeout option in my app. Thanks
13
6205
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 should reply with their Id and Ack in this format '0 Ack' To be certain that I didn't miss a...
2
3956
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
6663
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
10397
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 and work on the command. This is similar to readline() function. Unfortunately there is no...
0
8638
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
9058
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 captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8952
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
7791
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
5894
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
4395
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 the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3081
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2371
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2018
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.