📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

649行目: 649行目:
Modbusは、産業用機器間の通信に特化したシンプルで信頼性の高いプロトコルである。<br>
Modbusは、産業用機器間の通信に特化したシンプルで信頼性の高いプロトコルである。<br>
<br>
<br>
Modbus RTUの基本構造について説明する。<br>
* Modbus RTUの基本構造
メッセージは、デバイスアドレス、ファンクションコード、データ、CRCの順に構成される。<br>
*: メッセージは、デバイスアドレス、ファンクションコード、データ、CRCの順に構成される。
デバイスアドレスは1バイトで、通信相手のデバイスを識別する。<br>
** デバイスアドレス
ファンクションコードは1バイトで、実行する操作を指定する。<br>
**: 1バイトで、通信相手のデバイスを識別する。
データは可変長で、読み書きするデータやアドレスを含む。<br>
** ファンクションコード
CRCは2バイトで、エラー検出用のチェックサムとして使用される。<br>
**: 1バイトで、実行する操作を指定する。
*: データは可変長で、読み書きするデータやアドレスを含む。
** CRC
**: 2バイトで、エラー検出用のチェックサムとして使用される。
<br>
<br>
主要なファンクションコードについて説明する。<br>
* 主要なファンクションコードについて
0x03は、ホールディングレジスタの読み取りに使用される。<br>
*: これらのファンクションコードを使用することで、ほとんどの産業用制御が可能になる。
0x06は、単一レジスタへの書き込みに使用される。<br>
** 0x03
0x10は、複数レジスタへの書き込みに使用される。<br>
**: ホールディングレジスタの読み取りに使用される。
これらのファンクションコードを使用することで、ほとんどの産業用制御が可能になる。<br>
** 0x06
**: 単一レジスタへの書き込みに使用される。
** 0x10
**: 複数レジスタへの書き込みに使用される。
<br>
<br>
<u>CRC計算</u>において、Modbus RTUでは、CRC-16を使用してデータの整合性を確認する。<br>
<u>CRC計算</u>において、Modbus RTUでは、CRC-16を使用してデータの整合性を確認する。<br>
CRCは、メッセージ全体であるアドレスからデータまでに対して計算される。<br>
CRCは、メッセージ全体であるアドレスからデータまでに対して計算される。<br>
受信側では、受信したCRCと計算したCRCを比較して、データの正当性を検証する。<br>
受信側では、受信したCRCと計算したCRCを比較して、データの正当性を検証する。<br>
<br>
* CRCの初期化:
*: <math>\mathrm{CRC} = \texttt{0xFFFF} \quad</math> (初期値は全ビット1)<br>
* 各バイト <math>D_i</math> に対して:
*: <math>\mathrm{CRC} = \mathrm{CRC} \oplus D_i \quad</math> (排他的論理和)<br>
* 8回繰り返し (各ビットに対して) :
*: <math>\text{if } (\mathrm{CRC} \;\&\; \texttt{0x0001}) = 1 \text{ then}</math>
*: <math>\quad \mathrm{CRC} = (\mathrm{CRC} \gg 1) \oplus \texttt{0xA001}</math>
*: <math>\text{else}</math>
*: <math>\quad \mathrm{CRC} = \mathrm{CRC} \gg 1</math>
*: <br>
*: <u>反復計算の詳細:</u>
*: <math>
\begin{aligned}
&\mathrm{CRC}_0 = \texttt{0xFFFF} \\
&\mathrm{CRC}_{i+1} = \mathrm{CRC}_i \oplus D_i
\end{aligned}
</math>
*: <br>
*: 各ビット <math>j \in \{0, 1, \ldots, 7\}</math> に対して:
*: <math>
\begin{aligned}
&\mathrm{CRC}_{j+1} = \begin{cases}
\left\lfloor \frac{\mathrm{CRC}_j}{2} \right\rfloor \oplus \texttt{0xA001} & \text{if } \mathrm{CRC}_j \;\&\; 1 = 1 \\
\left\lfloor \frac{\mathrm{CRC}_j}{2} \right\rfloor & \text{if } \mathrm{CRC}_j \;\&\; 1 = 0
\end{cases}
\end{aligned}
</math>
* 最終結果:
*: <math>\mathrm{CRC}_{\text{final}} = (\mathrm{CRC}_{\text{low}}, \mathrm{CRC}_{\text{high}}) \quad</math> (リトルエンディアン形式)
<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  // ModbusRTU.hファイル
  // ModbusRTU.hファイル
991行目: 1,028行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== マルチドロップ通信 ====
==== マルチドロップ通信 ====
RS-485では、複数のデバイスを1つのバスに接続するマルチドロップ構成が可能である。<br>
RS-485では、複数のデバイスを1つのバスに接続するマルチドロップ構成が可能である。<br>