● 実験テーマ137

「温湿度センサーHDC1000の経年変化改善の為、SHT31に交換した。」
 (センサー購入後から約3.5年間は良かったが去年当たりから湿度が高目に表示され出した)

■ 2022.9.29
  ・
自作の温湿度計(気圧も含む)の内
   
BME280を使ったものは、割と近い値が出る(針式:64%→ 53%)が、
   HDC1000を使ったものは、20%位高目に出る。(針式:64%→ 81.51%)
   なので梅雨時等は直ぐに、99.99%に張付く。

<WEB情報>
「電気と電子と電波の日記」サイトより
 「温湿度センサーHDC1000劣化→交換:2018.09.23」
 プログラムを改修しようと思い、宅内に配置された各センサーを回収しつつ計測値を改めて見ると、
 湿度の計測値が異常。3つが99.9%に張り付き。1つは明らかに高め。運用開始後2年近く。こんなことあるのか。

 ※ 秋月電子ではこの製品(AE-HDC1000)は取扱終了。
    後継はSHT31あたりか。
    ちと高いが、HDC1000モジュールとはピンコンパチブルなので、ハードウェアの手直し不要。発注!
    到着後、ソフトをSHT31のライブラリに変更して、テスト成功。

「henteko.org」サイトより
 「温度・湿度センサーの経年劣化について:2017.04.28」
 HDC1000の測定する湿度を検証してみました。
 SHT11を使用したもの2台と比較すると湿度が20%近く高めに測定されます。
 これは、使用していたHDC1000の2つともほぼ同じように表示されます。

 予備として買い置きしてあった新品のHDC1000に交換してみると今度はSHT11に比較して10%以上低く測定されます。
 新品と古いものとの差は30~40%もあります。
 ・・ということで、まずはっきりしたことは「HDC1000は経年劣化(1年半ほど)で湿度が高く測定されるようになる」ということです。


■ 2022.9.29
  ・
代替えは秋月電子の「AE-SHT31」が価格的にも手頃そうなので注文した。221001

  ・改めて比較のため証拠写真を撮ってみた。
   @ 針式(バイメタル式):59%
   A BME280:50%
   B HDC1000:78.34%



  ・自作のグラフ表示温湿度・気圧計に実装の、HDC1000はソケットに実装されているので
   ハード的にはそのままSHT31を差替えれば良さそうである。
   ソフトのみ別プロジェクトで変更する予定。


■ 2022.10.1
  ・
ソフトのみ別プロジェクトで変更する予定
   新規プロジェクト名は「PIC24F_QVGA_TmpHumPres_TEST_7」とする。


■ 2022.10.2
  ・
HDC1000とSHT31の違い整理
   @ HDC1000:"TI社製"
      SHT31 :"SENSIRION社製"(デバイス正式名称:SHT31-DIS)

   A ピンコンパチだが、
      HDC1000-4pin:RDY
      SHT31-4pin :ADR
      になっている。ここは両者共オープンで問題無い。

   B 電源電圧
      HDC1000:3〜 5V
      SHT31 :2.4〜 5.5V

   C データビット数
      HDC1000:設定により、温度= 14, 11, 8bit/ 湿度= 14, 11bit を選択
      SHT31 :16bit(温湿度共)

   D I2C転送速度
      HDC1000:最大400kHz
      SHT31 :最大1MHz

   E I2Cアドレス
      HDC1000:0x40
      SHT31 :0x45(ADR= open)/ 0x44(ADR= gnd)

   F 測定精度
      HDC1000:温度= -20℃〜 +85℃、±0.2℃/ 相対湿度= 0% 〜 100%(無結露状態)±3% 
      SHT31 :温度= -40℃〜 +125℃、±0.2℃ (@0℃〜 90℃)/ 相対湿度= 0% 〜 100%、±2% (@0℃〜 90℃)

    G 消費電流
      HDC1000:スリープモード時の消費電流200nA(HDC1000本体の消費電流)
             − 820nA@1秒1回サンプリング、11ビット相対湿度計測
             − 1.2uA@1秒1回サンプリング、11ビット温度、相対湿度計測
      SHT31 :800μA (測定時)
            2μA@温湿度測定/秒 (平均、測定/1秒時)
            0.2μA@アイドル時 (シングルショットモード)

  ※ その他、SHT31のみに記載があった項目
     @ 反応時間(τ63%):2 秒[ 温度]、8 秒[ 湿度]
     A 長期安定度:0.03℃/ 年[ 温度]、0.25%RH/ 年[ 湿度]


■ 2022.10.3
  ・
SHT31のライブラリを検討してみた。
   現在HDC1000のライブラリは「きむ茶工房」さんの、PIC16F用のライブラリ:skHDC.c/ skHDC.hを
   PIC24F用に改修して作成している。
   SHT31のライブラリも、PIC16F用のライブラリ:skSHT3x.c/ skHDC.hとして掲載されていたので
   同様に、PIC24F用に改修して作成しようと思う。


■ 2022.10.4
  ・
SHT31のライブラリを検討してみた_2
   @ I2Cライブラリは以前の_TEST_6のもので動きそうなのでそのまま使う。
      (バージョンは、V3.00。現在は、UPされており、Cライブラリ:V3.20、Hライブラリ:V3.21となっているが
      様々なハードに対応出来る用に、#if defで設定定義されているので非常に解り難いし、前バージョン_TEST_6
      のソースを極力崩さない形にしたいのでI2Cライブラリは以前の_TEST_6のものを使用。)

    A _TEST_6のシステムクロックの定義は、QVGA液晶ライブラリの、hファイルで行い cファイルの中で、遅延関数が用意されているので、これを使う。


■ 2022.10.5
  ・
イニシャル時の各センサーのIDチェックについて
   TEST_6では、HD1000(温湿度)とLPS25H(気圧)のIDを読込んでIDが正しいかチェックしているが
   TEST_7の温湿度センサー:SHT31にはIDその物が無く上記のチェック方法では判断出来ない。
   I2Cの初期化をした際のバスの衝突等のチェック結果で判断するしかないが、
   元々_TEST_6の、エラーチェック無しのI2C関数を使っているので、今回は手抜きであるが簡易的に気圧センサーのみチェックすることにした。


■ 2022.10.6
  ・
SHT31は「単発測定モード」で良さそう。
  ・一応ソース改修してコンパイルしてみたが以下のエラー発生
skSHT3x_PIC24F.o(.nbss+0x6):C:\work\PIC24F_QVGA_TmpHumPres_TEST_7\skSHT3x_PIC24F.c: multiple definition of `Temp'
PIC24F_QVGA_TmpHumPres_TEST_7.o(.nbss+0x4):C:\work\PIC24F_QVGA_TmpHumPres_TEST_7\PIC24F_QVGA_TmpHumPres_TEST_7.c: first defined here
skSHT3x_PIC24F.o(.nbss+0x2):C:\work\PIC24F_QVGA_TmpHumPres_TEST_7\skSHT3x_PIC24F.c: multiple definition of `Humi'
PIC24F_QVGA_TmpHumPres_TEST_7.o(.nbss+0x0):C:\work\PIC24F_QVGA_TmpHumPres_TEST_7\PIC24F_QVGA_TmpHumPres_TEST_7.c: first defined here
c:\program files (x86)\microchip\mplab c30\bin\bin\..\bin/pic30-coff-ld.exe: Link terminated due to previous error(s).
Link step failed.

→ TempとHumiが2重定義されている旨のエラーと思われる。

<調査開始>
 @ 「きむ茶工房」さんのサンプルソースのこの部分はどうなっているか?

skSHT3x.hの中で
float Humidity ; // 湿度の値を保存する変数
float Temperature ; // 温度の値を保存する変数
と宣言

//// skSHT3x.hの中で以下の関数をプロトタイプ宣言
int SHT3x_MeasureRead(int mode)
{
    int ans ;
    unsigned int data[6] ;

    ans = I2C_Start(Sensor_adrs,RW_0); // スタートコンディションを発行する
    if (ans == 0) {
        if (mode == SHT3X_ONCE_MODE) {
            // 単発測定コマンド(クロックストレッチ無効)を発行する
            I2C_Send(0x24) ; // MSBを送信する
            I2C_Send(0x00) ; // LSBを送信する
            __delay_ms(20) ; // 測定終了まで待つ
        } else {
            // 周期的連続測定コマンドを発行する
            I2C_Send(0xE0) ; // MSBを送信する
            I2C_Send(0x00) ; // LSBを送信する
        }
        // 測定値の読み込み
        ans = I2C_rStart(Sensor_adrs,RW_1) ; // リピート・スタートコンディションを発行する
        if (ans == 0) {
            // 温度読み込み
            data[0] = I2C_Receive(ACK) ; // HIGHバイト読出し
            data[1] = I2C_Receive(ACK) ; // LOWバイト読出し
            data[2] = I2C_Receive(ACK) ; // CRCバイト読出し(無チェック)
            // 湿度読み込み
            data[3] = I2C_Receive(ACK) ; // HIGHバイト読出し
            data[4] = I2C_Receive(ACK) ; // LOWバイト読出し
            data[5] = I2C_Receive(NOACK) ; // CRCバイト読出し(無チェック)
        }
    }
    I2C_Stop() ; // ストップコンディションを発行する
    // 測定データを物理量値へ換算する
    if (ans == 0) {
        data[2] = (data[0] << 8) | data[1] ;
        data[5] = (data[3] << 8) | data[4] ;

        Temperature = -45.0 + (175.0 * (float)data[2] / 65535.0) ; // ℃
        Humidity = (100.0 * (float)data[5]) / 65535.0 ; // %RH
    }

    return ans ;
}

SHT31_once.c(メインソース)の中で
#include "skSHT3x.h" // SHT31-DIS用関数ライブラリ

void main()
{
    while(1) {
        // 湿度センサーから単発測定モードで湿度・温度値を読出す
        ans = SHT3x_MeasureRead(SHT3X_ONCE_MODE) ;
         ・
         ・
         ・
       __delay_ms(1000) ;
    }
}

※ これと同じようにやっているはずだが? エラー?
  デバイス毎のコンパイラコントロールの違いか? 片やPIC16F 片やPIC24F

 A TEST_6でも同じようなエラーで悩んだ経験があった。
   その時と同じ対処にしてみた。

  <その時の対処>
   ・メインで、型宣言:double Temp
             double Humi

   ・メインに、ライブラリにあった当該関数をプロトコル宣言し、末尾に記述
   ・ライブラリの当該関数は削除(ヘッダーファイルからも)

   ・この他にもメインに移動しないとリンクエラーになる以下の箇所があった。
     @ ライブラリにあった
       void SHT3x_Init(int address)を削除(ヘッダーファイルからも)してメインに移動
       ライブラリの頭で宣言されていた
       static int Sensor_adrs ; // デバイスのI2Cアドレスを保存する変数 も削除し
       メインに移動→ 今日(221008)確認したら、移動していなかった。
               2重宣言には何故かならなかったので気が付かなかった。

  ※ この対処でコンパイルが通った。

  ・HDC1000モジュールを外し、SHT31モジュールにピンヘッダを半田付け後実装。

   hex書込み後動作確認開始
   まずは駄目。
   固定表示部を表示後、先に進まず。
   SHT31のpinをテスターでチェックした。
   VDD, GNDピンはOK 3.30Vが供給されている。
   ADRピンはオープンで内部プルアップされているので、3.27VでOK
   SDA,SCLピンはテスターでは判断できない。


■ 2022.10.8
  ・
static int Sensor_adrs ; // デバイスのI2Cアドレスを保存する変数も削除してみた。
   次のエラーが出た。
   skSHT3x_PIC24F.c:55: error: 'Sensor_adrs' undeclared (first use in this function)
   なのでこれは削除できない。

   それから、ライブラリにあった
   void SHT3x_Init(int address)も削除できない。

   つまり、221006時点のソースに戻すことになる。
   戻すが、一点修正が必要な個所発見。
   void SHT3x_Init(int address)の中の末尾にある
   return SHT3x_SoftRST() ;
   はエラー処理を無くしたので、
   SHT3x_SoftRST() ;
   だけで良い。
   この修正を加えてみる。

 ・この修正をしてみたが
  double Temp
  double Humi
  の2重定義エラーがまた出る。
  そこで、メインに、SFT31ライブラリにあったSHT3x_MeasureRead(int mode)関数をプロトコル宣言し、末尾に記述、
  ライブラリの当該関数は削除(ヘッダーファイルからも)
  それだけではなく末尾に記述した関数中に記述した以下朱書きNOTE1,NOTE2の2点修正(修正しないと、相変わらずSensor_adrsが宣言されてないと言われる)
  これでリンクが取れ、SHT3x_Init(int address)問題も含めコンパイルが通った。

void SHT3x_MeasureRead(int mode)
{
    unsigned int data[6] ;

    // I2C_Start(Sensor_adrs,RW_0); // スタートコンディションを発行する
    I2C_Start(SHT31_ADRS,RW_0);     //  ※ NOTE1:スタートコンディションを発行する。 Sensor_adrsを使わずダイレクト指定 221008
    if (mode == SHT3X_ONCE_MODE) {
        // 単発測定コマンド(クロックストレッチ無効)を発行する
        I2C_Send(0x24) ; // MSBを送信する
        I2C_Send(0x00) ; // LSBを送信する
        delay_ms(20) ; // 測定終了まで待つ
    }
    else {
        // 周期的連続測定コマンドを発行する
        I2C_Send(0xE0) ; // MSBを送信する
        I2C_Send(0x00) ; // LSBを送信する
    }

    // 測定値の読み込み
    // I2C_rStart(Sensor_adrs,RW_1) ; // リピート・スタートコンディションを発行する
    I2C_rStart(SHT31_ADRS,RW_1) ;     // ※ NOTE2:リピート・スタートコンディションを発行する。 Sensor_adrsを使わずダイレクト指定 221008
     ・
     ・
}

※ これで一応動くようにはなった。
  温度は問題無し。
  湿度は今度は低目に出る。(針式と比較すると、BME280:-14%, SHT31:-22%)
  BME280= 65%/ SHT31= 57.15%/ 針式= 79%


■ 2022.10.9
  ・
湿度は今度は低目に出るが、高めになるよりは良い。
   梅雨時とか雨模様の時などは直ぐに、99.99%に張付くので。
   私が使用している針式の湿度計が、どれほどの信頼性があるか判らないが、これに比較すると-22%位低めに出る。
   しかし、BME280と比較すれば、-8%程度なので許せる範囲と言って良い。

  ・HDC1000が何時位から経年変化を起こしているか過去のドキュメントを調べてみた。
   最初に購入して実験テーマ83で実験したのは、2016/10/15で、58.50%を表示している写真が残っている。
   また実験テーマ85で実験したのは、2016/12/24で、53.88%を表示している写真が残っている。
   これ以降の実験結果は以下
   実験テーマ86:2017/1/11 54.21%
   実験テーマ87:2017/8/11 74.28%
           2018/1/23 67.17% 4年ぶりの関東平野大雪
           2019/10/13 76.12% 台風19号関東上陸
           2020/4/14 81.72% コロナ騒ぎの中、強風雨

   正しそうな表示値のようだ。
   ここまで購入から、約3.5年経過までは経年変化は、見られなかったと言ってよいと思う。
   去年当たりから高目に表示されてたと考えられる。


■ 2022.10.10
  ・
コメントアウト部など削除して、ソースを整理しといたので、そのhexファイルを書込んで、最終動作確認した。
   問題無く動いた。
   ここで再度、温湿度表示の証拠写真を撮ってみた。(丸1日エージングをした後なので、ちょっとは湿度センサーに変化があるのでは・・・)
   結果は、針式を基準に考えるとその差は、
BME280:-9%, SHT31:-13%
   BME280= 71%/ SHT31= 66.71%/ 針式= 80%



   少しは湿度センサーが外気に馴染んできたせいか、近似値にはなったと思う。
   後は、これで経年変化が無ければ良いのだが・・・
   様子見ということで、そろそろドキュメント整理に掛かりたい。


■ 2022.10.11
  ・
WEB情報
  <「JA0QON HomePage 実験・製作の記録」サイトより>
   ※ BME280= 47.5%
      SHT31= 44.1%

    → SHT31の方が低目に出るのは同じ。
       差は、-3.4%

     昨日の私の結果では、
     BME280= 71%
     SHT31= 66.71% 差:-4.29% まあ近い結果にはなっている。


■ 2023.1.25
  ・
センサーを交換してから約4ヶ月経過したところで本日の、測定結果を以下にアップした。
   昨日の夜9時頃から、全国的に大寒波が襲来してきて気圧は下がり湿度は上がり、温度は明け方に
   掛けて低くなって来た。
   問題の湿度だが異常に高くはなっていない。
   こんなもんだろう。
   OKということで・・・


<最終回路図>
 ・こちらから、どうぞ→ 「QVGA_グラフ表示温湿度・気圧計(AE-SHT31版) TEST_7基板」


<最終ソース及びヘッダファイル>
 ・こちらから、どうぞ→ 「PIC24F_QVGA_TmpHumPres_TEST_7.c」 (メインソース)

                 /// I2Cライブラリ
                 「skI2C_PIC24F_lib.c」
                 「skI2C_PIC24F_lib.h」

                 /// SHT31ライブラリ
                 「skSHT3x_PIC24F.c」
                 「skSHT3x_PIC24F.h」

                 /// LPS25Hライブラリ
                 「skLPS25H_PIC24F.c」
                 「skLPC25H_PIC24F.h」

                 /// QVGAカラー液晶ライブラリ: dsPIC33Fの物を、PIC24F用に一部修正しましたが、名前は、そのままにしました。
                 colorlcd_libdsPICVH.c
                 colorlcd_libdsPICVH.h

                 /// アスキーフォント
                 ASCII12dot.h


← 実験テーマ1に戻る   TOP PAGEに戻る   実験テーマ138へ →