views:

639

answers:

3

Hi folks,

I've created a script to monitor the output of a serial port that receives 3-4 lines of data every half hour - the script runs fine and grabs everything that comes off the port which at the end of the day is what matters...

What bugs me, however, is that the cpu usage seems rather high for a program that's just monitoring a single serial port, 1 core will always be at 100% usage while this script is running.

I'm basically running a modified version of the code in this question: pyserial - How to Read Last Line Sent from Serial Device

I've tried polling the inWaiting() function at regular intervals and having it sleep when inWaiting() is 0 - I've tried intervals from 1 second down to 0.001 seconds (basically, as often as I can without driving up the cpu usage) - this will succeed in grabbing the first line but seems to miss the rest of the data.

Adjusting the timeout of the serial port doesn't seem to have any effect on cpu usage, nor does putting the listening function into it's own thread (not that I really expected a difference but it was worth trying).

  • Should python/pyserial be using this much cpu? (this seems like overkill)
  • Am I wasting my time on this quest / Should I just bite the bullet and schedule the script to sleep for the periods that I know no data will be coming?
A: 

Would a system style solution be better? Create the python script and have it executed via Cron/Scheduled Task?

pySerial shouldn't be using that much CPU but if its just sitting there polling for an hour I can see how it may happen. Sleeping may be a better option in conjunction with periodic wakeup and polls.

Bob Breznak
If you run from cron or sleep, you'll miss serial output. The program must be run as a daemon or active process.
jmanning2k
I appreciate the suggestion TheLobster, but jmanning2k has got the right of it - this is meant to be a daemon like process.We will get data every half hour but that's about as precise as it will be. A cron/scheduled task approach would have to be *insanely* accurate in it's timing to work and the smallest upset would result in lost data. That simply won't do.
Crazy Joe Malloy
+4  A: 

Maybe you could issue a blocking read(1) call, and when it succeeds use read(inWaiting()) to get the right number of remaining bytes.

tonfa
Awesome! It's purring like a kitten now, next to nil CPU usage and it grabs everything that I'm throw at it.I had been using read(inWaiting()) under the impression that it would function the same way as read(1) - obviously this is not the case. Thanks for clearing that up for me.
Crazy Joe Malloy
Cool, and thanks for making me discover pyserial, I'll consider it next time I play with serial ports :)
tonfa
It's excellent - painless to setup and use, this was the only thing I had trouble with and **I** was the problem.
Crazy Joe Malloy
A: 

Good approach, I took it to another level as I abstracted both pyserial and sockets, I'm fairly certain I can get this same approach to reducing cpu usage to work, knowing where its being hogged at.

Chuck