DIY Self-Driving Car – Connecting to vehicle CAN

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

Important OBD II Signals:

This (incomplete) table probably applies to most GM cars:

OBD II PinColor used by cable linked aboveDescription
1brownLS-CAN High
4orangeChassis GND
5light blueSignal GND (Used as LS-CAN Low)
6greenHS-CAN High
14green-whiteHS-CAN Low
16red+12V (Always on)
Optional: 3D printed case, since SMD micro-USB sockets are the most fragile thing ever invented

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

-> Part 3: Data Collection – What do we need?

2 Antworten zu “DIY Self-Driving Car – Connecting to vehicle CAN”

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert