【CAN】J1939で独自データを送る方法。Proprietary PGN設計・実装完全ガイド1(概念解説)
はじめに
「J1939で独自データを送れ」
そう言われて困った経験はないだろうか。エンジンECUやトランスミッションECUであれば、J1939-71に定義済みのPGNを使えばよいことも多い。
しかし実際の開発現場では、
・オリジナル情報
・ロボットアームの関節角度
・独自BMSのセル電圧
・油圧制御ユニットの内部状態
・AI推論結果
・カメラ認識情報
など、標準PGNに存在しないデータを送らなければならない場面が必ず発生する。
ところが規格書には、
「Proprietary PGNが存在する」
とは書かれているが、
・どの番号を選ぶべきか
・社内でどう管理するか
・DBCをどう作るか
・Address Claimは必要か
・BAMとRTS/CTSはどちらを選ぶべきか
といった実務上の判断基準はほとんど書かれていない。その結果、「とりあえず動いた」レベルの実装になり、数か月後にPGN衝突やDBC不整合で大きなトラブルになる。
この記事では単なる規格解説ではなく、
量産開発で実際に困るポイントに焦点を当てる。
題材として、
PGN = 0xFF10
を用いた4軸ロボットアームの関節データ送信を例に、設計から実装、運用までを解説する。
なぜオリジナルPGNが必要なのか
J1939には数百種類のPGNが定義されている。
しかし現実には足りない。
理由は製品ごとに必要なデータが異なるからである。例えば、
農機 建機 ロボット 船舶
では必要な情報が大きく異なる。
そのためSAEはメーカー独自用途としてProprietary PGNを予約している。
つまり、
標準PGNに存在しないデータを送ること自体は規格違反ではない。むしろ正しい使い方である。
最初にやるべきこと
多くのエンジニアはコードを書き始める。
しかし実務では先にPGN管理台帳を作るべきである。
例
PGN:0xFF10 名称:ARM_DATA 担当:Robot Team
PGN:0xFF11 名称:BMS_DATA 担当:Power Team
PGN:0xFF12 名称:VISION_DATA 担当:AI Team
PGN衝突の多くは技術的な問題ではなく運用上の問題である。
Proprietary A と Proprietary B
J1939には独自用途向けの領域が存在する。【Proprietary A】
PGN = 0xEF00
特徴
・PDU1 ・宛先指定可能 ・ユニキャスト向き
主な用途
・位置指令 ・設定値変更 ・制御コマンド
【Proprietary B】
PGN = 0xFF00〜0xFFFF
特徴
・PDU2 ・ブロードキャスト ・センサデータ向き
主な用途
・角度情報 ・温度情報 ・状態監視 ・ロギング
本記事ではProprietary Bを使用する。
なぜProprietary Bが使われるのか
受信ノードが増えても送信側を変更する必要がないためである。例えば、ロボットECUが送信したデータを、
・HMI ・ロガー ・診断ツール ・上位制御装置
が同時に受信できる。
システム拡張が容易になる。
PGN設計で最も重要な考え方
初心者は「今送るデータ」だけを考える。
しかし実務では「将来追加されるデータ」も考慮しなければならない。
例えば今回の設計で61bitしか使わないなら、残りのビットを将来拡張用に確保しておく。
おすすめはVersionフィールドを持たせること。たった数bit確保するだけで将来の変更に対応しやすくなる。
PGN番号の管理方法
実務で本当によく起きるトラブルがある。
開発者A
「0xFF10使います」
開発者B
「自分も0xFF10使っていました」
量産試験で発覚。実際によくある話である。
対策はシンプル。PGN管理表をGitで管理する。
Excelだけで管理すると衝突に気づきにくい。
推奨する番号割り当て
0xFF00〜0xFF1F ロボット系
0xFF20〜0xFF3F BMS系
0xFF40〜0xFF5F 油圧系
0xFF60〜0xFF7F 診断系
0xFF80〜0xFFFF 将来予約
最初から用途別に分けておくと運用しやすい。
Address Claimを軽視してはいけない
試験環境では問題なく動作していても、量産環境では同じSAを持つECUが接続される可能性がある。
J1939ではAddress Claimによってアドレス競合を解決する。これを実装していないと、診断ツールから不正ノードと判断される場合もある。
BAMとRTS/CTSの選択
多くの記事ではBAMしか紹介されていない。しかし実務ではRTS/CTSも重要である。
【BAM】
メリット
・実装が簡単 ・全ノード受信可能
デメリット
・受信確認なし ・欠落検出不可
用途
・温度 ・圧力 ・状態監視
【RTS/CTS】
メリット
・高信頼 ・受信確認あり
デメリット
・実装が複雑
用途
・設定データ ・キャリブレーション ・ファームウェア情報
現場で多い失敗事例
【事例1】
DBCだけ更新された
送信側と受信側でバージョン不一致。
速度100%が4%と表示された。
【事例2】
エンディアン違い
IntelとMotorolaを混同。
角度45°が異常値になる。
【事例3】
PGN重複
別チームが同じPGNを使用。
ロガーが誤デコード。
原因特定に数週間かかった。
【事例4】
Address Claim未実装
開発環境では正常。
量産環境でSA競合。
通信不安定化。
DBCはソースコードと同じ扱いにする
実務ではDBCをメール添付で配布するケースがある。これは非常に危険である。
推奨は、
・ソースコード ・DBC ・PGN管理表 ・SPN管理表
を同じリポジトリで管理すること。
社内SPN管理
本記事で使用している
520200〜520205
はSAE公式SPNではない。社内管理用SPNの例である。独自SPNを採番する場合は管理台帳を用意すること。
バス負荷を忘れない
CANは有限資源である。後から
・診断通信 ・ロギング ・OTA
が追加される。平均30〜40%程度に抑えておくと運用しやすい。
設計レビューで確認すべき項目
PGN重複なし
SPN管理済み
DBC作成済み
Address Claim実装済み
BAM/RTS選定済み
バス負荷計算済み
境界値試験実施
ループバック試験実施
CANアナライザ確認済み
Git管理済み
まとめ
J1939の独自PGN設計で本当に重要なのは、CAN ID計算ではない。ビットパッキングでもない。量産後も維持できる運用設計である。実際のトラブルの多くは、
PGN管理不足
DBC不一致
Address Claim未実装
によって発生する。
設計 → ドキュメント → 実装 →検証 ↓→運用
この順番を守るだけで、多くの問題を未然に防ぐことができる。今回紹介したPGN=0xFF10の例は小規模なサンプルだが、建機 農機 船舶 産業機械 ロボットの量産システムでも同じ考え方が適用できる。
まずは仮想CAN環境でフレームを流し、DBCでデコードし、Address Claimまで確認してみてほしい。そこまでできれば、独自PGN設計の第一歩は十分に踏み出せている。
次に実装してみよう👇️
