Our goal is to connect to the vehicle CAN through the OBD II Connector via USB. Or more precisely, to one of the CAN buses, because there are at least 2 of them. So far the Low-speed CAN bus had all the messages we’re interested in, so that’s what we’ll use.
Here we can read the current steering wheel angle, detect the state of left and right indicators, get the current position of brake pedal and accelerator, detect (and emulate!) steering wheel button presses (incl. cruise control…) and the current vehicle speed.
Hardware used
- CAN <-> USB Adapter, SocketCAN compatible, includes RS232 Connector with screw terminals and microUSB <-> USB-A cable: https://www.amazon.de/USB-CAN-Konvertermodul-f%C3%BCr-Raspberry-Zero/dp/B07Q812QK8/
- J1962 aka. „OBD II Connector“ <-> RS232 Cable: https://www.amazon.de/gp/product/B076P6W5LS/
Important OBD II Signals:
This (incomplete) table probably applies to most GM cars:
OBD II Pin | Color used by cable linked above | Description |
1 | brown | LS-CAN High |
4 | orange | Chassis GND |
5 | light blue | Signal GND (Used as LS-CAN Low) |
6 | green | HS-CAN High |
14 | green-white | HS-CAN Low |
16 | red | +12V (Always on) |
After plugging the cable into the Jetson Nano (or Raspberry Pi or any Linux machine really) we can use SocketCAN and the can-utils to set up the communication and read from and write to the CAN Bus.
How do we know what all those messages and values on the bus mean? We need to reverse engineer them. Do a thing, see what happens on the bus, try to find correlations.
Note that cansniffer
does not support the extended (29-bit) arbitration IDs, so it’s pretty much useless for our purposes. candump
and cansend
work fine.
So we’ll need to write a little script to monitor what’s happening:
import os
import can
import time
import binascii
os.system("sudo ip link set can0 up type can bitrate 33300")
bus = can.interface.Bus('can0', bustype='socketcan')
can_dict = {}
last_out_time = 0;
while True:
message = bus.recv()
can_dict[message.arbitration_id] = message
if (time.time() - last_out_time > 0.2): # seconds
os.system('clear')
os.system('clear')
out = []
for arbitration_id, message in can_dict.items():
outstring = (hex(arbitration_id) + ": " + str(binascii.hexlify(message.data)))
out.append(outstring)
out.append("") # make sure all msgs are printed, even if odd count
i=0
print("Entries: " + str(len(out)))
for idx in range(len(out)-1):
if (idx%2==0):
print(out[idx].ljust(40) + out[idx+1])
last_out_time = time.time()
Here are some of my findings: Astra J LS-CAN Reverse Engineering
2 Antworten zu “DIY Self-Driving Car – Connecting to vehicle CAN”