User Tools

Site Tools


canbus

Using CAN on the RaspberryPi

In this wiki entry some nice-to-knows are noted, when making experiments with a CAN-Bus (WikiPedia: Controller Area Network (CAN)) on a modern RaspberryPi with an MCP2515 CAN-controller (solution like this one e.g.).

Setting up a CAN-bus

Possible common speeds are:

ip link set canX up type can bitrate <speedvalue>

CAN Speed
10 kBit/s
20 kBit/s
50 kBit/s
100 kBit/s
125 kBit/s
250 kBit/s
500 kBit/s
800 kBit/s
1 MBit/s

speedvalue
10000
20000
50000
100000
125000
250000
500000
800000
1000000

So setting up can0 to 125kBit is done by executing:

ip link set can0 up type can bitrate 125000 #125 kBit

If unsure what are the possibilites in total, just add help at the end:

ip link set can0 type can help

Depending on the system, the result might look like this:

Usage: ip link set DEVICE type can
	[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] | 
	[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
 	  phase-seg2 PHASE-SEG2 [ sjw SJW ] ]

	[ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] | 
	[ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1
 	  dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]

	[ loopback { on | off } ]
	[ listen-only { on | off } ]
	[ triple-sampling { on | off } ]
	[ one-shot { on | off } ]
	[ berr-reporting { on | off } ]
	[ fd { on | off } ]

	[ restart-ms TIME-MS ]
	[ restart ]

	Where: BITRATE	:= { 1..1000000 }
		  SAMPLE-POINT	:= { 0.000..0.999 }
		  TQ		:= { NUMBER }
		  PROP-SEG	:= { 1..8 }
		  PHASE-SEG1	:= { 1..8 }
		  PHASE-SEG2	:= { 1..8 }
		  SJW		:= { 1..4 }
		  RESTART-MS	:= { 0 | NUMBER }

So finally a pretty good start-up value for initiating the can controller could be the following one, just to ensure, the device will not be in listen-only mode and therefore prevent it from not sending any acknowledge bits and ensure in addition whenever entering the “bus-off” state, if too many errors occurred on the CAN bus, to try to come back after 100ms again:

sudo ip link set can0 type can bitrate 125000 listen-only off restart-ms 100

Interface can0 can be set on and off by calling:

sudo ifconfig can0 up
sudo ifconfig can0 down

Status of a CAN-interface

Asking for the current status of can0:

ip -d -s link show can0

…which equals…

ip -details -statistics link show can0

Producing the following output:

4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
    link/can  promiscuity 0 
    can state ERROR-ACTIVE restart-ms 0 
	  bitrate 125000 sample-point 0.875 
	  tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
	  mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
	  clock 8000000
	  re-started bus-errors arbit-lost error-warn error-pass bus-off
	  0          0          0          0          0          0         
    RX: bytes  packets  errors  dropped overrun mcast   
    16         2        0       0       0       0      
    TX: bytes  packets  errors  dropped carrier collsns 
    16         2        0       0       0       0      

Interesting is the row, where the state of the bus is written:

can state ERROR-ACTIVE restart-ms 0

The current state of the CAN controller: “ERROR-ACTIVE”, “ERROR-WARNING”, “ERROR-PASSIVE”, “BUS-OFF” or “STOPPED”.

There are some further details and explanations, which are very interesting to know, these can be read here: https://www.kernel.org/doc/Documentation/networking/can.txt

Listening on the bus

By using candump out of the utility suite (sudo apt-get install can-utils), the device can listen on the connected bus and dump anything to the console. By adding some more parameters and listening on any device (any = can0, can1, canX, …), the output is quite helpful:

candump -aedxc -t A any

 (2016-03-21 17:11:07.526260)  can0  RX - -  42A   [8]  43 41 4E 42 65 72 72 79   'CANBerry'
 (2016-03-21 17:11:30.767062)  can0  RX - -  42A   [8]  43 41 4E 42 65 72 72 79   'CANBerry'
 (2016-03-21 17:13:21.067450)  can0  RX - -  42C   [7]  41 6E 64 72 65 61 73      'Andreas'
 (2016-03-21 17:14:15.029558)  can0  RX - -  23F   [8]  4C 69 6E 6B 54 65 63 68   'LinkTech'
 (2016-03-21 17:17:45.646466)  can0  RX - -  123ABCDF   [8]  4C 69 6E 6B 54 65 63 68   'LinkTech'
 (2016-03-21 17:18:36.728044)  can0  RX - -  1FABCDEF   [7]  41 6E 64 72 65 61 73      'Andreas'

Output includes both 11-Bit-identifier, known as “Base frame format” (CAN 2.0A), and extend 29-Bit-identifier, known as “Extended frame format” (CAN 2.0B).

Generating Test-CAN messages

For testing it's quite often useful to have some testdata going on the bus. Using cangen on the interface generates just “something”, the default call would be cangen -v can0, where the optional '-v' makes it verbose to immediately see the generated messages.

Message generation can be modified with various params, by executing cangen -g 1000 -e -v can0 there is only every second a message generated and sent, consisting only out of 29-bit extended identifiers with random payload sent to can0:

  can0  1C25738A#C4.CE.65
  can0  0FB43CE6#92.73.C2.12
  can0  1EFA1FE0#01.11.05.6B
  can0  0227596F#78.3F.76.3D.0C.1A
  can0  154C5477#DB
  can0  129B3B9A#47.09.E4.73.85.A7.8E.0A
  can0  1F56EB20#83.F1.C4.2E.50.63
  can0  0F56DE7C#27
  can0  1930ECA5#25.2C.9D.7B.8B.29.E5.68
  can0  10DD12CF#3B.AA.70.2A.AF.32.D7
  can0  17907FFC#2C.33.A0.3C.6B.D9.B7.79
canbus.txt · Last modified: 21.03.2016 22:34 by andreas