AM2321 I2Cバス通信の解説 |
I2Cインターフェイス
・AM2321と通信するI2Cバスのデータ転送速度は、最大100KHzです。
・I2Cバス通信の基本的な説明は、別途専門書等を参照して下さい。
|
通信プロトコル
・AM2321センサーのI2C通信プロトコルは、標準的なI2Cバス協定の基礎上にあり、I2C_ModBus協定
とAM2321センサー自身の特徴の組み合わせでなる、Modbusプロトコルを参照します。
・具体的な形式は、次のとおりです。
データ形式: |
スレーブアドレス+ R/W |
機能コード |
データ領域 |
CRCチェックサム |
データ長: |
1バイト |
1バイト |
Nバイト |
16ビットのCRC(巡回冗長符号) |
|
スレーブアドレス
・[STARTコンディション]の後に送信される最初のバイトは、スレーブアドレスです。
・上位ビット(MSB)のbit7〜1がAM2321のアドレスを示し、[B8h]を指定します。
MSB |
LSB |
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
R/W |
・最下位(LSB)のbit0は、マスターとスレーブのデータ方向を表します。
・[0]の場合はマスターからスレーブにデータを書き込み、[1]の場合はマスターがスレーブから
データを読み出します。
|
機能コード
・機能コードは、ホストコンピュータが要求する動作を、センサーに実行させるために送信する
命令バイトです。
・コードは1〜127の数値で定義されます。
・I2C_ModBus機能コードの一部
機能コード |
定 義 |
操 作 (バイナリー) |
03h |
レジスター・データの読み取り |
1つ以上のデータ・レジスタを読み出す。 |
10h |
複数レジスターへの書き込み |
バイナリデータを複数のレジスターに書き込む。 |
|
データ領域
・データ領域は、センサーからどの種類の情報を読み出すか、あるいはどのような動作を
実行しなければならないかを含みます。
・これらの情報は、データ(例えば:温度、湿度、センサーの装置情報、ユーザーが書き込むデータ)、
基準アドレス等でもよいです。
・例えば、ホストコンピュータが機能コード[03h]を使用して、センサーにレジスターの値を返させます。
(読み取るレジスターの先頭アドレス および レジスターの個数を含む)
返されるデータには、レジスターのデータ長とレジスターのデータ内容が含まれます。
・「AM2321 データ・レジスター表」にあるレジスターテーブルの、いずれかを読み出すことができます。
AM2321 データ・レジスタ表 |
アドレス |
レジスターの情報 |
00h |
湿度の上位バイト |
01h |
湿度の下位バイト |
02h |
温度の上位バイト |
03h |
温度の下位バイト |
04h |
(予約済み) |
05h |
(予約済み) |
06h |
(予約済み) |
07h |
(予約済み) |
08h |
デバイス型番の上位バイト |
09h |
デバイス型番の下位バイト |
0Ah |
バージョン番号 |
0Bh |
デバイスID (24〜31bit) |
0Ch |
デバイスID (16〜23bit) |
0Dh |
デバイスID (8〜15bit) |
0Eh |
デバイスID (0〜7bit) |
0Fh |
ステータス・レジスター |
|
|
アドレス |
レジスターの情報 |
10h |
ユーザー・レジスター[1]の上位バイト |
11h |
ユーザー・レジスター[1]の下位バイト |
12h |
ユーザー・レジスター[2]の上位バイト |
13h |
ユーザー・レジスター[2]の下位バイト |
14h |
(予約済み) |
15h |
(予約済み) |
16h |
(予約済み) |
17h |
(予約済み) |
18h |
(予約済み) |
19h |
(予約済み) |
1Ah |
(予約済み) |
1Bh |
(予約済み) |
1Ch |
(予約済み) |
1Dh |
(予約済み) |
1Eh |
(予約済み) |
1Fh |
(予約済み) |
|
・センサーのデータ・レジスターには、湿度、温度、センサーのデバイス情報、その他の関連情報が
保存されます。
・すべてのデータ・レジスターは、バイナリデータの単一バイト(8ビット)です。
・一度の読み出しで、最大10個のレジスター内容を読み取ることができます。
・読み出しの長さを上回った場合は、センサーが対応するエラーコードを返します。
|
機能コード[03] レジスター・データの読み取り
・ホストはレジスター・データを読み取る命令を送ります。
通信内容 |
解 説 |
START |
I2Cバスをスタート・コンディションにする。 |
B8h |
スレーブアドレス + [W] (B8h + 0) |
03h |
機能コード [03] レジスター・データの読み取り |
00h |
レジスタの先頭アドレス (この例では湿度の上位バイト) |
04h |
読み出すレジスタの数 (湿度と温度の4バイト) |
STOP |
I2Cバスをストップ・コンディションにする。 |
・ホストはスレーブが返すレジスター・データを読み取ります。
通信内容 |
解 説 |
SART |
I2Cバスをスタート・コンディションにする。 |
B9h |
スレーブアドレス + [R] (B8h + 1) |
03h |
機能コード [03] 機能コードの返し |
04h |
返送するバイト数 (この例では湿度と温度の4バイト) |
01h |
アドレス[00]の内容 (湿度の上位バイト) |
F4h |
アドレス[01]の内容 (湿度の下位バイト) |
00h |
アドレス[02]の内容 (温度の上位バイト) |
FAh |
アドレス[03]の内容 (温度の下位バイト) |
A5h |
16ビットのCRC(巡回冗長符号) (下位バイトが先) |
31h |
16ビットのCRC(巡回冗長符号) (上位バイト) |
STOP |
I2Cバスをストップ・コンディションにする。 |
湿度と温度の数値計算方法
・温度の解像度は16bitで、最上位(MSB)のbit15が[0]の場合は正(プラス)の温度、[1]の場合は
負(マイナス)の温度を示します。
・最上位のbit15を除き、bit14〜bit0は、センサーの示した温度値が入ります。
例: -10.1℃は、1000_0000 0110_0101
・センサーから出力される湿度と温度データは、実際の湿度/温度値の10倍された値です。
・センサーから返される湿度と温度データを、10進数に変換して10で割り算をすると、
湿度は%RH、温度は℃の単位に相当する値となります。
・例えば上記のデータで計算すると、
湿度: 01F4 = 1×256 + 15×16 + 4 = 500 → 湿度 = 500÷10 = 50.0%RH
温度: 00FA = 15×16 + 10 = 250 → 温度 = 250÷10 = 25.0℃
CRC(巡回冗長符号)
・別記のCRC計算方法の項を参照して計算し、正しくない場合は通信等にエラーが存在するので、
そのデータを使用するべきではありません。
|
機能コード[10] 複数レジスターへの書き込み
・センサーのユーザー・レジスターに、データを保存することができます。
・すべてのユーザー・レジスターは、バイナリデータの単一バイト(8ビット)です。
・一度の書き込みで、最大10個のレジスター内容を書き込むことができます。
・書き込みの長さを上回った場合は、センサーが対応するエラーコードを返します。
・ホストはセンサーのレジスターにデータを書き込む命令を送ります。
通信内容 |
解 説 |
SART |
I2Cバスをスタート・コンディションにする。 |
B8h |
スレーブアドレス + [W] (B8h + 0) |
10h |
機能コード [10] 複数レジスターへの書き込み |
10h |
書き込むレジスタの先頭アドレス (この例ではユーザー・レジスター[1]の上位) |
02h |
書き込むバイト数 (この例では2バイト) |
01h |
指定アドレスに書き込むデータ (この例ではアドレス[10]) |
02h |
指定アドレスに書き込むデータ (この例ではアドレス[11]) |
92h |
16ビットのCRC(巡回冗長符号) (下位バイトが先) |
C0h |
16ビットのCRC(巡回冗長符号) (上位バイト) |
STOP |
I2Cバスをストップ・コンディションにする。 |
・ホストはセンサーの応答メッセージを読み取ります。
通信内容 |
解 説 |
START |
I2Cバスをスタート・コンディションにする。 |
B9h |
スレーブアドレス + [R] (B8h + 1) |
10h |
機能コード [10] 機能コードの返し |
10h |
書き込まれたレジスタの先頭アドレス |
02h |
書き込まれたバイト数 (この例では2バイト) |
04h |
16ビットのCRC(巡回冗長符号) (下位バイトが先) |
FCh |
16ビットのCRC(巡回冗長符号) (上位バイト) |
STOP |
I2Cバスをストップ・コンディションにする。 |
|
CRCチェックサム
・情報を伝送する過程で、ノイズまたは何らかの干渉によってエラーが発生する場合があります。
・CRC(巡回冗長検査)によって、ホストコンピュータあるいはセンサーが、通信データの検証を
行うことができます。
・これにより伝送されたデータを破棄することもできるので、システムの安全性と効率を高める
ことができます。
・CRC(巡回冗長符号)は、2バイトで16ビットのバイナリー値です。
・送信デバイス(ホスト)が計算するCRCチェックサムは、機能コード以降に送られるバイトに
対して計算します。 (スレーブアドレスは、CRC計算に含みません)
・CRCチェックサムの2バイトは、下位バイトが先に送られます。
・CRCチェックサムの計算方法
1. あらかじめ16ビットのレジスター(変数)に16進数で[FFFF]をセットします。
(これを、CRCレジスターと称します)
2. 1つ目の8ビットバイナリーデータ(通信フレームの1バイト目)と、16ビットのCRCレジスターの
下位8ビットで排他的論理和を計算し、結果をCRCレジスターに置きます。
3. CRCレジスターの内容を1ビット右シフト(LSBに向かって)して、最上位(MSB)に[0]を埋めます。
そして、右シフトによってあふれた最下位ビットを検査します。
4. もし、あふれた最下位ビットが[0]ならば、「手順 5.」へ進みます。
あふれた最下位ビットが[1]ならば、CRCレジスターと多項式[A001](1010_0000_0000_0001)の
排他的論理和を行い、CRCレジスターに格納します。
5. 「手順 3.と 4.」を8回繰り返し、8ビット全体に右シフトの処理を行います。
6. 通信フレームの次のバイトに対しても、「手順 2.〜 5.」の処理を繰り返し行います。
7. 通信フレームのすべてのバイトに対して上記の処理を行った後、結果として得た16ビット
CRCレジスターを、上位バイト(8ビット)と下位バイト(8ビット)に分けます。
8. CRCチェックサムの値として、下位バイトを先に、上位バイトを後に送信します。
|
I2C通信シーケンス
・AM2321センサーのI2C通信は、標準I2C通信シーケンスに従っていますが、正確にセンサーを
読み取るために、独自の通信プロトコルおよび通信タイミングの要件に従う必要があります。
・センサーの読み出しと書き込みを行うには、次の3つの手順に従う必要があります。
ステップ1 |
|
ステップ2 |
|
ステップ3 |
S |
SLA+W
B8h |
待ち
T1 |
P |
アイ
ドル |
S |
SLA+W
B8h |
DATA
1 |
P |
待ち
T2 |
S |
SLA+R
B9h |
待ち
T3 |
DATA
2 |
P |
S = START コンディション
P = STOP コンディション |
T1 = 最小800μs〜最大3ms
T2 = 最小1.5ms
T3 = 最小30μs |
DATA 1 = ホストがデータを読み書きするための命令を送信する。
DATA 2 = センサーがデータの読み取りまたは確認を返すためにデータを送信する。 |
ステップ1: センサーを休止状態から呼び覚まします。
・センサーが自己発熱による湿度誤差を低減するため休止状態に入っている場合、センサーへの
読み書き命令を送る前に、センサーを休止状態から呼び覚ます必要があります。
・そうしなければ、センサーは反応しません。
・注意しなければならないのは、センサーを呼び覚ます時、スレーブアドレスに対してセンサーは
ACKを返すことができません。
しかしホストは必ずACKのための9番目のクロック(SCL)を発送しなければなりません。
・ホストがSTARTを発行しスレーブアドレスを送信した後に、一定期間(最小800μs〜最大3ms)の
待ち時間を入れてからSTOPを発行します。
ホストがハードウェアI2Cの場合は自動的に待機するので、プログラムで待つ必要はありません。
START |
スレーブ
アドレス+[W]
B8h |
NACK |
最小800μs〜最大3ms
の待ち時間 |
STOP |
ステップ2: 読み出し命令を送信するか、書き込み命令を送信します。
・AM2321センサーを呼び覚ました後は、標準的なI2C読み書きのタイミングに従って、最高速度の
100Kb/sをサポートします。
・湿度と温度を読み出す命令の例。
START |
スレーブ
アドレス+[W]
B8h |
ACK |
機能コード
03h |
ACK |
レジスタの
先頭アドレス
00h |
ACK |
読み出す
レジスタの数
04h |
ACK |
STOP |
ステップ3: センサーが読み取ったデータや確認信号を返します。
・ホストは、読み出しや書き込み命令を送信した後に、少なくとも1.5msの待ち時間を入れる必要が
あります。
・それから再び、読み出すデータや確認信号を受信するためのシーケンスを送信します。
・そして、受信のためのシーケンスで注意する点は、スレーブアドレスを送信した後に、少なくとも
30μsの待ち時間を入れてから、データを読み取る必要があることです。
・そうでなければ、通信のエラーが発生します。
・湿度と温度の値を読み取る例。 (1.5msの待ち時間の後)
START |
スレーブ
アドレス+[R]
B9h |
ACK |
最小30μs
の待ち時間 |
機能コード
の返し
03h |
ACK |
返送する
バイト数
04h |
ACK |
湿度の
上位バイト
03h |
ACK |
湿度の
下位バイト
39h |
ACK |
温度の
上位バイト
01h |
ACK |
温度の
下位バイト
15h |
ACK |
CRC
下位バイト
E1h |
ACK |
CRC
上位バイト
FEh |
NACK |
STOP |
・上記の例で湿度と温度の値を計算すると、
0339h = (3×256) + (3×16) + (9) = 825 → 湿度 = 825÷10 = 82.5%RH
0115h = (1×256) + (1×16) + (5) = 277 → 温度 = 277÷10 = 27.7℃
・これら3つのステップにより、センサーのすべてのレジスターを読むことができます。
・書き込み操作は、4つのユーザー・レジスターとステータス・レジスターの5つに対してだけで、
それ以外の場合はエラーになります。
|
エラーコード
・エラーが発生した場合、ステップ3でセンサーが返してくるデータの、「返送するバイト数」が05hと
なり、次のバイトに下記のエラーコードが入り、16ビットのCRCチェックサムが続きます。
80h: サポートしていない機能コード。
81h: 不正なアドレスの読み込み。
82h: 範囲を超えたデータの書き込み。
83h: CRCチェックサムエラー。
84h: 書き込み禁止。
|
ステータス・レジスター
・ステータスレジスターは、一時的にすべて予約されています。
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
予約済 |
予約済 |
予約済 |
予約済 |
予約済 |
予約済 |
予約済 |
予約済 |
|
測定の手順
・AM2321は、温度および湿度を正確に測定するため、センサーが測定をしていないときには、
負荷を軽減し自己発熱の影響を減らすため、自動的に休止状態になります。
・AM2321の作業モデルは、被動式を採用しています。
・つまり、ホストコンピュータが命令によってセンサーを呼び覚ました後に、再び相応の命令を
送信して、温度および湿度を読み取ります。
・通信が終わった後に、センサーは1回の温度と湿度のサンプリングを起動します。
・そのため、もし長い時間センサーを読まなかった場合は、連続して2度センサー読んで下さい。
(2度の読み込みの最小間隔は2秒です)
・2回目の値を最新の測定値とします。
・サンプリングが終わった後に、センサーは自動的に休止状態に変わります。
・次回ホストコンピュータが、またセンサーを読まなければならない時は、改めてセンサーを
呼び覚ます必要があります。
・注意しなければならないのは、ホストコンピュータとの通信で、初めから終わりまでの最も長い
時間は3秒です。
・もし3秒以内に通信が完了しない場合は、センサーは自動的に通信を終えて、自動的に休止の
状態に変わります。
・ホストコンピュータが再度センサーを読み込む場合、改めて呼び覚まさす命令を送信しなければ
なりません。
※要約すれば、1回目の温度と湿度の読み込み命令で、センサーが休止状態から起動して
サンプリングを始めるので、この時の温度と湿度データを読み出せるのは2秒後だということです。
(最短でも2秒の遅延が発生するということです)
そして、長時間読み出しを行わなかった場合は、次回に読み出した温度と湿度データは過去の
値であるため、最新の数値を得るためには、連続して2回(2秒の間隔をおいて)読み出さなければ
ならないということです。
例えば、1時間おきに測定する場合に、1回目の読み出した値は1時間前のデータであるため、
連続して2回(2秒の間隔をおいて)読み出した値が最新の値となります。
|