センシリオン製温湿度センサーSHT31を使う上での注意点その3です。
Part1とPart2で、SHT31にWriteコマンドを送った後にある程度の待ち時間が必要で有ることを示しましたが、Part3では、どの程度の待ち時間が適切なのか?を検討したいと思います。
● 初期化コマンドは1msの待ち時間でOK。測定開始コマンドの場合は、データシートに記載がある測定完了までの待ち時間が必要
結論としては表題の通りなのですが、順を追って説明します。まず、全ての待ち時間を1msとした場合のI2Cバスの挙動を観測してみました。Arduinoのスケッチを以下に示します。
void setup()
{
Wire.begin(); //Wireライブラリを使って、I2Cの有効化
Serial.begin(9600); //シリアル通信スピードを9600bpsに設定//ソフトウエアリセットコマンド送信
Wire.beginTransmission(SHT31_Address);
Wire.write(0x30);
Wire.write(0xA2);
Wire.endTransmission();
delay(1);//ステータスレジスタクリア
Wire.beginTransmission(SHT31_Address);
Wire.write(0x30);
Wire.write(0x41);
Wire.endTransmission();
delay(1);//内部ヒーターOFF
Wire.beginTransmission(SHT31_Address);
Wire.write(0x30);
Wire.write(0x66);
//コマンド送信終了
Wire.endTransmission();
delay(1);
}void loop()
{
//SHT31にI2C経由でコマンド送信開始
Wire.beginTransmission(SHT31_Address);
//シングルショットモードで測定
//MSB部のコマンド。0x24はクロック・ストレッチ無効とする
Wire.write(0x24);
//LSB部のコマンド。0x00は繰り返し精度「高」
Wire.write(0x00);
//コマンド送信終了
Wire.endTransmission();
delay(1);//SHTー31に対して、I2C経由で6バイト分のデータを読むようにリクエスト
Wire.requestFrom(SHT31_Address,6);
//6バイト準備されるまで待つ
while (Wire.available()<6){
}
//読み込み開始
Ta_MSB=Wire.read();
Ta_LSB=Wire.read();
Ta_CRC=Wire.read();
RH_MSB=Wire.read();
RH_LSB=Wire.read();
RH_CRC=Wire.read();
(以下略)
上記スケッチを動作させたときのI2Cバスの応答を図1-1から図1-4に示します。
図1-1 ソフトウエアリセットコマンド(0x30A2)は正常に受信されている。
図1-2 ステータスレジスタ消去コマンド(0x3041)も問題ない。
図1-3 内部ヒーターOFFコマンド(0x3066)もOK。
図1-4 測定開始コマンド(0x2400)は正常に送られているが、
データ読み込みに失敗。I2Cバス停止。
ソフトウエアリセット、ステータスレジスタ消去、内部ヒーターOFFまでは、1msの待ち時間で問題ありませんが、測定開始コマンド(0x2400)を送ってからデータ取得までの待ち時間が1msだと読み込みに失敗しI2Cバスが停止してしまいます(図1-4の右端「45R~a」の部分)。
では適切な待ち時間はどれくらいかのか?は、SHT31のデータシートに記載がありました。図2に示します。
「測定時間」の項目に書かれている時間が「待つべき時間」で、測定精度「高」の場合、標準値12.5ms、最大15msとあります。
そこで、スケッチを以下のように書き換えて動かしてみました。
void loop()
{
//SHT31にI2C経由でコマンド送信開始
Wire.beginTransmission(SHT31_Address);
//シングルショットモードで測定
//MSB部のコマンド。0x24はクロック・ストレッチ無効とする
Wire.write(0x24);
//LSB部のコマンド。0x00は繰り返し精度「高」
Wire.write(0x00);
//コマンド送信終了
Wire.endTransmission();
delay(20); //データシート上は最大15msだが、余裕を見て20ms待つこととした//SHTー31に対して、I2C経由で6バイト分のデータを読むようにリクエスト
Wire.requestFrom(SHT31_Address,6);
//6バイト準備されるまで待つ
while (Wire.available()<6){
}
//読み込み開始
Ta_MSB=Wire.read();
Ta_LSB=Wire.read();
Ta_CRC=Wire.read();
RH_MSB=Wire.read();
RH_LSB=Wire.read();
RH_CRC=Wire.read();
(以下略)
上記変更を行った時のI2Cバスの波形を図3−1と図3−2に示します。
図3-1 測定開始コマンド(0x2400)を送ったところ。「45Wa 24a 00a」となって正常動作
図3-2 測定開始コマンドから約20ms遅れてデータ読み出しを行うと「45Ra」への応答があり、SHT31からの測定値が順次送られているのがわかる。
やっと満足な結果が得られ、かつ待ち時間の妥当性が検証できました。最終的なArduinoのスケッチは、次回のエントリで紹介したいと思います。