見出し画像

【CAN】J1939 標準PGN を使ったモーター制御の実装ガイド

J1939の標準PGNを使用してモーターの制御を行う事例をサンプルコードを入れながら紹介する。

J1939では自作PGNを作ることで自由にやり取りができるがここでは標準で用意されているPGNのみとしている。

なかなかここまでの具体例は出てこないと思うので役立ててほしい。

SAE J1939 / ISO 11783 準拠 ─ 実コード・フレーム解析付き

  • 対象PGN: PGN 0xF003 (TSC1) / PGN 0xF004 (EEC1) / PGN 0xFEF2 (EEC2)

  • 通信仕様: 29bit Extended ID / 250kbps または 500kbps



1. なぜ J1939 でモーター制御なのか

CAN通信を使ったモーター制御というと、多くのエンジニアはまず独自プロトコルや CANopen を思い浮かべる。しかし大型車両・産業機械・農業機械・建設機械の世界では、SAE J1939 が事実上の標準として君臨している。J1939 は単なるデータリンク層の規定ではなく、PGN(Parameter Group Number)という形でアプリケーション層のメッセージ定義まで標準化している点が最大の特徴だ。

特に注目すべきは、J1939 がもともとディーゼルエンジン制御向けに設計されていながら、その PGN 体系がそのまま電動モーター・インバーター制御に転用できることだ。EV トラックや電動農機のコントローラーが J1939 互換の診断・制御インターフェースを持つのはこのためである。本稿では標準 PGN を使い、インバーター ECU(ノードアドレス `0x1A`)に対してマスターECU(`0x01`)からモーターのトルク・回転数を制御する具体的な実装を解説する。

💡 Scope

対象は 250 kbps または 500 kbps の J1939 バス。ハードウェアは Linux SocketCAN(例:Kvaser、PEAK)または組み込み MCU(STM32G4 + FDCAN)を想定。サンプルコードは C と Python の両方を示す。


2. J1939 フレーム構造の復習

J1939 は CAN 2.0B の29ビット拡張 IDを使う。この 29 ビットに優先度・PGN・送信元アドレスが詰め込まれる。

29-BIT EXTENDED IDENTIFIER LAYOUT

+-----+---+---+-----------------+-----------------+-----------------+
| PRI | R | DP|   PF (8 bits)   |   PS (8 bits)   |   SA (8 bits)   |
+-----+---+---+-----------------+-----------------+-----------------+
  |     |   |          |                 |                 |
  |     |   |          +--------+--------+                 +-- 送信元アドレス
  |     |   |                   |
  |     |   |                   V
  |     |   +------------> PGN (18 bits)
  V     +----------------> リザーブ・データページ
優先度 (0=最高, 7=最低)

J1939のID体系において最も重要なのが、PDU Format (PF) の値による挙動の違いである。

  • PF < 0xF0 (240) のとき:PDU1 形式(ピアツーピア宛先指定)

    • ​PS バイトが「宛先アドレス (DA: Destination Address)」として扱われる。

    • ​メッセージとしての本来の PGN は、下位8ビット(PS部分)を 0x00 とみなして計算する。

    • ​モーター制御の司令塔である TSC1 (PGN 0xF003) は PDU1 形式であるため、特定のインバーター宛てに投げ分けることができる。

  • PF ≥ 0xF0 のとき:PDU2 形式(ブロードキャスト)

    • ​PS バイトは「グループ拡張 (GE: Group Extension)」となり、PFと合せて純粋な PGN 番号の一部として扱われる。

    • ​ステータス通知に使う EEC1 (PGN 0xF004) は PDU2 形式であるため、バス上の全ノードへブロードキャストされる。

​📊 CAN 29bit ID の計算ロジック

​29bit IDのビット配置をコードに落とし込む際は、以下のマクロ構造を使用する。

// 29bit ID = (Priority << 26) | (PGN << 8) | SA

// 例1:マスター(SA=0x01)からインバーター(DA=0x1A)へ送る TSC1 の場合
// PGN自体は 0xF003 だが、PDU1のためID上のPGNフィールドは 0xF01A となる
// ID = (3 << 26) | (0xF01A << 8) | 0x01 = 0x0CF01A01

// 例2:インバーター(SA=0x1A)がブロードキャストする EEC1 (PGN 0xF004) の場合
// ID = (3 << 26) | (0xF004 << 8) | 0x1A = 0x0CF0041A

3. モーター制御に使う主要標準 PGN

PGN (hex) 略称 名称 方向 周期 用途
0xF003 TSC1 Torque/Speed Control 1 マスター → インバーター 10ms / イベント トルク・回転数の指令値
0xF004 EEC1 Electronic Engine Controller 1 インバーター → バス 10ms 実際の回転数・実トルクのフィードバック
0xFEF2 EEC2 Electronic Engine Controller 2 インバーター → バス 50ms アクセル開度・トルクリミット状態
0xFECA DM1 Active Diagnostic Trouble Codes インバーター → バス 1s / イベント リアルタイムの故障コード(SPN/FMI)
0xEA00 RQST Request PGN 双方向 オンデマンド 任意のPGNデータの要求
0xFEEC VI Vehicle Identification ECU → バス オンデマンド シリアル番号・VIN等のアセット情報

制御の主役は TSC1 だ。これはPDU1形式(PF=0xF0未満)なので、特定のインバーターECUアドレス(DA=0x1A)に向けて送信する。一方、EEC1 はインバーターが自らの状態をブロードキャストするためのものであり、マスター(VCU)はこれを購読して実際の回転数や実トルクをクローズドスタックでモニターする。

ここから先は

12,183字

¥ 980

この記事が気に入ったらチップで応援してみませんか?