Posted by: yegorich | May 22, 2012

SocketCAN Support in Python

Since version 3.3 Python provides support for SocketCAN. You can specify AF_CAN protocol family as you do in C. Below you’ll find slightly modified example provided in the original SocketCAN patch.

To get started just copy the code into example.py and start it as follows provided your CAN interface is can0:

python3 example.py can0

Use build_can_frame() and dissect_can_frame() to build/dissect CAN frames. Interface management like bitrate settings or getting statistics will be made as usual via iproute2 utility.

import socket
import struct
import sys

# CAN frame packing/unpacking (see `struct can_frame` in <linux/can.h>)
can_frame_fmt = "=IB3x8s"

def build_can_frame(can_id, data):
        can_dlc = len(data)
        data = data.ljust(8, b'\x00')
        return struct.pack(can_frame_fmt, can_id, can_dlc, data)

def dissect_can_frame(frame):
        can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
        return (can_id, can_dlc, data[:can_dlc])

if len(sys.argv) != 2:
        print('Provide CAN device name (can0, slcan0 etc.)')
        sys.exit(0)

# create a raw socket and bind it to the given CAN interface
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind((sys.argv[1],))

while True:
        cf, addr = s.recvfrom(16)

        print('Received: can_id=%x, can_dlc=%x, data=%s' % dissect_can_frame(cf))

        try:
                s.send(cf)
        except socket.error:
                print('Error sending CAN frame')

        try:
                s.send(build_can_frame(0x01, b'\x01\x02\x03'))
        except socket.error:
                print('Error sending CAN frame')

As alternative you can use python-can module, that can handle both Python 2 and 3 and you can also use it under MS Windows OS.

Advertisements

Responses

  1. dissect_can_frame doesn’t work.
    In case of this telegram: 603_4000100000000000
    I get (603h=1539)

    print(dissect_can_frame(cf))

    (1539, 8, b’\x00\x10\x00\x00\x00\x00\x00′)

    Python 3.3

  2. Try using this instead:
    can_id, can_dlc, data = dissect_can_frame(cf)
    print(‘Received: can_id=%x, can_dlc=%x, data=%s’ % (can_id, can_dlc, ‘:’.join(format(x, ’02x’) for x in data)))
    Python 3.3

  3. When i run the script on my beagle bone i get this error:
    Traceback (most recent call last):
    File “Can.py”, line 22, in
    s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
    AttributeError: ‘module’ object has no attribute ‘AF_CAN’

    • What Python version are you using? It must be Python 3.3 oh newer.

      • oh, I do in fact have 2.7.3 .
        I’m trying to look at ways to upgrade to 3.3. There doesnt seem like there is a python3 package available for beaglebones default OS, Angstrom. Is there a preferred method to do it on the Angstrom distribution?

        Should I instead load Ubuntu onto the board and download python from there?

        Thank you!

      • Take a look at Buildroot (http://buildroot.net/downloads/manual/manual.html).

        This embedded Linux distribution provides both Python versions and it even has a defconfig for BeagleBone. Just clone it’s git repo and invoke “make help”. You’ll see beaglebone_defconfig among others.

  4. Hello,
    I want to run this script on an Apache webserver. Is there any possibility? Apache does not like thw while loop.

    Thanks
    Michael

    • Why do you need Apache? Take a look at and it’s support for WebSocket. With WebSocket you can create a thread, that would take care of incoming CAN frames and push them to the browser.

  5. i tried to run the script on my raspberry pi 2 with pyton 3.4.2 but i got the error message ‘module’ object has no Attribute ‘AF_CAN’

    • Are you sure you really use Python3? This error message is typical for Python2. If you invoke the example like this you won’t have this error: python3 example.py can0. I’ll correct my blog entry.

  6. now i cant open file and it says that there is no sch file or Directory but its there when i look in the directory

  7. ok sry missspelled it f** thx for your help


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: