Python Serial Read Timeout Example
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?
Python Serial Read Timeout Example
Currently I'm working in Windows, but I'd prefer a platform independent solution if possible. Thanks - Rowan. 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)= 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. = 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.FSETFL, os.ONONBLOCK) Then you put a call to the read in a loop, and use time.time to do your time out, resetting a starttime 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 getareply routine with variable time out, moving the action from the char to the message level: starttime=time.time s = ' while time.time-starttime. 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). Here's the URL. 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.
Click download file button or Copy wifi rehacker unlock key URL which shown in textarea when you clicked file title, and paste it into your browsers address bar. Serial key for wifi rehacker.
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. 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.

I am relatively new to raspberry and I'm trying to connect it to an Arduino using the raspberry USB. I spoke too soon. It worked for a short time. Now it is back the way it was when I reported the issue - ie not working.
I have verified that the script works one line at a time in Python console and I have also confirmed that I can send the same data back and forth between the arduino and raspberry in Minicom. Why doesn't the Python script work as expected? The script runs without error but prints a blank line (line feed) instead of the expected result. I have fitted an LED on the arduino which flashes when receiving data from raspberry. It flashes as expected when I run the python script from raspberry with the ser.write statement. Looks (here ) like the open is not required. Can you verify what exactly the Arduino returns as reponse (especially is there a newline character included)?
And how fast does it respond? And might be worth checking the communication speed is the correct one. As read reads only one byte, it's most likely not the best choice - readline expects a newline at end of line, but with the timeout defined when opening the port should work (returns when newline read or timed out) - maybe try a bit longer timeout in case Arduino is slow to respond. I'm not sure what Arduino you've got, but you may find that opening the serial port is causing it to reset - and for a time (500ms or more) after reset the Arduino bootloader will be running, not your temperature-reading sketch. If you're typing things in at the console, you won't notice this because the bootloader will have finished before you got to read anything. So I'd try putting a time.sleep(2.0), after you've opened the port, before you try to talk to your sketch.
If that helps, you may find the time delay can be reduced, depending on what bootloader you've got. Also, you may find you need to call flushInput on the serial port at the start, to discard old data left lying about in the buffers by whatever was running previously. Hi, i have raspberry pi zero w and am working with SIM800l.
My problem is i have connected sim800l with pi zero using gpio pins (2 pin-5v, 6 pin-gnd,8 pin-RX of sim800l & 10pin-TX of sim800l) and able to send/receive sms and calls using minicom AT commands. Now, i have to run AT commands using python code. I have tried this code for 1 AT command as AT: import serial ser = serial.Serial('/dev/ttyS0', 115200, timeout=5) ser.write('AT r') response = ser.read(2) print response ser.close Problem is code is running without error but there is no response for AT. There should be OK response i should get but unable to get it. I have tried r n in ser.write also ser.readline but no use whats the problem?? Thank you for help.
Display posts from previous: Sort.