Skip to content

Instantly share code, notes, and snippets.

@hdoverobinson
Last active February 1, 2024 12:48
Show Gist options
  • Star 30 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save hdoverobinson/42732da4c5b50d031f60c1fae39f0720 to your computer and use it in GitHub Desktop.
Save hdoverobinson/42732da4c5b50d031f60c1fae39f0720 to your computer and use it in GitHub Desktop.
Configure u-blox GPS/GNSS modules with Bash
#!/bin/bash
###AUTHOR###
#Harry Dove-Robinson 5/8/2017
#harry@doverobinson.me
#https://gist.github.com/hdoverobinson
#https://github.com/hdoverobinson
###USAGE###
#This is a script used to configure u-blox GPS/GNSS modules from a text file generated by u-center.
#This allows for the possibility of simple in-situ u-blox receiver configuration on a Linux host. (u-center is Windows-only software.)
#It has been tested on the NEO-M8T and EVK-M8T modules with u-center 8.24 and should work with any GPS receiver on the u-blox 8/M8 firmware.
#The script takes its first argument as the path to a GPS device file and the second argument as the path to a .txt file used to configure the GPS.
#Example: ./ubxconfig.sh /dev/ttyACM0 NEO-M8T_10HZ_GNSS_SBAS.txt
#The receiver is first reset to factory defaults before it is configured from the text file. The configuration is then saved to all available flash.
#The configuration text file used should be one that is outputted from u-center (Tools -> GNSS Configuration...).
#The packages "dos2unix" and "bc" are required for this script to run.
###NOTES###
#The script will not run unless there is an exact match between the MON-VER string of the text file and the MON-VER output of the GPS receiver.
#The MON-VER response is the longest parsed by the script, and it may take a few tries before the full message is able to be parsed.
#All other messages are sent up to 10 times before being permanently declared "NOT ACKNOWLEDGED". Note that this does not mean that it was explicitly rejected.
#If "ERROR - MESSAGE NOT ACKNOWLEDGED" is shown after 10 retries, then there is likely a problem with the contents of the configuration file or communication with the GPS receiver.
#It is expected behavior for some UBX messages to be rejected by the receiver. Try running the configuration file within u-center to see which ones.
#The STTY variable holds the stty configuration message that sets up the serial line for this script. It assumes a USB device able to run at 921600 baud.
#Other stty configuration messages can be loaded in with the output of "stty -F /dev/GPS0 -g" where "GPS0" is the character device file of the GPS.
#Currently this script cannot handle changes in the baudrate when used over an analog serial line. The GPS receiver should be connected to the host via USB.
export GPS=$1
export CONFIG=$2
export STTY="406:0:18b7:8a30:3:1c:7f:8:4:2:64:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0"
export RETRY_COUNT="10"
export TIMEOUT=".25s"
export UBX_ACK_ACK="b5620501"
export UBX_ACK_NAK="b5620500"
export UBX_PREAMBLE="B5 62"
export UBX_MON_VER_POLL="0A 04 00 00"
export UBX_CFG_CFG_REVERTDEFAULT="06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 17"
export UBX_CFG_CFG_SAVE="06 09 0D 00 00 00 00 00 FF FF 00 00 00 00 00 00 17"
#counts number of sent messages up to the set number of retries
#anything sent into the counter should fail with exit code 1 and pass with exit code 0
send_counter ()
{
SENT_COUNTER=0
until [ $SENT_COUNTER == $RETRY_COUNT ] && echo "$(tput setaf 1)ERROR - MESSAGE NOT ACKNOWLEDGED$(tput sgr0)" && let ERROR_COUNTER=ERROR_COUNTER+1 || "$@"
do
let SENT_COUNTER=SENT_COUNTER+1
echo "NOT ACKNOWLEDGED"
if [ $SENT_COUNTER -ge 1 ] && [ $SENT_COUNTER -le $(expr $RETRY_COUNT - 1) ]
then
echo "RETRYING"
fi
done
}
#these needed to be functions so that ver_check can loop multiple times if it fails
file_mon_ver ()
{
#pulls MON-VER string from configuration file, finds only the hex and reformats for comparison
grep "MON-VER" $1 | sed 's/^.*-\s//' | xxd -r -p | xxd -p | tr -d '\n'
}
dev_mon_ver ()
{
#sends the MON-VER polling message, has larger timeout and set byte range because we expect a long response
echo "`ubx_chksum "$UBX_MON_VER_POLL"`" | xxd -r -p > $GPS && timeout 5s cat $GPS | xxd -p -l50000 | grep -m1 -a -A 10 "b5620a04" | tr -d '\n'
}
ver_check ()
{
if [[ `dev_mon_ver` =~ .*`file_mon_ver $1`.* ]]
then
echo "Version match!"
else
return 1
fi
}
send_ubx ()
{
echo "Sending UBX message: "$@""
#timeout is allowed in case no response is received
ubx_response=`timeout $TIMEOUT cat $GPS | xxd -p | grep -m1 -a -e "$UBX_ACK_ACK" -e "$UBX_ACK_NAK" & echo $2 | xxd -r -p > $GPS`
if [[ $ubx_response == *$UBX_ACK_ACK* ]]
then
echo "$(tput setaf 2)ACKNOWLEDGED$(tput sgr0)" && let ACK_COUNTER=ACK_COUNTER+1
elif [[ $ubx_response == *$UBX_ACK_NAK* ]]
then
echo "$(tput setaf 3)REJECTED$(tput sgr0)" && let NAK_COUNTER=NAK_COUNTER+1
else
return 1
fi
}
ubx_chksum ()
#############################################################################################################################
###Fletcher checksum calculator adapted from: http://www.aeronetworks.ca/2014/07/fletcher-checksum-calculator-in-bash.html###
#############################################################################################################################
{
SUM=0
FLETCHER=0
j=0
printf "$UBX_PREAMBLE "
for i in $1
do
j=$(echo "ibase=16;$i" | bc)
printf "%02X " "$j"
SUM=$(echo "$SUM + $j" | bc)
SUM=$(echo "$SUM%256" | bc)
FLETCHER=$(echo "$FLETCHER + $SUM" | bc)
FLETCHER=$(echo "$FLETCHER%256" | bc)
done
printf "%02X " "$SUM"
printf "%02X\n" "$FLETCHER"
}
main ()
{
#validate the GPS device and .txt file
if [[ -c $GPS ]] && [[ -f $CONFIG && -s $CONFIG && $CONFIG == *.txt ]]
then
#prepare serial port
stty -F $GPS $STTY
#remove windows carriage returns from config file
dos2unix $CONFIG
#version compatibility loop
echo "Checking compatibility..."
until ver_check $1
do
echo "Version mismatch! Checking again..."
done
ACK_COUNTER=0
NAK_COUNTER=0
ERROR_COUNTER=0
#configuration start
echo "Configuring u-blox GPS at $GPS from $1..."
echo "Resetting to factory defaults..."
send_counter send_ubx "UBX-CFG-CFG-REVERTDEFAULT" "$(ubx_chksum "$UBX_CFG_CFG_REVERTDEFAULT")"
echo "Restoring configuration from file..."
#loop through config file after MON-VER line and pass through ubx_chksum, send_ubx, and send_counter
while read -r line
do
send_counter send_ubx "`echo $line | sed 's/\s.*$//'`" "`ubx_chksum "$(echo $line | sed 's/^.*-\s//')"`"
done < <(tail -n+2 $1)
echo "Saving configuration to flash..."
send_counter send_ubx "UBX-CFG-CFG-SAVE" "$(ubx_chksum "$UBX_CFG_CFG_SAVE")"
echo -en "\n"
echo "Done!"
#print message stats
TOTAL=$(($ACK_COUNTER+$NAK_COUNTER+$ERROR_COUNTER))
echo -en "\n"
echo "----------------------------------------"
echo -en "\n"
echo "UBX MESSAGE STATISTICS:"
echo "$(tput setaf 2)ACKNOWLEDGED:$(tput sgr0) $ACK_COUNTER ($(echo "scale=2; $ACK_COUNTER / $TOTAL * 100" | bc | sed s/\\.[0-9]\\+//)%)"
echo "$(tput setaf 3)REJECTED:$(tput sgr0) $NAK_COUNTER ($(echo "scale=2; $NAK_COUNTER / $TOTAL * 100" | bc | sed s/\\.[0-9]\\+//)%)"
echo "$(tput setaf 1)ERRORS:$(tput sgr0) $ERROR_COUNTER ($(echo "scale=2; $ERROR_COUNTER / $TOTAL * 100" | bc | sed s/\\.[0-9]\\+//)%)"
echo "TOTAL SENT: $TOTAL"
echo -en "\n"
else
echo "Provide the GPS device as first argument and .txt file as second!"
return 1
fi
}
#check for dos2unix
if ! command -v dos2unix > /dev/null 2>&1
then
echo "Please install dos2unix!"
exit 2
fi
#check for bc
if ! command -v bc > /dev/null 2>&1
then
echo "Please install bc!"
exit 2
fi
#run
main $CONFIG
exit $ERROR_COUNTER
@Avamander
Copy link

Awesome, thanks!

@Avamander
Copy link

This might be the only proper method of configuring a ublox GPS receiver on Linux.

@maximevince
Copy link

It's nice, because it's a script. However uBlox' u-center on Wine works really well, too.

@mr337
Copy link

mr337 commented Feb 3, 2022

Holy smokes, this is awesome. Works like a champ!

@marcuzz0
Copy link

Hi hdoverobinson,
I downloaded and launched the script with this command:
./ubxconfig /dev/ttyACM0 ../conf/new_U1_nmea.txt

but it returns this message:

dos2unix: converting file ../conf/new_U1_nmea.txt to Unix format...
Checking compatibility...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...

do you have any idea?

@mr337
Copy link

mr337 commented Mar 23, 2022

The Version mismatch is a check between the device and the configuration on file. The check is https://gist.github.com/hdoverobinson/42732da4c5b50d031f60c1fae39f0720#file-ubxconfig-sh-L71.

Generally you don't want to upload config older version may not have a different setting etc. If you feel brave you can always comment out those lines and see what happens. Worst case you may need to reset the receiver to to default it to factory settings.

Hi hdoverobinson, I downloaded and launched the script with this command: ./ubxconfig /dev/ttyACM0 ../conf/new_U1_nmea.txt

but it returns this message:

dos2unix: converting file ../conf/new_U1_nmea.txt to Unix format... Checking compatibility... Version mismatch! Checking again... Version mismatch! Checking again... Version mismatch! Checking again... Version mismatch! Checking again...

do you have any idea?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment