Python Event Driven Seriale

 
  1. Python Event Driven Framework

I have ran across a couple of different event libraries that are available on the AVR and Andruino but I am not sure which one is the best option. What I would like to do is design my program in a event driven style but not sure how to go about this.I have a project that I need to keep lightweight but also in this program I have several actions that can be happening at any given time i.e. Digital Inputs being triggered and I need to run code whenever these events happen.I found that looked promising but I wanted to get some feedback from some others that might of used this type of library before and might be able to provide some examples and maybe some experiences.Another site I found and lists all sorts of different libs.

We have some equipment that communicates at 57600 baud RS232. The path fromthe PC is USB to a Phillips USB hub, then off of that a TUSB3410 USB/Serialconverter. The driver for the 3410 chip creates a 'normal' comm port (likeCOM3). There is a C program that has no problem talking to the equipment,but two Python programs have trouble. One is a big, scary, controllerprogram, and the other, since that is the one I'm having trouble with, is awhile loop.The while loop program seems to be able to open and close the serial portall day. It also seems to be able to open, send 'blahblahblah', and closethe port for the same length of time.

But writing anything to the portquickly (not always right away.like maybe 5-6 iterations through theloop?) causes thewin32file.CloseHandle(self.hComPort)statement in the 'def close(self)' function of the serialwin32.py file ofthe pySerial package to hang for a few seconds, then return. The nextopen attempt fails with the 'could not open port: (995, 'CreateFile', 'TheI/O operation has been aborted because of either a thread exit or anapplication request.'

) exception.The failure mode with the large program is it opens the port successfullycompletes a bunch of back and forth talking, then hangs for a few secondswhen the port is closed, and then can't reopen the port. It never seems tofail in the middle of a bunch of reads and writes, but only when/after theport is closed. It can also run for the better part of an hour with noproblems then all of a sudden. Like I said, the C program never fails.I've looked at the settings in the C program, and in the serialwin32.pyfile and tried to set them the same as best I can, but no luck. Digginginto the win32all stuff gets me lost quite quickly.

I see all of thesettings, but have no idea what to try. This is all on WinXP, Python 2.4.1,the latest pySerial and win32all.Does this ring any bells with anyone?Thanks!Bob. Bob Greschke wrote: But writing anything to the portquickly (not always right away.like maybe 5-6 iterations through theloop?) causes thewin32file.CloseHandle(self.hComPort)statement in the 'def close(self)' function of the serialwin32.py file ofthe pySerial package to hang for a few seconds, then return.Are you certain it is this line that is blocking, and not the precedingline which is a call to SetCommTimeouts? How did you prove which lineit is? (I don't have an answer to the problem, just wanted to be sureof the information.)-Peter. 'Peter Hansen' wrote in messagenews:rf.@powergate.ca. Bob Greschke wrote: But writing anything to the portquickly (not always right away.like maybe 5-6 iterations through theloop?) causes thewin32file.CloseHandle(self.hComPort)statement in the 'def close(self)' function of the serialwin32.py file ofthe pySerial package to hang for a few seconds, then return.Are you certain it is this line that is blocking, and not the precedingline which is a call to SetCommTimeouts?

How did you prove which lineit is? (I don't have an answer to the problem, just wanted to be sure ofthe information.)-PeterHi!I had the SetCommTimeouts line commented out. I just have a couple ofprints before and after the CloseHandle line.I didn't write the C program, but it looks like it never closes the serialport.

It opens it when it starts up, then keeps it open until it quits.Tsk tsk tsk. Maybe they did that to cover up this problem.:)Bob. Bob Greschke wrote: I didn't write the C program, but it looks like it never closes the serialport. It opens it when it starts up, then keeps it open until it quits.Tsk tsk tsk. Maybe they did that to cover up this problem.:)Actually, I'm curious why you don't do the same. I'd call it veryunusual (in my experience) to have a program open and close a serialport repeatedly. Among other things, this means that the DSR/DTR linesare toggling high and low repeatedly, and that alone could causeundesirable behaviour in certain devices.In none of my own serial-based programs (perhaps a few dozen such todate) have I ever opened and closed a port other than at startup andshutdown (just as your C program does).

Unless you've got a goodreason to do otherwise, if this solves your problem it's certainly themost direct approach to do so.-Peter. 'Peter Hansen' wrote in message Actually, I'm curious why you don't do the same. I'd call it very unusual(in my experience) to have a program open and close a serial portrepeatedly. Among other things, this means that the DSR/DTR lines aretoggling high and low repeatedly, and that alone could cause undesirablebehaviour in certain devices.I guess I could. It's just that not releasing the port/not KNOWING that theport has been closed at predictible times is our chief complaint about theC program.

As an aside, when I left work I left a version of thewhile-loop program running, opening the port, writing to the equipment,getting a response, and closing the port. It was up to about 180 sucessfulcycles (in a row - it will stop if it fails).

Python Event Driven Seriale

I think it's a hardwareproblem.:)In none of my own serial-based programs (perhaps a few dozen such to date)have I ever opened and closed a port other than at startup and shutdown(just as your C program does). Unless you've got a good reason to dootherwise, if this solves your problem it's certainly the most directapproach to do so.One of the serial ports (there are actually two) is used to read some NMEAsentences from a GPS. It is only rarely read. If it is also opened whenthe program starts and kept open would you just dump the buffer and thenread to get the most current info? What happens when the buffer fills up?The 'main' port is just commands sent, responses received kind of traffic.I'd write a C extension to do the serial stuff, but I don't know a thingabout Windows programming.Thanks! Bob Greschke wrote:'Peter Hansen' wrote in message Actually, I'm curious why you don't do the same.

I'd call it very unusual(in my experience) to have a program open and close a serial portrepeatedly. Among other things, this means that the DSR/DTR lines aretoggling high and low repeatedly, and that alone could cause undesirablebehaviour in certain devices.I guess I could. It's just that not releasing the port/not KNOWING that theport has been closed at predictible times is our chief complaint about theC program. As an aside, when I left work I left a version of thewhile-loop program running, opening the port, writing to the equipment,getting a response, and closing the port. It was up to about 180 sucessfulcycles (in a row - it will stop if it fails).

I think it's a hardwareproblem.:)Hmm, keep the port open. One bad thing that can happen is that if youdon;t keep the port open then another program running on the box and nipin and claim ownership of the port. I agree with Peter, I neverrelinquish the port in code unless I have a reason to (ie shutdown orchnaging the COM port I'm using). I doubt that it is a hardware problemon your device as the RS232 tandard (I prefer to call it a rumour)doesn't have any kind of RRP.

Even if you are running RTS/CTS orXON/XOFF then you again shouldn't have a problem becuase once the datais sent.received then the lines should be back to normal. If you wishto test this and am not happy with writing C code to test it then maybeyou could try it with something that doens;t use C code such as Java(with the javax.comm or rxtx extensions)?In none of my own serial-based programs (perhaps a few dozen such to date)have I ever opened and closed a port other than at startup and shutdown(just as your C program does). Unless you've got a good reason to dootherwise, if this solves your problem it's certainly the most directapproach to do so.One of the serial ports (there are actually two) is used to read some NMEAsentences from a GPS.

Dead space 3 pc download. It is only rarely read. If it is also opened whenthe program starts and kept open would you just dump the buffer and thenread to get the most current info? What happens when the buffer fills up?The 'main' port is just commands sent, responses received kind of traffic.PySerial doesn;t have any kind of event firing to notify you when datais available. The way I get round this is to have a loop polling (in aseperate thread) to see if any data is available (it's a method on theinterface), then read all the data in and fire this off to mylisteners/observers with the read data. That way your buffers will notfill up.

I would also do that on your other port as well to give you acommon way of receiving data. I did this and then started downloadingrandom stuff of wiki and sending the data from one serial port toanother in huge chunks with no problems.I'd write a C extension to do the serial stuff, but I don't know a thingabout Windows programming.Thanks!I wouldn't bother as well - PySerial works fine for me, as I mentionedthe only thing I don;t like is no evetn firing when data is availabelbut you can code around taht if you wish to.Cheers,Neil-Neil BennSenior Automation EngineerCenix BioScienceBioInnovations ZentrumTatzberg 47D-01307DresdenGermanyTel: +49 (0)351 4173 154e-mail:Cenix Website. Bob Greschke wrote: 'Peter Hansen' wrote in message I'd call it very unusual(in my experience) to have a program open and close a serial portrepeatedly.One of the serial ports (there are actually two) is used to read some NMEAsentences from a GPS.

It is only rarely read. If it is also opened whenthe program starts and kept open would you just dump the buffer and thenread to get the most current info? What happens when the buffer fills up?The 'main' port is just commands sent, responses received kind of traffic.Generally, yes, you just dump data received up to the point you areabout to send a new request (if this is a request/response type ofthing).

Python Event Driven Seriale

PySerial has a.flush method of some kind I believe, or youcan just loop as long as inWaiting isn't False.If you aren't using hardware or software handshaking, then the bufferfilling up is a non-issue for you or the sender. If you're usinghandshaking, then you do have to keep the buffer from filling. Prettymuch all my interesting code runs the PySerial stuff in a separatethread, reading whenever data is available, and (this is asimplification) posting it to a Queue which the main thread can readfrom as required. In that scenario, you could just have a flag thatcauses the receive thread to stop posting stuff to the Queue where youcurrently have close the port to prevent data being seen.I don't recall: is NMEA 0183 asynchronous? Messages can be sent by theGPS even when you didn't ask for one explicitly? If so, then it'spossible there are problems even with your current approach: what if youopen the port halfway through a packet, and receive only the last fewbytes? If it's synchronous (data sent only in response to yourrequests), then none of this is an issue since there will be no trafficunless you ask for it, so the serial port will be idle between uses.-Peter.

Neil Benn wrote: PySerial doesn;t have any kind of event firing to notify you when datais available. I use PySerial in a 16 line data collection systemwith LOTS of threads, and yes am frustrated by read.This sounds excellent, keep us updated.BTW, haven't done any event driven Python except Tkinter.Would this a class library which would let youdefine an event and a handler?Do you have a one line code example?Thanks.Peter Hansen wrote:Neil Benn wrote:PySerial doesn;t have any kind of event firing to notify you when datais available. On Thu, 28 Jul 2005 21:55:35 -0600, 'Bob Greschke' declaimed the following in comp.lang.python:One of the serial ports (there are actually two) is used to read some NMEAsentences from a GPS. It is only rarely read. If it is also opened whenthe program starts and kept open would you just dump the buffer and thenread to get the most current info? What happens when the buffer fills up?The 'main' port is just commands sent, responses received kind of traffic.Two ports in use?Best advice I could come up with is to create two threads (oneper port) to handle the I/O, and use Queue to transfer data in/out ofthe I/O threads to the main process.For the GPS side (as I recall, those send messages continuously,at something like a 1-2second rate) use a global flag to indicate ifdata is desired or not; not = read&dump, desired = read&queue to main.The command port probably should read&queue everything. Main processwould be a loop retrieving data from the queue (use one queue, andpackage the data with a source Identifier: ('GPS', data-string), ('CMD',command-data)I'd write a C extension to do the serial stuff, but I don't know a thingabout Windows programming.I had to do serial stuff on a W98 laptop in C.

It was NOTpretty (and basically came down to the same thing - running the I/O ina thread and signaling the main process when data had arrived, usingvery low-level w32 os calls). The only 'easy' serial port programming onWindows is the VB MSCOMM control, which does have an event handler (ONEhandler, requiring long case/if logic to determine if it is input/outputor error).-.

On Fri, 29 Jul 2005 08:08:56 -0400, Peter Hansen declaimed the following in comp.lang.python:I don't recall: is NMEA 0183 asynchronous? Messages can be sent by theAsynchronous, messages at something like 1sec intervals (maydepend on how many variations of messages are being sent).open the port halfway through a packet, and receive only the last fewbytes? If it's synchronous (data sent only in response to yourGPS messages have a recognizable start; something like $GPxxxOne would have to scan for the start of message, and then makesure to read through to the end.-. Phil wrote: I use PySerial in a 16 line data collection systemwith LOTS of threads, and yes am frustrated by read.This sounds excellent, keep us updated.BTW, haven't done any event driven Python except Tkinter.Would this a class library which would let youdefine an event and a handler?Roughly speaking, yes.

Python Event Driven Framework

The primary parent class happens to be calledHandler, and is a threading.Thread subclass which in its run methodbasically sits in a win32 WaitForMultipleObjects call for variousthings to happen, then calls handler routines based on which event fires.Do you have a one line code example?One line? This isn't Perl.;-)from bent.serial import Driverclass MyDriver(Driver):def init(self, port, baud=9600):Driver.init(self, port, baud=baud, name='iodriver')self.start # start the threaddef handleSerialRead(self, data):print 'read%r'% datadef handleSerialDsr(self, level):print 'DSR', leveldef handleSerialBreak(self):print 'break detected, ho hum'Usage for this would be simply: d = MyDriver('COM3') and then sit backand watch the, uh, fireworks. Or at least the print statements.Anything interesting represents a much more sophisticated subclass whichparses the data as it arrives, of course, and at least in my case thencalls a handlePacket routine where the fun really begins.-Peter.