How to make statements in python script behave just like them executed in interactive shell
I have an instrument that is conne开发者_开发百科cted to a serial comm port. I use Python 3.2 in Windows XP, plus pySerial module. I have a problem when I execute a script consisting of a series of statements that open the comm port, configure it, write strings to and receive strings from it. Thoese strings aer either commands pertinent to the instrument (control) or responses from the instrument (response).
When those statements are executed in a python interpreter interactively (at >>>), I get what I expect and the results are good and correct. However, when I execute the script, either within the interpreter or from a shell, I don’t get what I want. The statements in the script is the same as what I use in the interactive interpreter.
Why do I get the strange behavior and how can I change the script to make it to behave like in interactive interpreter?
def read(comport):
wrt_str=b'movt 3000'+b'\r\n'
ret_str=comport.write(wrt_str)
wrt_str=b'scan'+b'\r\n'
ret_str=comport.write(wrt_str)
rsp_str=comport.readlines() #########1
wrt_str=b'hllo'+b'\r\n'
ret_str=comport.write(wrt_str)
rsp_str=comport.readlines()#########2
The problem is with the lines above with #######. In interactive mode, there is about 1 second delay at #1, and 9 seonds delay at #2. I get correct responses there. However, if I execute the script above, there is no delay at all and I get incorrect results (garbage). I set the read timeout to 0 in comm port set up, as
comport.timeout=0
So the comport should be in blocking mode if it waits for the end of line or end of file.
Update (Aug 19, 2011)
I have an update to the original post I made a few days ago. I think I know what the problem is and want to know if anyone has a solution:
After putting "print" and "time.sleep(delay)" after every statement, I found when the script is running, it appears going around the pyserial statement, such as "comport.write(..)" or "comport.readlines(...)" while the pyserial command is executing (appearing as waiting and busying doing some thing, you know serial port is slow). So for example, when I exec all statements in a python interactive shell, I am not able to type and run a new statement if the previous one is not returned. Let's ay, if comport.readlines() is not returning, I can't type and run the next comport.write(...) statemtn. However, in a script that is running, if the comport.readlines() is busy reading, the next statement is running, if the next statement happens to be a comport.write() which will abort the reading.
Is there any way to force the python script to behave like running exactly sequentially?
I read the document of pyserial:
timeout = None: wait forever
timeout = 0: non-blocking mode (return immediately on read)
timeout = x: set timeout to x seconds (float allowed)
if you set comport.timeout=0 then readlines() will return immediately. Try set comport.timeout = 10.
I'd try sticking each command string into its own function, then calling those sequentially, with pauses.
alternatively, if you know how long the output data string is, you could set your read()
/readlines()
to stop reading after that many bytes have passed, or an arbitrary number, if your read strings are variable lengths.
Try sticking a pause (time.sleep(1)
for instance) after each comport.write
. This will give the device time to respond to each command before you look for the response.
As HYRY points out, setting timeout
to 0
will return immediately, so it does not do what you think it does. Beyond that, though, when you execute the statements one at a time, there's a delay as you type in each line. When you execute them in a script, they run without much of a gap in between.
精彩评论