I have a python script that saves values from a MPU6050 sensor to a csv, and then zips the file. When I run it from Thonny or direct from the command line, it works. When I run from rc.local at startup it shows up as running in 'Task Manager' but the files do not save.
My rc.local:
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
sudo python /home/pi/Code/Prospectus/RecordAcceleration.py &
exit 0
My python script named RecordAcceleration.py stored in /home/pi/Code/Prospectus/:
#This is for Sensor Number
SeNum = 4
import numpy as np
#import matplotlib.pyplot as plt
import mpu6050 as mp
import time
import zipfile
import pandas as pd
import os
path = '/'
sensor = mp.mpu6050(0x68)
start = time.time()
j = 1
GB = 2
if len(os.listdir('/media/pi')) ==0:
path = '/home/pi/AccelData'
else:
if not os.path.isdir('/media/pi/' + os.listdir('/media/pi')[0] +'/AccelData'):
os.mkdir('/media/pi/' + os.listdir('/media/pi')[0] +'/AccelData')
path = '/media/pi/' + os.listdir('/media/pi')[0] +'/AccelData/'
while GB > 1:
Results = []
FileStart = time.time()
for i in range(60000):
try:
gx, gy, gz = sensor.get_accel_data(True)
except:
del sensor
time.sleep(0.01)
sensor = mp.mpu6050(0x68)
gx, gy, gz = sensor.get_accel_data(True)
#tx, ty, tz = sensor.get_gyro_data()
Results.append([time.strftime('%y%m%d-%H%M%S.')+str(int((time.time()-int(time.time()))*10000%10000)).zfill(4), gx, gy, gz,SeNum])
time.sleep(0.00001)
Results = np.matrix(Results)
NextFileName = '60kPoints-'+time.strftime('%y%m%d-%H%M')+'-s'+str(SeNum)
df = pd.DataFrame(data=Results)
df.to_csv(NextFileName+'.csv', sep=',', header=False, float_format='%.5f')
print(j, (time.time()-start) / 60.0, NextFileName)
j+=1
zip_file = zipfile.ZipFile(path + NextFileName+'.zip', 'w')
zip_file.write(NextFileName+'.csv', compress_type=zipfile.ZIP_DEFLATED)
zip_file.close()
os.remove(NextFileName+'.csv')
st = os.statvfs(path)
bytes_avail = (st.f_bavail * st.f_frsize)
GB = bytes_avail / 1024 / 1024 / 1024
2 Answers 2
rc.local
has been deprecated for some time - here's one description explaining its current state. You shouldn't use rc.local
because it's not supported any longer.
There are two common alternatives for running your script at startup:
1, cron
with the @reboot
invocation,
2. create a "unit file" to run under systemd
As a general comparison between the two options, cron
is simpler, while systemd
gives you more control once you've "done your homework"
cron
:
Setting up a cron
job to run at startup is generally straightforward. Open your crontab
for editing:
$ crontab -e
This opens your crontab
file in your default editor.
Then add your "job(s)" - for example, to run a Python script named HelloWorld.py
located in pi's home directory at start/boot time requires a single line be added to your crontab
:
@reboot /usr/bin/python /home/pi/HelloWorld.py
This is all that's needed for a very simple cron
job, but complications arise in many real-world applications. I feel that using cron
successfully requires an understanding of its limitations - I've tried to summarize those here with solutions that will often overcome these limitations.
I noted that your rc.local
command calls your Python script using sudo
- suggesting that it must be run with root
privileges. If that's the case, you should use the root crontab
instead of using sudo
in your pi user crontab
. You may get away with using sudo
in a pi
user crontab
in Raspberry Pi (due to how user pi
is configured), but it won't work properly on most other Unix/Linux systems. Otherwise, using the root crontab
is virtually identical to using a user crontab
:
$ sudo crontab -e
There are many Q&A here on using cron
to schedule jobs - I have answered a few myself.
systemd
:
Scheduling a job to run at start/boot time may also be accomplished using what is called a systemd unit
file. systemd
is considered by some to be a better solution in many cases because it does not have some of cron
's limitations. Many would say creating the unit
file is more difficult than creating a cron
job, but like most new tasks, a little experience will make things considerably easier over time.
I won't try to walk through creation of a unit
file, but there are many tutorials available online. There's a brief overview of a unit
file creation here that will be useful for RPi users (as RPi is a Debian derivative). There are also numerous Q&A here on RPi SE that may be useful.
-
I will try to set it up with a cron job and see if it is more stable. Thank youDan Hendrickson– Dan Hendrickson2021年11月24日 17:22:13 +00:00Commented Nov 24, 2021 at 17:22
It was a missing '/' in path if no drive is mounted. The drive does not mount until after the script is already running, so it tries to use the /home/pi location, but I had a mistake there. When I run it after boot, it works fine because the drive is mounted. I added a time.sleep(10) after the imports, and that delay is sufficient for the drives to mount.
/media/pi
(which most likely is the case when you're using rc.local (personally I wouldn't use rc.local anyway... and no need for sudo in rc.local)