You can manage this by using the /etc/udev/rules.d/99-arduino.rules file to hard-code each Arduino to a logical port.
Here's an example of adding a fourth UNO to a BrewPi host. Hopefully you'll find it explanatory but if you have any questions please ask!
You can also use this to manage UNO's connected via Bluetooth or Wifi adapters.
In this example "RPINTS" is the host name, and each UNO instance has its associated file sets (rooted under both /home/pi and /var/www) in unique folders.
Code:
Adding Fourth UNO R3 to RPINTS
Cloned /home/brewpi/brewpi3 to /home/brewpi/brewpi4
Changed /home/brewpi/brewpi4/settings/config.cfg
scriptPath = /home/brewpi/brewpi4/
wwwPath = /var/www/brewpi4/
port = /dev/brewpi4
altport = /dev/null
boardType = uno
beerName = BrewPi2%20Test%202
dataLogging = active
save and exit
Cloned /var/www/brewpi3 to /var/www/brewpi4
Changed /var/www/brewpi4/config_user.php
$scriptPath = '/home/brewpi/brewpi4';
save and exit
Changed tag in /var/www/brewpi4/index.php:
<title>BrewPi4 reporting for duty!</title>
Find UNO serial number
$ udevadm info -a -n /dev/ttyACM1 | less > info.log
looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.2':
KERNELS=="1-1.2"
ATTRS{manufacturer}=="Arduino (www.arduino.cc)"
ATTRS{serial}=="55431313238351104021"
Changed the rules file:
$ sudo nano /etc/udev/rules.d/99-arduino.rules
SUBSYSTEM=="tty", KERNEL=="ttyACM*", ATTRS{serial}=="85336303532351F0A031", SYMLINK+="brewpi1", GROUP="brewpi"
SUBSYSTEM=="tty", KERNEL=="ttyACM*", ATTRS{serial}=="754373038303510BF870", SYMLINK+="brewpi2", GROUP="brewpi"
SUBSYSTEM=="tty", KERNEL=="ttyACM*", ATTRS{serial}=="5543131323835130B160", SYMLINK+="brewpi3", GROUP="brewpi"
SUBSYSTEM=="tty", KERNEL=="ttyACM*", ATTRS{serial}=="55431313238351104021", SYMLINK+="brewpi4", GROUP="brewpi"
Reloaded the udev rules:
$ sudo /etc/init.d/udev reload
Restarted scripts successfully
Set up cron job to start the script for BrewPi4:
$ sudo nano /etc/cron.d/brewpi4
PYTHON=/usr/bin/python
SCRIPTPATH=/home/brewpi/brewpi4
MAILTO=""
* * * * * brewpi $PYTHON $SCRIPTPATH/brewpi.py --config $SCRIPTPATH/settings/config.cfg --checkstartuponly --dontrunfile; [ $? != 0 ] && $PYTHON -u $SCRIPTPATH/brewpi.py --config $SCRIPTPATH/settings/config.cfg 1>$SCRIPTPATH/logs/stdout.txt 2>>$SCRIPTPATH/logs/stderr.txt &
Save the file and exit
Restart CRON:
$ sudo /etc/init.d/cron restart
BrewPi4 is up and running on USB!
Cheers!
Okay I may have spoke to soon but I think I found the actual problem... I didn't change the cron entry file like the example. I figured the example was doing that because of the needed fourth brewpi install needing a crone entry to start yet a fourth instance of the script.. if i run a kill then manually run the script the script starts up and works...
pi@raspberrypi:/home/brewpi $ sudo python brewpi.py --kill
Jan 05 2019 12:54:23 Killing all BrewPi Processes
pi@raspberrypi:/home/brewpi $ ./brewpi.py
Jan 05 2019 12:54:30 Opening serial port
Jan 05 2019 12:54:30 Notification: Script started for beer 'keggerator'
Jan 05 2019 12:54:40 Checking software version on controller...
Jan 05 2019 12:54:40 Found BrewPi v0.2.10 build unknown, running on an Arduino Uno with a revC shield on port /dev/brewpi
Jan 05 2019 12:54:41 {"BeerTemp":null,"BeerSet":null,"BeerAnn":null,"FridgeTemp": 67.77,"FridgeSet":null,"FridgeAnn":null,"RoomTemp": 70.02,"State":0}
Jan 05 2019 12:54:41 {"BeerTemp":null,"BeerSet":null,"BeerAnn":null,"FridgeTemp": 67.77,"FridgeSet":null,"FridgeAnn":null,"RoomTemp": 70.02,"State":0}
Jan 05 2019 12:56:42 {"BeerTemp":null,"BeerSet":null,"BeerAnn":null,"FridgeTemp": 67.77,"FridgeSet":null,"FridgeAnn":null,"RoomTemp": 70.02,"State":0}
My chron entry that was already there created automatically by brewpi was slightly different from the example.. I tried matching it more like the example and to no avail.... is there something maybe causing the cron job to try and start before the usb devices are assigned by the udev rule? If so any reason I cant create a systemd service for brewpi instead of the cron job?