Skip to content

Instantly share code, notes, and snippets.

@BretStateham
Last active August 22, 2023 04:17
Show Gist options
  • Save BretStateham/304cc565215dc8c82feffb8782574488 to your computer and use it in GitHub Desktop.
Save BretStateham/304cc565215dc8c82feffb8782574488 to your computer and use it in GitHub Desktop.
Dump OBDII Info via cansend and candump
# --------- SCRIPT BEGIN ----------
# By Bret Stateham
# This script assumes
# - You are running on a linux machine
# - You have the can-utils installed and working. See:
# - https://github.com/linux-can/can-utils
# - https://www.kernel.org/doc/Documentation/networking/can.txt
# - You have a can device attached and configured as can0 (you can change the targetbus variable to match if otherwise)
# - The can device is attached to your running target vehicle
# This script uses bc - An arbitrary precision calculator language. You may need to install it with "sudo apt-get install -y bc"
targetbus="can0"
zero_pad() {
# stolen from: https://unix.stackexchange.com/a/145659
# zero_pad <string> <length>
[ ${#1} -lt $2 ] && printf "%0$(($2-${#1}))d" ''
printf "%s\n" "$1"
}
echo ""
echo "Requesting the vehicle's VIN"
echo ""
# start candump in the background and capture it's process id
candump $targetbus,7DF:7FF,7E0:7E0 > vin.log &
vindumpprocid=$!
# Request the VIN, and send the flow control message to get all frames
cansend $targetbus 7df#0209020000000000
sleep 0.01
cansend $targetbus 7e0#3000000000000000
sleep 1
# kill the vin candump
kill -s SIGINT $vindumpprocid
echo ""
echo "Requesting all Service 01 PIDS"
echo ""
# start candump in the background and capture it's process id
candump $targetbus,7DF:7FF,7E0:7E0 > pids.log &
allpiddumpprocid=$!
# Valid PID hex values are 00 to E0 or in decimal 0 to 224
for pid in {0..224}
do
pidhex=$(echo "obase=16;$pid" | bc)
pidhexstr=$(zero_pad "$pidhex" 2)
#echo $pidhexstr
canprefix="7DF#0201"
cansuffix="0000000000"
canpayload="$canprefix$pidhexstr$cansuffix"
echo $canpayload
cansend $targetbus $canpayload
# Delay for a bit to keep from flooding the bus
sleep 0.05
done
# kill the candump
kill -s SIGINT $allpiddumpprocid
echo ""
echo "Requesting Service 01 PIDS that return multi-frame messages"
echo ""
# ok, now loop through the pids.log file created above, and look
# Lines that have a data payload that starts with #1 indicate the
# first frame in a multi-frame sequence. We need to capture the ID
# of the sender of that message (the hex value to the left of the #)
# as well as the PID (the 5-6 digits to the right of the #) that was
# initially requested.
# We then need to requery the PID (on 7DF) and then after a short
# (like .02 second) delay, follow up with the 7EX#30000000000000 flow
# control message where 7EX is the hex id minus eight we calculated above
# Example line:
# can0 7E8 [8] 10 09 41 68 03 4A 52 00
# start candump in the background and capture the extended messages
candump $targetbus,7DF:7FF,7E0:7E0 > pids_extended.log &
extpiddumpprocid=$!
while read line; do
ln=$(echo $line | tr -s ' ')
firstbyte=$(echo $ln | cut -d' ' -f4)
if [ "$firstbyte" == "10" ]
then
echo $line
sourceid=$(echo $ln | cut -d' ' -f2)
targetpid=$(echo $ln | cut -d' ' -f7)
flowid=$(echo "obase=16;ibase=16;$sourceid-008" | bc)
querypre="cansend $targetbus 7DF#0201"
querypost='0000000000'
querycmd=$querypre$targetpid$querypost
flowpre="cansend $targetbus "
flowpost='#3000000000000000'
flowcmd=$flowpre$flowid$flowpost
echo $querycmd
eval $querycmd
sleep 0.01
echo $flowcmd
eval $flowcmd
fi
done < pids.log
# kill the candump
kill -s SIGINT $extpiddumpprocid
echo ""
echo "Requesting the vehicle's DTCs (Diagnostic Trouble Codes)"
echo ""
# start candump in the background and capture it's process id
candump $targetbus,7DF:7FF,7E0:7E0 > dtcs.log &
dtcdumpprocid=$!
# Request the DTCs, and send the 0x7E0 flow control message to get all frames
# from 0x7E8
cansend $targetbus 7df#0103000000000000
sleep 0.01
cansend $targetbus 7e0#3000000000000000
sleep 1
# kill the vin candump
kill -s SIGINT $dtcdumpprocid
#combine the two logs into a single file
rm obdii_info.txt 2> /dev/null
echo "########## VEHICLE VIN ##########" >> obdii_info.txt
cat vin.log >> obdii_info.txt
echo "########## ALL PID REQUESTS ##########" >> obdii_info.txt
cat pids.log >> obdii_info.txt
echo "########## MULTI-FRAME PID REQUESTS ##########" >> obdii_info.txt
cat pids_extended.log >> obdii_info.txt
echo "########## VEHICLE DTCs ##########" >> obdii_info.txt
cat dtcs.log >> obdii_info.txt
rm vin.log pids.log pids_extended.log dtcs.log
echo ""
echo "All pid messages (including multi-frame messages) have been logged to:"
echo ""
echo "obdii_info.txt"
echo ""
cat obdii_info.txt
# --------- SCRIPT END ----------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment