I have a python script running with an RFID reader. The script runs fine when ran from terminal. When I add python /home/pi/script.py &
to /etc/profile
and reboot the Raspberry Pi, the scripts launches fine but gets stuck in this except:
while True:
#Setting up the RFID reader
try:
reader = mercury.Reader("tmr:///dev/ttyUSB0")
break
except TypeError:
print('Error, manual reset. Retrying')
Why can't I access the USB port when running the python script on boot in /etc/profile?
EDIT
- attempt to fix the issue.
Instead of adding it to
/etc/profile
, add it to/etc/rc.local
. The script won't run when doing this.
EDIT
I needed to sudo raspi-config
and set the RPi to auto boot in desktop mode logged in as user pi. It now works!
3 Answers 3
As @jsotola adviced, you could run it later in the boot process.... or you can write your script to keep on trying to open the port over and over again till it's available (with a certain delay of a few seconds between attempts so that you don't go into a tight loop).
Addendum: Apparently the tip that was followed was to start the script from rc.local... this is my full comment, just in case:
Another would be to add it to /etc/rc.local which is run at the end of the boot sequence, if I'm not mistaken. Just make sure that the process actually goes in the background so that the script doesn't hang (run it with &, for example). There might be other details to take care but it should take care of running it veery late on the boot process.
Hope that's good enough to anyone looking for an answer later on.
-
How would you run it later in the boot process?Daniel– Daniel2018年04月21日 09:24:04 +00:00Commented Apr 21, 2018 at 9:24
-
1One way would be to add it to systemd (which has already been adviced). Another would be to add it to /etc/rc.local which is run at the end of the boot sequence, if I'm not mistaken. Just make sure that the process actually goes in the background so that the script doesn't hang (run it with &, for example). There might be other details to take care but it should take care of running it veery late on the boot process. But the simplest thing is just to make your script attempt to open the port every so often (say, every second.... or every 2 or 5 seconds) until it does open.eftshift0– eftshift02018年04月21日 14:27:19 +00:00Commented Apr 21, 2018 at 14:27
-
The information you placed in the comment about /etc/rc.local should be added to this answer. This solved the problem, and I therefore accept this answer.Daniel– Daniel2018年04月22日 19:20:05 +00:00Commented Apr 22, 2018 at 19:20
There is no relation between /etc/profile and the boot process. Add your script to the init process.
-
1Better add a sleep to your script too, so that other processes get a chance in between retries.Gerard H. Pille– Gerard H. Pille2018年04月21日 02:26:50 +00:00Commented Apr 21, 2018 at 2:26
-
@GerardH.Pille I have tried to find a guide to "Add your script to the init process". Do you agree with the process done here(in method 3): dexterindustries.com/howto/…Daniel– Daniel2018年04月21日 09:15:24 +00:00Commented Apr 21, 2018 at 9:15
-
I would say yes if I was sure your system is using sysvinit, but nowadays most distributions have switched to the systemd moloch, and then you'd need solution 4 or the answer given here by Ingo.Gerard H. Pille– Gerard H. Pille2018年04月21日 12:13:06 +00:00Commented Apr 21, 2018 at 12:13
Start your script as service. First create a new service with:
rpi3 ~$ sudo systemctl edit --force --full rfid-reader.service
Insert this statements, save them and quit the editor:
[Unit]
Description=Setting up the RFID reader
Wants=sockets.target
After=sockets.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStart=/home/pi/script.py
[Install]
WantedBy=multi-user.target
Check the new service:
rpi3 ~$ systemctl status rfid-reader.service
●くろまる rfid-reader.service - Setting up the RFID reader
Loaded: loaded (/etc/systemd/system/rfid-reader.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Now you can enable and test your service:
rpi3 ~$ sudo systemctl enable rfid-reader.service
rpi3 ~$ sudo systemctl start rfid-reader.service
I cannot test it because I have no RFID reader. You are alone with this. Here are some commands that may help:
rpi3 ~$ systemctl status rfid-reader.service
rpi3 ~$ systemctl cat rfid-reader.service
rpi3 ~$ sudo systemctl restart rfid-reader.service
rpi3 ~$ sudo systemctl edit --full rfid-reader.service
One problem is that I cannot check out for you the target after
that /dev/ttyUSB0
is available. In the example above I use
sockets.target
. Don't know if this already initialised /dev/ttyUSB0
.
With
rpi3 ~$ systemctl
you will find what services and targets are active. Only look at the targets. Other candidates for Wants=
and After=
seem to be:
local-fs.target Local File Systems
sysinit.target System Initialization
basic.target Basic System
If sockets.target
does not work I would try other targets in this order.
-
When starting it as a service, would it than run on every time /dev/ttyUSB0 is available?Daniel– Daniel2018年04月21日 09:56:23 +00:00Commented Apr 21, 2018 at 9:56
-
1@DanielRobotics It is a service like any other service and can run as daemon. This simple example has by default
Type=simple
. You didn't said that you want to monitor the status of/dev/ttyUSB0
. This is a bit more complicated. You have to modify your script to work as a daemon and maybe start it with an otherType=
, maybeforking
ordbus
. Have a look atman systemd.service
optionType=
.Ingo– Ingo2018年04月21日 10:31:58 +00:00Commented Apr 21, 2018 at 10:31 -
@DanielRobotics Or maybe you can use
udev
with a proper rule instead of running a service.Ingo– Ingo2018年04月21日 10:43:05 +00:00Commented Apr 21, 2018 at 10:43
/dev/ttyUSB0
does not exist at the time when you run your code ... run the code later in the boot sequesnce