I'm running three python scripts on a Pi 4 Model B. These scripts are ran from boot using the '.config/autostart function'. I have a batch script placed in 'autostart' which then in turn starts the three required python scripts in succession. This batch script can be seen below:
import os
import RPi.GPIO as GPIO
import time
from sys import exit
os.system("python3 LoggerChannel1.py & python3 LoggerChannel2.py & python3 shutdown.py")
The issue I'm having is with the 'LoggerChannel1.py' and 'LoggerChannel2.py' scripts. If I start up the pi, all of the scripts run from boot as they should and they function as they should for around a month. After they have been running for a month, these two scripts both stop. When in this stopped state, the Pi itself is still fully functional and the 'shutdown.py' script still works... as this script is also ran from 'batchscript.py' I do not think the issue lies with the batch script.
'LoggerChannel1.py' and 'LoggerChannel2.py' are duplicates of the same script apart from different variables such as different assigned GPIO pins etc. The scripts basically work by sampling the state of a GPIO pin each second and recording its state as a 0 or 1 into a list, after 300 seconds, all entries into the list are summed and this number, along with a timestamp, is recorded into a csv file. The list is then cleared and the loop starts again. The 'LoggerChannel1.py' script can be seen below:
import RPi.GPIO as GPIO
import time
from datetime import datetime
from sys import exit
import os
#This configures BCM GPIO pinout and disables associated GPIO warnings.
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#This defines the pin used for the stop push button and configures it as a GPIO input.
StopLogger = 5
GPIO.setup(StopLogger, GPIO.IN)
#This pin defines the pin used for the 'Logger Running' indicator LED and configures it as a GPIO output.
LoggerRunning = 16
GPIO.setup(LoggerRunning, GPIO.OUT)
#This defines the pins used for digital inputs and outputs for channel 1 and channel 2.
DI01 = 17
DI02 = 27
DO01 = 23
DO02 = 24
#This deduces which channel is to be used, if activechannelIN = DI01 then channel 1 will be used, if activechannelIN = DI02 then channel 2 will be used.
activechannelIN = DI01
#This ensures that if channel 1 input is selected then channel 1 output will be selected and similarly, that if channel 1 input is selected then channel 1 output will be selected.
if ((activechannelIN) == DI01):
activechannelOUT = DO01
if ((activechannelIN) == DI02):
activechannelOUT = DO02
iomap = {'17':'Channel 1', '27':'Channel 2', '23':'Output 1', '24':'Output 2'}
GPIO.setup(activechannelIN, GPIO.IN)
GPIO.setup(activechannelOUT, GPIO.OUT)
logdir = "/home/pi/shared/"
def logToFile(filename, content):
with open(logdir + filename, "a") as logfile:
logfile.write(content + "\n")
lst = "sample_list"
#This is the list in which the rawstate samples are collected and summed.
sample_list = []
#This is the time interval between rawstate samples in seconds.
sample_frequency = 1
#This is the time interval between each log to the csv file in seconds.
logging_frequency = 300
#This is the number of loop iterations after which the sum of sample_list will be logged to the csv file. For as long as sample_frequency = 1, the logging_time can be seen as the logging_frequency minus 1.
logging_time = ((logging_frequency)-1)
while True:
restart = False
for i in range(0,logging_frequency):
time.sleep(sample_frequency)
rawstate = GPIO.input(activechannelIN)
sample_list.extend([int(rawstate)])
print(sample_list)
print (i)
GPIO.output(LoggerRunning, True)
if (GPIO.input(StopLogger) == True):
print("stop button pressed")
GPIO.output(LoggerRunning, False)
GPIO.cleanup()
import loggerstopped.py
break
if i == (logging_time):
print (i)
csvlog = sum(sample_list)
channelname = iomap[str(activechannelIN)]
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
record = timestamp + "," + channelname + "," + str(csvlog)
print (record)
logToFile("LoggerChannel1.csv", record)
sample_list.clear()
restart = True
break
elif (GPIO.input(activechannelIN) == True):
GPIO.output(activechannelOUT, True)
elif (GPIO.input(activechannelIN) == False):
GPIO.output(activechannelOUT, False)
elif (GPIO.input(StopLogger) == True):
print("stop button pressed")
GPIO.cleanup()
import loggerstopped.py
break
if not restart:
break
I feel like this issue has something to do with the list that is formed getting too large since it is happening every time after about a month of running, however,I was under the impression that my use of 'list.clear()' prevented this happening?
Apologies in advance if the code is awful or I'm not making much sense with my questions... this is my first project with python and coding in general and I would appreciate any advice you can give me.
ps -o cmd,rss [-C command|-p pid]
orhtop
(you'll need toapt install htop
, and/or check outtop
, which is already installled).