2017/09/16

Raspberry PiでCAN通信 その4【Pythonで標準フレームの送信】

前回のC言語で書いたCANの標準フレームの送信を
Pythonで実装します。

PythonでCAN通信するには、python-canを使えばよいようですが、
私の職場はインターネットに接続させてもらえないので、
pipでpython-canをインストールすることができません。

pythonでsocketが使えるので、SocketCANを使って、
CAN通信するプログラムを作ることにしました。

動作環境も前回と同じく、OS:raspbian jessie
仮想CANデバイス(vcan1)でテストしています。

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

"""
    sudo modprobe vcan
    sudo ip link add dev vcan1 type vcan
    sudo ip link set vcan1 up
"""

import sys
import socket
import struct

CAN_MAX_DLEN = 8
CAN_MTU = 16

CAN_NAME = 'vcan1'

def cansend_stdframe(id, data):

    if(CAN_MAX_DLEN < len(data)):
        print('dlc too long.', file=sys.stderr)
        return -1

    s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)

    s.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, None, 0)

    # no loopback
    loopback = 0 # 0 = disabled, 1 = enabled(default)
    s.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK, loopback)

    try:
        s.bind((CAN_NAME,))
    except OSError:
        print('bind error', file=sys.stderr)
        return -4

    dlc = len(data)
    bdata = bytes(data)
    frame = struct.pack('IB3x8s', id, dlc, bdata)

    if(s.send(frame) < CAN_MTU):
        print('send', file=sys.stderr)
        return -5

    s.close()

    return 0

if __name__ == '__main__':
    def main():
        data = [ 0x11, 0x22, 0x33, 0x44 ]
        cansend_stdframe(0x0123, data)

    main()

これで、id=0x123,data=0x11 0x22 0x33 0x44 のデータを1回送信します。



0 件のコメント:

コメントを投稿