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_type | CANOPEN |
| 実装クラス | plantpulse.driver.protocol.canopen.CANOpenDriver |
| ライブラリ | 独自ネイティブ (plantpulse-plc-protocol の canopen — SDO expedited upload) |
| 継承 | BaseProtocolDriver (PLC4j ではない) |
getProtocol() | "canopen:tcp" (旧 PLC4X scheme 表記を維持 — ログ/診断互換) |
| デフォルトポート | 20200 (CAN-over-TCP ゲートウェイ) |
| ステータス | 安定 (SDO expedited ポーリング) |
| read | OK (SDO expedited upload、値 ≤4バイト) |
| write | ❌ (読み取り専用 — SDO download 未実装) |
| セキュリティ | なし |
デフォルト 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、command0x43(4B)/0x47(3B)/0x4B(2B)/0x4F(1B) — 値は little-endian。0x80= Abort(コード u32 LE) → 通信例外。 - segmented / block transfer 非対応(値 >4B、例: 長い文字列) — スカラータグのポーリングには expedited で十分です。
OPC 登録オプション
| フィールド | 意味 | デフォルト |
|---|---|---|
opc_agent_ip | CAN-TCP ゲートウェイ IP | 192.168.1.20 |
opc_agent_port | ゲートウェイ TCP ポート | 20200 |
options.read-timeout | SDO 応答タイムアウト (ms) | 3000 |
options.transport | tcp / socketcan(スタブ) | tcp |
options.can-interface | socketcan モードのインタフェース名 | can0 |
旧フォーム/ドキュメントの node-id オプションは廃止されました — ノード ID は現在タグアドレスの1番目のフィールドです(下記参照)。request-timeout/heartbeat オプションもネイティブ実装では受け付けません(タイムアウトは read-timeout)。
タグ plc_address 形式 (新しい規約)
<nodeId>:<index>:<subindex>[:<TYPE>]
| フィールド | 意味 | 表記 |
|---|---|---|
nodeId | CANopen ノード 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:INT32 | Position actual value (32-bit signed) |
5:8192:1 | ノード 5、index 10進 8192(=0x2000)、TYPE 省略 → UINT16 |
TYPE トークン (別名を許容)
| トークン(別名) | サイズ | 解釈 |
|---|---|---|
BOOL(BOOLEAN) | 1 | 0 以外は true |
UINT8(U8,USINT,BYTE) / INT8(I8,SINT) | 1 | u8 / i8 |
UINT16(U16,UINT,WORD) / INT16(I16,INT) | 2 | u16 / i16 (デフォルト UINT16) |
UINT32(U32,UDINT,DWORD) / INT32(I32,DINT) | 4 | u32 / i32 |
REAL(FLOAT,F32,REAL32) | 4 | IEEE-754 float (LE) |
STRING(STR,VISIBLE_STRING) | ≤4 | ASCII (末尾の 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() = false、write()は常に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-protocolのcanopenパッケージ。 - 運用: ゲートウェイのフレーミングは独自バイナリ(
canId+dlc+data) — socketcand のテキストプロトコルとは異なります。アドレスは device の EDS ファイルを基準に検証することを推奨します。