メインコンテンツまでスキップ

CANopen ドライバ

概要

CANopen — CAN バス上の EN 50325-4 / CiA 301 標準 application layer(モータドライブ / エンコーダ / IO モジュールで一般的)。2026-07 ネイティブ再実装 — 旧 Apache PLC4j canopen への委譲は削除されました(PLC4X の CANopen はローカル SocketCAN transport のみ対応で TCP に載せられず、物理 CAN バスを持たないエッジでは connect が失敗していました)。現在は plantpulse-plc-protocol 独自の SDO expedited upload 実装(CanopenSdoClient)+ transport 抽象化(CanTransport)を使用 — AB-ETH / BACnet と同じネイティブパターンです。

項目
opc_typeCANOPEN
実装クラスplantpulse.driver.protocol.canopen.CANOpenDriver
ライブラリ独自ネイティブ (plantpulse-plc-protocolcanopen — SDO expedited upload)
継承BaseProtocolDriver (PLC4j ではない)
getProtocol()"canopen:tcp" (旧 PLC4X scheme 表記を維持 — ログ/診断互換)
デフォルトポート20200 (CAN-over-TCP ゲートウェイ)
ステータス安定 (SDO expedited ポーリング)
readOK (SDO expedited upload、値 ≤4バイト)
write❌ (読み取り専用 — SDO download 未実装)
セキュリティなし
CAN-over-TCP ゲートウェイ前提

デフォルト transport(tcp)は CAN ↔ TCP ゲートウェイ の先にある CANopen ノードと通信します。CAN フレームを canId(4B BE) + dlc(1B) + data[dlc] 独自のバイナリフレーミングで TCP に載せて転送します(ハンドシェイク/バス名ネゴシエーションなし — シミュレータと同一フレーミング)。transport=socketcan(ローカル can0)は 現時点ではスタブ(AF_CAN ネイティブバインディング/JNI が必要)であり connect は失敗します — 物理 CAN インタフェース対応は後続対応です。


クラス構造

BaseProtocolDriver
└── CANOpenDriver — connect() 에서 CanTransport(tcp/socketcan) + CanopenSdoClient 생성

read 失敗(Abort/タイムアウト/ソケット)時はソケットを無効化(connected=false + close)し、エッジ側の再接続を促します。


wire フォーマット要約 (独自実装 — SDO expedited upload)

  • 要求: COB-ID 0x600+nodeId、data [0x40, index LE(2B), subindex, 0×4]
  • 応答: COB-ID 0x580+nodeId、command 0x43(4B)/0x47(3B)/0x4B(2B)/0x4F(1B) — 値は little-endian。0x80 = Abort(コード u32 LE) → 通信例外。
  • segmented / block transfer 非対応(値 >4B、例: 長い文字列) — スカラータグのポーリングには expedited で十分です。

OPC 登録オプション

フィールド意味デフォルト
opc_agent_ipCAN-TCP ゲートウェイ IP192.168.1.20
opc_agent_portゲートウェイ TCP ポート20200
options.read-timeoutSDO 応答タイムアウト (ms)3000
options.transporttcp / socketcan(スタブ)tcp
options.can-interfacesocketcan モードのインタフェース名can0
旧 PLC4X オプションの削除

旧フォーム/ドキュメントの node-id オプションは廃止されました — ノード ID は現在タグアドレスの1番目のフィールドです(下記参照)。request-timeout/heartbeat オプションもネイティブ実装では受け付けません(タイムアウトは read-timeout)。


タグ plc_address 形式 (新しい規約)

<nodeId>:<index>:<subindex>[:<TYPE>]
フィールド意味表記
nodeIdCANopen ノード id (1..127)10進
indexオブジェクトディクショナリ index (0..0xFFFF)0x 接頭の16進(0x6041) または 10進
subindexサブ index (0..255)0x 接頭の16進 または 10進
TYPE (任意)LE バイトの解釈タイプ省略時は data_type から推論 → それも無い場合は UINT16
表記意味
1:0x6041:0:UINT16ノード 1、DS402 Statusword
3:0x2000:0:REALノード 3、メーカー領域 float32
1:0x6064:0:INT32Position actual value (32-bit signed)
5:8192:1ノード 5、index 10進 8192(=0x2000)、TYPE 省略 → UINT16

TYPE トークン (別名を許容)

トークン(別名)サイズ解釈
BOOL(BOOLEAN)10 以外は true
UINT8(U8,USINT,BYTE) / INT8(I8,SINT)1u8 / i8
UINT16(U16,UINT,WORD) / INT16(I16,INT)2u16 / i16 (デフォルト UINT16)
UINT32(U32,UDINT,DWORD) / INT32(I32,DINT)4u32 / i32
REAL(FLOAT,F32,REAL32)4IEEE-754 float (LE)
STRING(STR,VISIBLE_STRING)≤4ASCII (末尾の NUL を除去)

TYPE 省略時は data_type から推論: Boolean→BOOL、Integer→INT16、Long→INT32、Float→REAL、Double→REAL(4B 近似)、String→STRING。


support / 非対応

  • read: SDO expedited upload (≤4バイト) — OK。
  • write: 非対応isWriteSupported() = falsewrite() は常に false。(SDO download は後続対応。)
  • segmented / block SDO、PDO マッピング、NMT / Heartbeat 監視、SYNC、EMCY、LSS: 非対応。
  • 直接 SocketCAN / USB-CAN: スタブ (CAN-over-TCP ゲートウェイ前提)。

curl 登録例

curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_CANOPEN_DRIVE1",
"opc_type": "CANOPEN",
"opc_name": "Servo Drive 1",
"opc_agent_ip": "192.168.1.20",
"opc_agent_port": "20200",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": { "read-timeout": "3000" },
"tag_list": [
{"tag_id":"OPC_CANOPEN_DRIVE1_T01","tag_name":"Statusword","plc_address":"1:0x6041:0:UINT16","data_type":"Integer"},
{"tag_id":"OPC_CANOPEN_DRIVE1_T02","tag_name":"ActualPos","plc_address":"1:0x6064:0:INT32","data_type":"Long"}
]
}'

参考

  • CiA 301 (Application Layer) / CiA 402 (Drives) 標準。
  • コード: plantpulse-edge-driver/src/plantpulse/driver/protocol/canopen/CANOpenDriver.java + plantpulse-plc-protocolcanopen パッケージ。
  • 運用: ゲートウェイのフレーミングは独自バイナリ(canId+dlc+data) — socketcand のテキストプロトコルとは異なります。アドレスは device の EDS ファイルを基準に検証することを推奨します。