Playing with SocketCan using can-utils

Introduction

When setting up and testing any new system some of the most common things I tend to want to do are:

  • view raw output
  • transmit raw input
  • log the output
  • re-play the logs

SocketCAN is no exception and the tools included with can-utils does just this. (Plus more.)

Installing can-utils

Debian based systems, I can’t speak for other versions of Linux, this is easy just issue the following command

$ apt-get install can-utils

For those who prefer to install directly from source, instructions can be found on elinux.org/Can-utils and the source is at github.com/linux-can/can-utils

Other useful information can be found at elinux.org/CAN_Bus and elinux.org/Bringing_CAN_interface_up.

Can-utils is a veritable Swiss Army Knife of tools and probably has a tool to get stones out of horses hoofs  somewhere. I’ll go over the ones I have found most useful.

candump

Candump probably the most useful of all the tools as it will dump information from the CANbus to stdout.

$ candump can0

Will then listen on the interface can0 and dump any CAN frames it sees to the terminal window. (note: ctrl+c will stop candump)

 can0 1DFF6773 [8] 00 0B 3B 9F 03 02 04 5A
 can0 1DFF6773 [6] 01 A1 12 19 09 09
 can0 0DF010A0 [8] FF FF A9 3F 18 A8 C6 28
 can0 15FD0773 [8] 00 C0 53 7A FF 7F FF FF
 can0 09F503A0 [8] FF FF FF 60 01 FF FF FF
 can0 11F80E2B [8] 00 1B 01 E0 53 7F 10 3F

Candump can also be set to log to file with the addition of a -l argument

$ candump -l can0
Disabled standard output while logging.
Enabling Logfile 'candump-2017-05-19_112441.log'

below is an example of what would be recorded in the log file

(1495188791.945986) can0 0DF805A0#040000000010FC0A
(1495188791.945993) can0 0DF805A0#055000FF7FFFFFFF
(1495188791.946000) can0 0DF805A0#067F00
(1495188791.946015) can0 0DF809A0#A93FFCEDC428B400
(1495188791.946029) can0 09F50373#004E01FFFF00FFFF

 

cansend

Cansend is used to transmit individual frames directly onto the CANbus.

$ cansend can0 5A1#11.22.33.44.55.66.77.88

Gives us the following candump output.

$ candump can0
 can0 5A1 [8] 11 22 33 44 55 66 77 88

canplayer

By default canplayer will replay a logfile back onto the interface recorded in the log file.

$ canplayer -I candump-2017-05-19_101301.log

Using the log file below

$ cat candump-2017-05-19_101301.log
(1495188791.945939) vcan1 0DF805A0#002B87A93FFCEDC4
(1495188791.945961) vcan1 0DF805A0#012800586711CFDB
(1495188791.945970) vcan1 0DF805A0#02490800F41547C4
(1495188791.945979) vcan1 0DF805A0#03D26E0380662300

Will produce

$ candump vcan1
 vcan1 0DF805A0 [8] 00 2B 87 A9 3F FC ED C4
 vcan1 0DF805A0 [8] 01 28 00 58 67 11 CF DB
 vcan1 0DF805A0 [8] 02 49 08 00 F4 15 47 C4
 vcan1 0DF805A0 [8] 03 D2 6E 03 80 66 23 00

Note – in this instance we are using the virtual can interface vcan1

It is possible to tell canplayer to play messages recorded on one interface back on another interface.

 $ canplayer -I candump-2017-05-19_101301.log can0=vcan1

will play messages recorded on vcan1 on can0 interface to produce

$ candump can0
 can0 0DF805A0 [8] 00 2B 87 A9 3F FC ED C4
 can0 0DF805A0 [8] 01 28 00 58 67 11 CF DB
 can0 0DF805A0 [8] 02 49 08 00 F4 15 47 C4
 can0 0DF805A0 [8] 03 D2 6E 03 80 66 23 00

Conclusion

I hope that this brief introduction to can-utils is useful to readers, I have only scratched the surface of what they can do. I strongly recommend using the -h argument with each of the tools to discover the full extent of what each tool can do.

 

 

Advertisements

Connecting socket CAN adapter to SignalK

Socket can introduction

What is SocketCan?

Put simply SocketCan is a set of CAN drivers and networking stack that enables can bus appear as a network interfaces on a Linux computer.

For a better and more detailed explanation see wikipedia article

Another feature of SocketCAN is the virtual can interface. This acts like the Ethernet loop-back interface and can be very useful for replaying log files without transmitting them on a physical CAN bus.

Note: The scripts and techniques discussed in this document have only been tested on:

  • Raspberry pi 3 B (Revision: a02082)
  • Raspbian jessy (2017-03-02)
  • PiCAN2 (manufacture link)
    • PiCAN2 Duo should work as the second can interface is just a duplicate of the fist using a different SPI CS pin

Setting up the PiCAN2

Make the following changes to the /boot/config.txt file on the Raspberry pi
( sudo nano /boot/config.txt )

enable the spi bus by changing the following line

#dtparam=spi=on to dtparam=spi=on

append the follwing lines to the end of the config.txt file

dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=mcp2515-can1,oscillator=16000000,interrupt=24 #this line is only needed for the PiCAN2 Duo
dtoverlay=spi-bcm2835-overlay

Setting up the SocketCAN interfaces

Append the follwing lines to the /etc/network/interfaces file
(sudo nano /etc/network/interfaces)

#physical can interfaces
allow-hotplug can0
iface can0 can static
bitrate 250000
down /sbin/ip link set $IFACE down
up /sbin/ifconfig $IFACE txqueuelen 10000

Virtual CAN interface

Append the following lines to the /etc/network/interfaces file
(sudo nano /etc/network/interfaces)

 #virtual can interfaces
 auto vcan0
 iface vcan0 inet manual
 pre-up /sbin/ip link add dev $IFACE type vcan
 up /sbin/ifconfig $IFACE up

 

If this has worked correctly (a reboot may be needed) in addition to the regular Ethernet interfaces, ifconfig should display the following

pi@raspberrypi:~ $ ifconfig
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

vcan0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

Install the CANboat project

step 2 is optional but will keep your home directory a little tidier
setp 3 is needed for the raspberry pi 3 but may not be needed on other Linux distros
1. get the latest package repository catalogue with the command

 sudo apt-get update

2. create a folder to hold the CANboat project

 mkdir ~/canboat
 cd ~/canboat

3. install required module for the compiler with the command

 sudo apt-get install xsltproc

4. clone and build CANboat

 git clone git://github.com/canboat/canboat
 cd canboat
 sudo make
 sudo make install

CANboat should now be good to go.

Testing the interface

A warning about timing issues

the NMEA2000 CAN bus normally runs at 250Kb/s  so if you just issue the following command,

cat canlog.log | socketcan-writer vcan0

then (with the hardware used here) CANboat will only receive/decode approx 25% of the messages transmitted, if you slow the rate of transmission down it solves the problem.

Python script for replaying a log and slowing transmission

The following is a realy simple python script will read a log file (fName) and write each line to stdout with a 0.025 second delay between lines.

to create the script do the following in a suitable folder on your system

 touch logReplay.py
 chmod 775 logReplay.py
 (note you will want to chose apropreate permissions)
 nano logReplay.py

copy the following into the file

#!/usr/bin/env python
from time import sleep
from sys import *
#This is a simple script to re-play a logfile to stdout with a delay between each line

fName = './aava-n2k.data'
delaySec = 0.025
f = open( fName, 'r')
for ln in f:
stdout.write(ln)
sleep(delaySec)

Transmitting messages to socket can interface

For testing purposes we are using the vcan0 interface if you wish to transmit on the physical bus use can0 / can1 instead
logPlay.py | SocketCAN-writer vcan0

Expected errors

Some serial interfaces (Actisense NGT-1) add proprietary messages that are in addition to what was transmitted on the CAN bus, these are distinguished by having a PGN > 16384 (0x4000). If these are sent to CANboat’s socketcan-writer it will throw and error skip the message.

ERROR 2017-05-17T15:35:37.332Z [socketcan-writer] Invalid PGN, too big (0x400f2). Skipping.

Logging received messages

issue the following command will pipe the output from candump to a logfile

candump vcan0 | .fileNameOfLog.File

Setting signalK to listen to a socket can adapter

The json sample below should act as a templete signalK pipedProvder, repalce vcan0 with the aproprate socket can interface.
Restart the signalK server, then when you replay a log file or messages appear on the CAN bus and they should apear in signalK

{
  "id": "n2k-vcan0",
  "pipeElements": [
    {
      "type": "providers/execute",
      "options": {
        "command": "candump vcan0 | candump2analyzer "
      }
    },
    {
      "type": "providers/liner",
      "options": {
        "rawlogging": true,
        "logdir": "logs",
        "discriminator": "2"
      }
    },
    {
      "type": "providers/n2kAnalyzer"
    },
    {
      "type": "providers/n2k-signalk"
    }
  ]
}

Welcome to Dayba Labs

Welcome to the Dayba Labs blog. Here we hope to publish some of the ideas and side projects that we get up-to in our spare time at Dayba.

This will range from internet of things hardware projects using Arduino and Raspberry Pi through to web programming tips and ideas.

To kick off with we have a short series on Yacht navigation systems, CANbus and using SignalK to display and distribute the data that is available on modern leisure craft.