CAN通信

PythonでCANを使う


Raspberry PiとOrangePi PCでCAN通信ができるようになりました。(インストールはこちら)
そこで、Pythonを使ってCAN通信を行う方法を紹介します。
こちらにサンプルが公開 されています。

以下のコマンドで受信処理を行います。
今回「2018-11-13-raspbian-stretch-lite」をクリーン・インストールしましたが、
python3はいつの間にか標準でインストールされていました。
$ python3 ./python_socketcan_example.py listen can0

以下のコマンドで送信処理を行いす。
$ python3 ./python_socketcan_example.py send can0 123 7766554433221100
$ python3 ./python_socketcan_example.py send can0 321 0011223344556677

受信側の端末に受信したデータが表示されます。
$ python3 ./python_socketcan_example.py listen can0
Listening on can0
can0 123#776655443322110
can0 321#011223344556677

CAN拡張フレームを送ると落ちます。
$ python3 ./python_socketcan_example.py send -e can0 123 7766554433221100
Traceback (most recent call last):
  File "./python_socketcan_example.py", line 132, in <module>
    main()
  File "./python_socketcan_example.py", line 129, in main
    args.func(args)
  File "./python_socketcan_example.py", line 89, in send_cmd
    s.send(cob_id, generate_bytes(args.body), socket.CAN_EFF_FLAG if args.extended_id else 0)
  File "./python_socketcan_example.py", line 46, in send
    can_pkt = struct.pack(self.FORMAT, cob_id, len(data), data)
struct.error: argument out of range



こちらにpython-canライブ ラリが公開されています。
インストールは以下の手順です。
pipがインストールされているときは、pipを削除しておかないと正しくインストールできません。
$ sudo apt install python3-pip

$ python3 -m pip3 --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.5)

$ python3 -m pip3 install python-can
Collecting python-can
  Downloading https://files.pythonhosted.org/packages/3f/c6/bd482201ec89d1107d1e12311c3e0023440e11ab1218c568e8dfd50b098e/python_can-3.1.1-py2.py3-none-any.whl (149kB)
    100% |????????????????????????????????| 153kB 284kB/s
Collecting wrapt~=1.10 (from python-can)
  Downloading https://www.piwheels.org/simple/wrapt/wrapt-1.11.1-cp35-cp35m-linux_armv6l.whl (65kB)
    100% |????????????????????????????????| 71kB 110kB/s
Installing collected packages: wrapt, python-can
Successfully installed python-can-3.1.1 wrapt-1.11.1

送信スクリプト
CAN標準フレームもCAN拡張フレームも送信することができます。
python2では動きません。
#!/usr/bin/python3
import can
import time

bus = can.interface.Bus(channel='can0', bustype='socketcan_native')

try:
    while True:
        #CAN 2.0A
        msg= can.Message(arbitration_id=0x7de, data=[0, 25, 0, 1, 3, 1, 4, 1], extended_id=False)
        bus.send(msg)
        time.sleep(1)

        #CAN 2.0B
        msg= can.Message(arbitration_id=0x7de, data=[0, 25, 0, 1, 3, 1, 4, 1], extended_id=True)
        bus.send(msg)
        time.sleep(1)
except KeyboardInterrupt:
    print('!!FINISH!!')

受信スクリプト
CAN標準フレームもCAN拡張フレームも受信することができます。
python2では動きません。
#!/usr/bin/python3
import can

bus = can.interface.Bus(channel='can0', bustype='socketcan_native')

for msg in bus:
    print("{:x}: {}".format(msg.arbitration_id, msg.data))


続く...