ラズパイ5 +Python+CANopenでモータを回す ⑦ CANバス信号を見る<前編>canreset.py candump0.py
CANopenは、物理層にCANバス・ネットワークを利用しています。CANバスを流れる信号は、ツールを使うと簡単にとらえることができます。ここでは、複数の方法を説明します。
●<その1>オシロスコープで信号を見る
CAN_LとCAN_Hにプローブを当てています。
二つの信号は極性が異なっているだけで、同じデータです。
ID(CAN-ID)、ここでは0x58Cですが、通信オブジェクト識別子(COB-ID)と呼ばれることもあり、11ビットの内MSBから4ビットをファンクション・コード、残り7ビットをデバイスのNode-IDで構成されています。ここでつながっているモータのNode-IDは12(0x0c)を設定しています。
ファンクション・コードで代表的なNMTは0000、PDOは0011~1010、送信のSDOは1011、受信のSDOは1100です。
したがって、0x58Cは、SDO(送信)のデータ・フレームだとわかります。
データ・フレーム(一連のデータの塊)のデータ・フィールドは0~8バイトで構成されていますが、ほとんどが8バイトです。
データ・フィールドの最初の1バイトは0x40と0x4Bが見つかります。0x40は、読み込みのアップロード要求です。0x4Bは、アップロード応答のコマンド指定子CSで、
CS(0x4x) | Index LB | Index HB | Subindex | LLB (D0) | LHB (D1) | HLB (D2) | HHB (D3) |
- CS = 0x4F;D0に1データ・バイト
- CS = 0x4B;D0~D1に2データ・バイト
- CS = 0x47;D0~D2に3データ・バイト
- CS = 0x43;D0~D3に4データ・バイト
0x4BはD0~D1に2データ・バイトということになります。
Index LBとIndex HBは4160なので、逆順にしてオブジェクト・ディクショナリから6041=Bits in Statuswordを読み出していることになります。
次のSubindexは0なので、ナシ、データは0x401Aだとわかります。これも逆にして、0x1A40=0b1101001000000は、下の表からSwitch on disabledだとわかります。
xxxx xxxx x0xx 0000 | Not ready to switch on |
xxxx xxxx x1xx 0000 | Switch on disabled |
xxxx xxxx x01x 0001 | Ready to switch on |
xxxx xxxx x01x 0011 | Switched on |
xxxx xxxx x01x 0111 |
Operation enabled |
xxxx xxxx x00x 0111 | Quick stop active |
xxxx xxxx x0xx 1111 | Fault reaction active |
xxxx xxxx x0xx 1000 | Fault |
各ビットの意味です。
0 Ready to Switch ON、1 Switched ON、2 Operation Enabled、 3 Fault、 4 Voltage Enabled、5 Quick Stop 、6 Switch ON Disabled、 7 Warning、 8 Drive profile operation ready (manufacturer-specific (MS)) 、9 Remote、 10 Target Reached、 11 Internal Limit Active、12,13 Operation Mode Specific (OMS) 、14 Reserved (manufacturer-specific (MS)) 、15 TLC (manufacturer-specific (MS))
●<その2>IXXATのUSB-to_CAN V2 Compactを利用する
WindowsマシンをCANバスに接続するために使っているIXXATのUSB-to_CAN V2 Compactには、canAnalyser3 Miniというユーティリティ・ソフトが付属します。CANバスのモニタとして利用ができますが、CANopenのプロトコルを解釈してはくれません。その手のソフトは調べると約20万円するようです。
右上のログ画面には、時刻、ID、データ・フレームが記録されています。
●リセット・プログラム canreset.py
プログラムを作って動かすと暴走することが多々あります。下記の画面は、BLVD_KRDのサポート・ソフトMEXE02のCANopen通信ステータス画面の一部です。暴走すると、左のNMT(通信ステート)がStoppedになったり、右のState Machine(運転ステート)がFault状態で止まってしまい、プログラムを修正しても、正しく動きださないことがあります。
そこで、いろいろエラーを解除し、電源が入った直後に戻すcanreset.py(ラズパイ用)を作りました。最初のCANバスのデータは、このプログラムなどを動かしたときのものです。100% 電源ONの初期状態に戻らないこともありますが、ほとんどうまく動きます。
import canopen # Start with creating a network representing one CAN bus # Connect to the CAN bus network.check() # Add some nodes with corresponding Object Dictionaries # all nodes simulaneously as a broadcast message # Reset network node.setup_402_state_machine() print('\ngoing to exit... stopping...') |
実行している様子です。
network.nmt.state = 'RESET'
このCANバスにつながっているすべてに対してリセットを発行?しているので、別の機材の接続が切れるなどするかもしれません。
このプログラムは、仮想環境で動かしています。
(envtest) yoshi@ras05:~ $ pip list
Package Version
----------------- -------
canopen 2.2.0
msgpack 1.0.8
packaging 24.0
pip 23.0.1
python-can 4.3.1
setuptools 66.1.1
typing_extensions 4.10.0
wrapt 1.16.0
●<その3>Linuxのcan utils
CANバスの信号をラズパイで見ます。can-utilsをインストールします。仮想環境envcanで動かしています。
(envcan) yoshi@ras05:~ $ sudo apt-get install can-utils
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
can-utils is already the newest version (2020.11.0-1).
The following packages were automatically installed and are no longer required:
libcamera0.1 libssl1.1 linux-headers-6.1.0-rpi7-common-rpi linux-headers-6.1.0-rpi7-rpi-2712
linux-headers-6.1.0-rpi7-rpi-v8 linux-image-6.1.0-rpi7-rpi-2712 linux-image-6.1.0-rpi7-rpi-v8 rtimucli
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
ターミナルを一つ立ち上げて、 can-utilsでインストールしたアプリケーションの一つcandumpを動かします(仮想環境でなくてよい)。
$ candump can0
can0は、プログラムで利用しているネットワーク・デバイスの名前です。
# sudo ip link set can0 up type can bitrate 1000000
network.connect(bustype='socketcan', channel='can0')
元のターミナルに戻って、canreset.pyを起動します。
(envcan) yoshi@ras05:~ $ python canreset.py
===start ID=12 OrientalMotor
network state 1) = INITIALISING
node state 1) = PRE-OPERATIONAL
state_machine state 1) = NOT READY TO SWITCH ON
going to exit... stopping...
もう一つのターミナルの表示です。CANバスを流れるデータが見えました。
●少しプログラムでデータを見やすく candump0.py
ダンプをファイルに落とします。canreset.pyを起動します。
$ candump can0>t.txt
フレームの最初はCAN-ID(ID)です。functionとNode-IDが組み合わさった11ビットなので、これを、デコードします。
FUNCTION = {'0000':'NMT','0001':'EMCY','0010':'TIME','0011':'TPDO1','0100':'RPDO1', f = open('t.txt', 'r') while line: |
プログラムの名称をcandump0.pyとしました。実行します。読み出すのはリダイレクトしたt.txtです。
ほとんど役に立たないですね。
第9回で、Analog Devices TCML-IDEを利用します。このツールは無償で使え、CANopenの流れるデータをリアルタイムでデコードできます。
●資料
<オシロスコープ> PicoScope 5242B(垂直方向の分解能が最大16ビット、帯域が60MHz、入力2チャネル、発振出力1チャネル)
<ixxat Windows driver software> https://www.ixxat.com/technical-support/support/windows-driver-software
<MEXE02> https://www.orientalmotor.co.jp/ja/products/detail?hinmei=MEXE02