I am using PySerial in concert with an integrated circuit board (ICB) to continually monitor the state of several infra-red (IR) emitter/sensor units (i.e. check if an IR beam broken or clear), and my program seems to eat through the computer's memory after about a day. I suspect this has something to do with PySerial, but am not certain.
Some project background: I have three IR emitter/sensor units labelled 1, 2, and 3. If none of the beams are broken, the ICB outputs the string '0' through a serial connection. If the beam on unit 1 is broken, the string '1' is output, '2' for unit 2, and so on. It's safe to assume only one beam can be broken at any point in time. I've programmed the ICB to output one string value (0, 1, 2, or 3) every 1/10th of a second.
Via the following code, I'm using PySerial to read the ICB output, and PyGame to record the amount of time each beam is broken, to a maximum amount of time (all in Python 2.7):
import pygame, serial
def breakLoop(cumulative_break_time, max_cumulative_break_time, ser, is_beam_broken_org):
elapsed_break_time = 0.
clock.tick() #Start clock.
while (cumulative_break_time + elapsed_break_time < max_cumulative_break_time):
ser.flushInput()
is_beam_broken = int(ser.read(1))
if is_beam_broken == is_beam_broken_org:
elapsed_break_time += clock.tick()/1000.
else:
break
cumulative_break_time += elapsed_break_time
return cumulative_break_time, elapsed_break_time
#Initialize objects and constants
ser = serial.Serial()
ser.baudrate = 115200
ser.port = 'COM3'
ser.open()
clock = pygame.time.Clock()
max_cumulative_break_time = 900.
cumulative_break_time = 0.
out_file = open('test.csv','w')
while cumulative_break_time < max_cumulative_break_time: #Enter main event loop.
ser.flushInput()
is_beam_broken = int(ser.read(1))
if is_beam_broken:
print 'Beam %s broken.' % is_beam_broken
cumulative_break_time, elapsed_break_time = breakLoop(cumulative_break_time, max_cumulative_break_time, ser, is_beam_broken)
print 'Beam %s un-broken.' % is_beam_broken
print 'Elapsed break time was: ', elapsed_break_time, ' s'
print 'Cumulative break time is now: ', cumulative_break_time, ' s'
print''
out_file.write(','.join([str(is_beam_broken),str(elapsed_break_time)]) + '\n')
out_file.flush()
out_file.close()
ser.close()
print '\n\nDone! Press any key to quit.'
raw_input('')
Now, the code functions fine, but when I let this run over a day or so, I get an "out of memory" error. I'm guessing this is something to do with PySerial, because I'm continually reading input from the ICB...perhaps because I'm always flushing the Serial buffer? I didn't think flushing memory contents made that same memory unavailable...
Also, I read through PySerial's documentation and came across this line:
Not implemented yet / Possible problems with the implementation: RFC 2217 flow control between client and server (objects internal buffer may eat all your memory when never read).
I don't know what RFC 2217 is, but I know I'm leaking memory somehow.
I'd really appreciate any input. Am I on the right track? Or could there be some other cause of my script's excessive memory usage?
Of course, I'm happy to further explain any details should they help you in helping me :)