I have the following python program on a raspberry pi:
#! /usr/bin/env python
import time
import Adafruit_CharLCD as LCD
import RPi.GPIO as GPIO
import os
import glob
import os.path
from pathlib2 import Path
import datetime as dt
from datetime import datetime
import threading
import socket
from time import gmtime, strftime
import socket
from Adafruit_CharLCD import Adafruit_CharLCD
import re
#############################lcd screen####################
lcd_rs = 25
lcd_en = 24
lcd_d4 = 23
lcd_d5 = 17
lcd_d6 = 18
lcd_d7 = 22
lcd_backlight = 4
lcd_columns = 16
lcd_rows = 2
lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows, lcd_backlight)
#############################temp reader########################
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
#divice_folder = glob.glob(base_dir + '28-0115818f20ff')[0]
#device_file = divice_folder + '/w1_slave'
def temp_sen():
for folder in os.listdir(base_dir):
#print folder
if re.match(r'[^w1_bus]', folder):
divice_folder = glob.glob(base_dir + folder)[0]
print divice_folder
device_file = divice_folder + '/w1_slave'
print device_file
return device_file
thefile = temp_sen()
def read_temp_raw():
f = open(thefile, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
#temp_f = temp_c * 9.0 / 5.0 + 32.0
#temp_c_str = "{:.3f}".format(temp_c)
#temp_f_str = "{:.3f}".format(temp_f)
#temp_c_str = str(round(temp_c, 1))
#temp_f_str = str(round(temp_f, 1))
#temps = 'C: ' + temp_c_str + '\n\rF: ' + temp_f_str
return temp_c
####################keypad###########################
class keypad():
KEYPAD = [
[1,2,3],
[4,5,6],
[7,8,9],
["*",0,"#"]
]
ROW = [21,6,13,19]
COLUMN = [12,16,20]
def __init__(self):
GPIO.setmode(GPIO.BCM);
def getKey(self):
for j in range(len(self.COLUMN)):
GPIO.setup(self.COLUMN[j], GPIO.OUT)
GPIO.output(self.COLUMN[j], GPIO.LOW)
for i in range(len(self.ROW)):
GPIO.setup(self.ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
rowVal = -1
for i in range(len(self.ROW)):
tmpRead = GPIO.input(self.ROW[i])
if tmpRead == 0:
rowVal = i
if (rowVal < 0) or (rowVal > 3):
self.exit()
return
for j in range(len(self.COLUMN)):
GPIO.setup(self.COLUMN[j], GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(self.ROW[rowVal], GPIO.OUT)
GPIO.output(self.ROW[rowVal], GPIO.HIGH)
colVal = -1
for j in range(len(self.COLUMN)):
tmpRead = GPIO.input(self.COLUMN[j])
if tmpRead == 1:
colVal = j
if (colVal < 0) or (colVal > 2):
self.exit()
return
self.exit()
return self.KEYPAD[rowVal][colVal]
def exit(self):
for i in range(len(self.ROW)):
GPIO.setup(self.ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
for j in range(len(self.COLUMN)):
GPIO.setup(self.ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
#######################logfile###########################
def log_file():
if temp_con.t != 0:
DTnow = str(datetime.now().strftime('%H:%M'))
today = str(datetime.now().date())
tmp = read_temp()
temp = str(tmp)
myfile = Path("/home/pi/TempLog/" + today + ".txt")
if myfile.is_file:
log = open(str(myfile), "a")
log.write(DTnow + " " + temp + "C" + "\n")
else:
log = open(str(myfile),"a+")
log.write(DTnow + " " + temp + "C" + "\n")
threading.Timer(2, log_file).start()
#########################relay control###################
relay_pin = 27
def on():
GPIO.setup(relay_pin, GPIO.OUT)
GPIO.output(relay_pin, GPIO.HIGH)
def off():
GPIO.setup(relay_pin, GPIO.OUT)
GPIO.output(relay_pin, GPIO.LOW)
######temp controler############
class temp_con:
def __init__(self):
self._t = 0
@property
def t(self):
return self._t
@t.setter
def t(self, value):
self._t = value
#############physical inputs################
def phys_in():
while True:
kp = keypad()
list = ['']
digit = None
while True:
digit = kp.getKey()
if digit != None and digit != '*' and digit != '#':
list.append(str(digit))
time.sleep(.5)
digit = None
elif digit == '*':
while True:
log_file()
stop = kp.getKey()
temp_con.t = int(''.join(list))
Rtemp = str(read_temp())
if read_temp() <= temp_con.t and stop != '#':
#time.sleep(1)
#lcd.clear()
print "relay activated!"
#lcd.message("relay activated!")
time.sleep(.5)
lcd.clear()
lcd.message(Rtemp)
print Rtemp
on()
elif read_temp() >= temp_con.t and stop != '#':
#time.sleep(1)
#lcd.clear()
print "relay deactivated!"
#lcd.message("relay deactivated!")
time.sleep(.5)
lcd.clear()
lcd.message(Rtemp)
print Rtemp
off()
elif stop == '#':
temp_con.t = 0
del list[:]
lcd.clear()
print "oven is now off!"
lcd.message("oven is now off!")
off()
digit = None
stop = None
break
######################main#########################
if __name__ == '__main__':
phys_in()
As this program runs it becomes increasingly slower.
the basic flow is use inputs a temperature on a keypad and then hits the '*' key. the program then reads from a temperature sensor and compares the 2 numbers and responds acording to weather the sensor tempurature is higher or lower than the input temperature. if the '#' key is pressed the input temperature is set to 0 and everything is reset to default.
the program is set to run at boot and starts out taking about 4 seconds to complete but after about 10 minutes it takes over 10 seconds and continues to degrade.
I suspect a memory leak some where but I am unable to locate it. can anyone spot the problem?
Edit: forgot to mention this is on a raspberry pi. upon checking processes with top i have discovered that memory usage is not increasing but cpu usage is. has gone from 2% to almost 30% in 2. minutes.
Edit2: this is the result of cProfile:
541055 function calls in 813.851 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 813.851 813.851 <string>:1(<module>)
180 0.005 0.000 0.868 0.005 Adafruit_CharLCD.py:169(clear)
180 0.021 0.000 1.758 0.010 Adafruit_CharLCD.py:234(message)
1225 0.112 0.000 2.051 0.002 Adafruit_CharLCD.py:261(write8)
8755 1.243 0.000 1.997 0.000 Adafruit_CharLCD.py:296(_delay_microseconds)
2450 0.113 0.000 0.368 0.000 Adafruit_CharLCD.py:302(_pulse_enable)
18375 0.154 0.000 0.229 0.000 GPIO.py:190(output)
2450 0.119 0.000 0.261 0.000 GPIO.py:81(output_pins)
5723 0.331 0.000 0.659 0.000 TempManualControlsOven.py:124(exit)
181 0.062 0.000 198.064 1.094 TempManualControlsOven.py:130(log_file)
180 0.005 0.000 0.011 0.000 TempManualControlsOven.py:149(off)
1 0.254 0.254 813.851 813.851 TempManualControlsOven.py:166(phys_in)
723 0.030 0.000 789.489 1.092 TempManualControlsOven.py:52(read_temp_raw)
723 0.068 0.000 789.574 1.092 TempManualControlsOven.py:57(read_temp)
1 0.000 0.000 0.000 0.000 TempManualControlsOven.py:86(__init__)
5723 0.534 0.000 1.617 0.000 TempManualControlsOven.py:88(getKey)
181 0.010 0.000 0.113 0.001 pathlib2.py:1172(__new__)
181 0.002 0.000 0.002 0.000 pathlib2.py:1182(_init)
181 0.038 0.000 0.064 0.000 pathlib2.py:177(parse_parts)
181 0.005 0.000 0.007 0.000 pathlib2.py:413(splitroot)
181 0.005 0.000 0.007 0.000 pathlib2.py:58(_py2_fsencode)
181 0.016 0.000 0.091 0.001 pathlib2.py:797(_parse_args)
181 0.009 0.000 0.101 0.001 pathlib2.py:826(_from_parts)
181 0.005 0.000 0.007 0.000 pathlib2.py:849(_format_parsed_parts)
181 0.015 0.000 0.022 0.000 pathlib2.py:866(__str__)
181 0.001 0.000 0.001 0.000 threading.py:1008(daemon)
181 0.006 0.000 0.174 0.001 threading.py:1046(Timer)
181 0.009 0.000 0.168 0.001 threading.py:1067(__init__)
181 0.004 0.000 0.004 0.000 threading.py:1152(currentThread)
543 0.018 0.000 0.089 0.000 threading.py:242(Condition)
543 0.064 0.000 0.071 0.000 threading.py:260(__init__)
180 0.002 0.000 0.002 0.000 threading.py:294(_release_save)
180 0.002 0.000 0.006 0.000 threading.py:297(_acquire_restore)
180 0.003 0.000 0.013 0.000 threading.py:300(_is_owned)
180 0.016 0.000 0.127 0.001 threading.py:309(wait)
362 0.006 0.000 0.089 0.000 threading.py:542(Event)
362 0.013 0.000 0.083 0.000 threading.py:561(__init__)
181 0.001 0.000 0.001 0.000 threading.py:570(isSet)
1086 0.011 0.000 0.011 0.000 threading.py:59(__init__)
181 0.008 0.000 0.141 0.001 threading.py:603(wait)
181 0.011 0.000 0.011 0.000 threading.py:629(_newname)
361 0.002 0.000 0.002 0.000 threading.py:64(_note)
181 0.022 0.000 0.124 0.001 threading.py:656(__init__)
181 0.006 0.000 0.012 0.000 threading.py:709(_set_daemon)
181 0.019 0.000 0.220 0.001 threading.py:726(start)
22901 0.056 0.000 0.056 0.000 {RPi._GPIO.input}
35727 0.130 0.000 0.130 0.000 {RPi._GPIO.output}
1 0.000 0.000 0.000 0.000 {RPi._GPIO.setmode}
80314 0.517 0.000 0.517 0.000 {RPi._GPIO.setup}
181 0.002 0.000 0.002 0.000 {built-in method __new__ of type object at 0x2d4c48}
362 0.032 0.000 0.032 0.000 {built-in method now}
181 0.005 0.000 0.005 0.000 {hasattr}
724 0.005 0.000 0.005 0.000 {intern}
543 0.005 0.000 0.005 0.000 {isinstance}
2450 0.010 0.000 0.010 0.000 {iter}
28983 0.039 0.000 0.039 0.000 {len}
901 0.106 0.000 0.106 0.000 {method 'acquire' of 'thread.lock' objects}
1268 0.006 0.000 0.006 0.000 {method 'append' of 'list' objects}
722 0.107 0.000 0.107 0.000 {method 'close' of 'file' objects}
181 0.001 0.000 0.001 0.000 {method 'date' of 'datetime.datetime' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
722 0.010 0.000 0.010 0.000 {method 'find' of 'str' objects}
2450 0.015 0.000 0.015 0.000 {method 'items' of 'dict' objects}
362 0.004 0.000 0.004 0.000 {method 'join' of 'str' objects}
181 0.002 0.000 0.002 0.000 {method 'lstrip' of 'str' objects}
723 789.152 1.091 789.152 1.091 {method 'readlines' of 'file' objects}
361 0.001 0.000 0.001 0.000 {method 'release' of 'thread.lock' objects}
181 0.000 0.000 0.000 0.000 {method 'reverse' of 'list' objects}
181 0.003 0.000 0.003 0.000 {method 'split' of 'str' objects}
181 0.029 0.000 0.029 0.000 {method 'strftime' of 'datetime.date' objects}
722 0.006 0.000 0.006 0.000 {method 'strip' of 'str' objects}
181 0.019 0.000 0.019 0.000 {method 'write' of 'file' objects}
904 0.261 0.000 0.261 0.000 {open}
1045 0.003 0.000 0.003 0.000 {ord}
28621 0.091 0.000 0.091 0.000 {range}
723 0.005 0.000 0.005 0.000 {thread.allocate_lock}
181 0.001 0.000 0.001 0.000 {thread.get_ident}
181 0.059 0.000 0.059 0.000 {thread.start_new_thread}
182 19.033 0.105 19.033 0.105 {time.sleep}
273246 0.754 0.000 0.754 0.000 {time.time}
the only thing jumping out at me is readlines.
cProfile.run("phys_in()")in the main and animport cProfileon the top. See what that gives you. Please let us know. - agtoeverread_temp_raw()? Could it be that it takes longer to get out of thewhile ... != 'YES'loop? Maybe add a counter to that loop and print its value after the while to see how that develops? Couldtime.sleep(0.2)combined with a 1-second-read-time of that file be responsible for the longer running time? - agtoever