Greetings,
I recently had an issue with configuring Seeed XIAO to run the Joystick 2.0 library. With guidance from here and digging on the internet I finally solved the issue. However, the solution prevented me from running the library on any other model of boards.
Searched the internet and the forums here. Solution were go back to Arduino IDE 1.xx and run a portable set version or modify the IDE configuration each time I changed board/project. There were a few request for change to add this type of feature since about 2015, but don't see it happening anytime soon.
So I decided to write a bash script to do what I needed for use on Linux. Does not work on Windows. Don't have a Mac to try it on. May work or need a bit of tweaking to get it to run.
Below is the script I came up. Releasing it to the community to use as they see fit.
It works by by moving the Arduino folders from there normally installed location to a folder named "ArduinoProfile" within the user's home folder. Each profile is given it own folder within it. i.e. ArduinoProfile/Default.
Links are then placed at the original Adruino folder locations pointing to the current profile.
Folders are:
- User'sHomeFolder/.arduino15
- User'sHomeFolder/.arduinoIDE
- User'sHomeFolder/.config/Arduino IDE
- User'sHomeFolder/.config/arduino-ide
- User'sHomeFolder/Arduino
This allows each profile to be a fully self contained environment with only the files and libraries needed. You can have profiles for board type or for each project, any way you choose. This prevents libraries from conflicting.
Features include:
- Creating a new empty profile. Arduino IDE will automatically fill it on its first run.
- Clone an existing profile. No need reconfigure a default setup.
- Delete a profile. Deleted profile are permanently deleted. Use with care.
- Switch profiles. Cannot/should be done while Arduino IDE is running. Will cause data corruption.
Must be run in console window.
Tested on Kubuntu 23.4.
#!/bin/bash
# Author: Randy S. Bancroft
# Date: June 12, 2023
#
# I make no guarantees for this script.
# Use at your own risk.
#
# Allows the use of multiple profiles/configurations of the Arduino IDE 2.xx.
# You can only run one profile at a time.
# You can run multiple instances of the same profile.
#
# It does so by by moving the Arduino folders from there normally installed
# location to a folder named "ArduinoProfile" within the user's home folder.
# Each profile is given it own folder within it. i.e. ArduinoProfile/Default.
# Links are then placed at the original Adruino folder locations pointing to
# the current profile.
# Folders are:
# - User'sHomeFolder/.arduino15
# - User'sHomeFolder/.arduinoIDE
# - User'sHomeFolder/.config/Arduino IDE
# - User'sHomeFolder/.config/arduino-ide
# - User'sHomeFolder/Arduino
# This allows each profile to be a fully self contained environment with only
# the files and libraries needed.
# You can have folders for board type or for each project, any way you choose.
# This prevents libraries from conflicting.
# Features include:
# - Creating a new empty profile. Arduino IDE will automatically fill it on
# its first run.
# - Clone an existing profile. No need reconfigure a default setup.
# - Delete a profile. Deleted profile are permanently deleted. Use with care.
# - Switch profiles. Cannot/should be done while Arduino IDE is running.
# Will cause data corruption.
#
# This script is free to use/modify/distribute as you desire.
START_UP_DIR=`PWD`
HOME=~
IDE_NAME="arduino-ide_2.1.0_Linux_64bit.AppImage"
IDE_PATH="${HOME}/Desktop/"
START_IDE="0" # 1 launches Arduino IDE after selecting profile. Ensure IDE_PATH and IDE_NAME are correct.
PROFILE="Default"
NUMBER_OF_DIRS=""
LINK=""
CURRENT_PROFILE=""
YN="n"
function list_profiles {
for i in "${!userarr[@]}"; do
echo $i ${userarr[$i]%*/}
done
NUMBER_OF_DIRS="${#userarr[@]}"
}
function change_profile {
rm -rf "${HOME}/.arduino15"
rm -rf "${HOME}/.arduinoIDE"
rm -rf "${HOME}/.config/Arduino IDE"
rm -rf "${HOME}/.config/arduino-ide"
rm -rf "${HOME}/Arduino"
ln -sf "${HOME}/ArduinoProfile/${1}/.arduino15" "${HOME}/.arduino15"
ln -sf "${HOME}/ArduinoProfile/${1}/.arduinoIDE" "${HOME}/.arduinoIDE"
ln -sf "${HOME}/ArduinoProfile/${1}/Arduino" "${HOME}/Arduino"
ln -sf "${HOME}/ArduinoProfile/${1}/.config/arduino-ide" "${HOME}/.config/arduino-ide"
ln -sf "${HOME}/ArduinoProfile/${1}/.config/Arduino IDE" "${HOME}/.config/Arduino IDE"
echo Arduino IDE will now use profile "#"$2 "("$1")"
if [ $START_IDE == 1 ]
then
launch_ide
fi
}
function create_new_profile {
if [ $1 == Default ]
then
NEW_PROFILE=$1
else
reset
echo Enter name of new profile or press \"Enter\" to exit:
read NEW_PROFILE
is_it_alphanumeric "$NEW_PROFILE"
fi
if [ ! -d "$HOME/ArduinoProfile/$NEW_PROFILE" ]
then
echo make new dirs "${HOME}/ArduinoProfile/${NEW_PROFILE}" # testing
mkdir -p "${HOME}/ArduinoProfile/${NEW_PROFILE}"
mkdir -p "${HOME}/ArduinoProfile/${NEW_PROFILE}/.arduino15"
mkdir -p "${HOME}/ArduinoProfile/${NEW_PROFILE}/.arduinoIDE"
mkdir -p "${HOME}/ArduinoProfile/${NEW_PROFILE}/.config/Arduino IDE"
mkdir -p "${HOME}/ArduinoProfile/${NEW_PROFILE}/.config/arduino-ide"
mkdir -p "${HOME}/ArduinoProfile/${NEW_PROFILE}/Arduino"
SELECTION=$NEW_PROFILE
reset
echo Profile \"$NEW_PROFILE\" created and ready for use!
echo
echo This is a blank profile and will be configuered
echo the first time Arduino IDE is run...
change_profile $NEW_PROFILE
else
if [ $NEW_PROFILE == Default ]
then
change_profile $NEW_PROFILE
else
echo Profile \"$NEW_PROFILE\" already exist!
sleep 5
exit
fi
fi
}
function delete_profile {
echo Delete Profile $1
yes_or_no
if [ $? == 1 ]
then
change_profile Default
rm -rf $HOME/ArduinoProfile/$1
echo Profile \"$1\" deleted...
fi
}
function is_ide_already_running {
if pidof arduino-ide > /dev/null
then
PIDS=`pidof arduino-ide`
PIDS="${PIDS} `pidof arduino-cli`"
echo Arduino IDE is running!
echo Cannot change profile while IDE is running.
echo Please close Arduino IDE and rerun this script.
echo
echo If you are sure Arduino IDE is not running
echo you have zombie process.
echo
echo " ........."
echo " ;(6) (o);"
echo " \\ \" "/""
echo " ( HHH )"
echo " _) (_"
echo ".' '-' '''---.._"
echo ": . .--''''CCD"
echo ": :_____: C(+,+)D"
echo "/_:___Z_: (-)"
echo "((| |"
echo " . : :"
echo " / | |"
echo " ; / ; /"
echo " L_) [_7"
echo
echo Kill the zombies...
yes_or_no
if [ $? == 1 ]
then
kill ${PIDS}
echo Killing zombies... uugh
echo Please wait...
echo " ___"
sleep 1
echo " ,-'RIP'-,"
sleep 1
echo " | .---. |"
sleep 1
echo " |( # # )_\|/_"
sleep 1
echo " | | # | | /"
sleep 1
echo " | :+++: |/"
sleep 1
echo " | | /"
sleep 1
echo "\"\"\"\"\"\"\"\"\"\"\"\"\"\""
sleep 2
else
echo Leave the zombies be...
sleep 3
exit
fi
fi
}
function yes_or_no {
read -p "Do you want to proceed? (yes/no) " yes_no
case $yes_no in
yes )
echo Yes! Proceeding as directed...;
return 1;;
YES )
echo Yes! Proceeding as directed...;
return 1;;
Yes )
echo Yes! Proceeding as directed...;
return 1;;
yES )
echo Yes! Proceeding as directed...;
return 1;;
y )
echo Yes! Proceeding as directed...;
return 1;;
Y )
echo Yes! Proceeding as directed...;
return 1;;
no )
echo No! Exiting...;
return 0;;
NO )
echo No! Exiting...;
return 0;;
No )
echo No! Exiting...;
return 0;;
nO )
echo No! Exiting...;
return 0;;
n )
echo No! Exiting...;
return 0;;
N )
echo No! Exiting...;
return 0;;
* )
invalid_exit;;
esac
}
function is_it_blank {
# if no input exit
if [ -z "$1" ]
then
echo Blank input! Exiting...
sleep 5
exit
else
return 1
fi
}
function is_it_alphanumeric {
is_it_blank $1
if [[ ! $1 =~ ^['a-zA-Z0-9. ']+$ ]]
then
reset
echo Input contained invalid characters!
echo
echo Upper and lower case letters, numbers,
echo period and space only.
echo
echo Exiting....
sleep 5
exit
fi
}
function is_it_numeric {
is_it_blank $1
if [[ ! $1 =~ ^['0-9']+$ ]]
then
reset
echo Input contained invalid characters!
echo
echo Numbers only.
echo
echo Exiting....
sleep 5
exit
fi
}
function invalid_exit {
echo Invalid entry! Exiting...
sleep 5
exit
}
function set_up_profiles {
echo Not configured to use profiles.
echo
if [ $1 == profile_exist ]
then
echo Existing Arduino IDE configuration found.
echo Continuing will set up profiles and place
echo existing configuration in the \"Default\"
echo profile.
echo
fi
echo Setup profiles:
yes_or_no
YN=$?
if [ $YN == 1 ] && [ $1 == profile_not_exist ] # yes
then
create_new_profile Default
elif [ $YN == 1 ] && [ $1 == profile_exist ]
then
mkdir -p "${HOME}/ArduinoProfile/Default"
mkdir -p "${HOME}/ArduinoProfile/Default/.arduino15"
mkdir -p "${HOME}/ArduinoProfile/Default/.arduinoIDE"
mkdir -p "${HOME}/ArduinoProfile/Default/.config/Arduino IDE"
mkdir -p "${HOME}/ArduinoProfile/Default/.config/arduino-ide"
mkdir -p "${HOME}/ArduinoProfile/Default/Arduino"
mv -f "${HOME}/.arduino15" "${HOM}E/ArduinoProfile/Default"
mv -f "${HOME}/.arduinoIDE" "${HOME}/ArduinoProfile/Default"
mv -f "${HOME}/.config/Arduino IDE" "${HOME}/ArduinoProfile/Default/.config"
mv -f "${HOME}/.config/arduino-ide" "${HOME}/ArduinoProfile/Default/.config"
mv -f "${HOME}/Arduino" "${HOME}/ArduinoProfile/Default"
change_profile Default
fi
}
function launch_ide {
nohup $IDE_PATH$IDE_NAME &
disown
sleep 5
exit
}
function clone_profile {
reset
list_profiles
echo
echo Enter number for profile to be cloned...
read CLONE
is_it_numeric "$CLONE"
SOURCE_NAME=${userarr[$CLONE]%*/}
echo Cloning profile \"$SOURCE_NAME\"
echo
echo Enter name for cloned profile or press \"Enter\" to exit:
read NEW_PROFILE
is_it_alphanumeric "$NEW_PROFILE"
echo
echo Cloning profile \"$SOURCE_NAME\" to new profile \"$NEW_PROFILE\"
YN=0
yes_or_no
YN=$?
if [ $YN == 1 ]
then
if [ -d "${HOME}/ArduinoProfile/${NEW_PROFILE}" ]
then
echo Profile \"$NEW_PROFILE\" already exist!
echo
YN=0
yes_or_no
YN=$?
if [ $YN == 1 ]
then
rm -Rf "${HOME}/ArduinoProfile/${NEW_PROFILE}"
else
Aborting....
sleep 5
fi
fi
cp -Rf "${HOME}/ArduinoProfile/${SOURCE_NAME}" "${HOME}/ArduinoProfile/${NEW_PROFILE}"
echo Profile \"$SOURCE_NAME\" cloned to \"$NEW_PROFILE\"...
fi
}
function get_current_profile {
CURRENT_PROFILE=${LINK#*${HOME}/ArduinoProfile/}
CURRENT_PROFILE=${CURRENT_PROFILE%/Arduino*}
if [ -z "$CURRENT_PROFILE" ]
then
CURRENT_PROFILE="none_in_use"
fi
}
reset
is_ide_already_running
if [ -d "$HOME/Arduino" ]
then
cd ${HOME}/Arduino;
LINK=`pwd -P`
cd $START_UP_DIR
if [ $LINK == ${HOME}/Arduino ]
then
set_up_profiles profile_exist
fi
else
set_up_profiles profile_not_exist
CURRENT_PROFILE="Default"
fi
get_current_profile
cd $HOME/ArduinoProfile
userarr=( */ );
reset
echo NOTE: Only one profile can be run at at time.
echo Running multiple profiles at once will cause data corruption!
echo
echo Multiple instances of the the same profile is no problem.
echo
echo Current profile is \"$CURRENT_PROFILE\"
echo
echo Enter the letter of the desire task and press enter:
echo \"n\" = create a new profile
echo \"c\" = clone an existing profile
echo \"d\" = delete a profile
echo \"s\" = switch to desired profile
read SELECTION
is_it_alphanumeric "$SELECTION"
if [ $SELECTION == "n" ] || [ $SELECTION == "N" ]
then
create_new_profile
elif [ $SELECTION == "d" ] || [ $SELECTION == "D" ]
then
reset
list_profiles
echo Enter number for profile to be deleted...
read TO_BE_DELETED
is_it_numeric "$TO_BE_DELETED"
if [[ $TO_BE_DELETED =~ [0-9] ]]
then
TO_BE_DELETED=$(($TO_BE_DELETED + 0))
if [ $TO_BE_DELETED -gt $NUMBER_OF_DIRS ]
then
invalid_exit
else
delete_profile ${userarr[$TO_BE_DELETED]%*/}
exit
fi
fi
elif [ $SELECTION == "c" ] || [ $SELECTION == "C" ]
then
clone_profile
elif [ $SELECTION == "s" ] || [ $SELECTION == "S" ]
then
reset
echo Current profile is \"$CURRENT_PROFILE\"
echo
echo Available profiles are:
list_profiles
echo Enter number of profile to selected...
read SELECTION
is_it_numeric "$SELECTION"
if [[ $SELECTION =~ [0-9]+$ ]]
then
SELECTION=$(($SELECTION + 0))
if [ $SELECTION -gt $NUMBER_OF_DIRS ]
then
invalid_exit
else
PROFILE=${userarr[$SELECTION]%*/}
change_profile "$PROFILE" "$SELECTION"
exit
fi
else
invalid_exit
fi
else
invalid_exit
fi
Hope this helps someone,
Randy S. Bancroft