今から始める電子工作 ⑭ I2Cバス その1-1 温湿度センサSHT45 + OLEDグラフィック・ボード

 いろいろなバスの中で、一番手軽に利用できるI2Cバスの利用を始めました。

   今から始める電子工作 ⑫ データを表示する その2 OLEDディスプレイ

 バスは、複数のデバイスをつないで利用できます。今回、温湿度センサのSHT45を利用します。

環境

  • Arduino IDE;2.3.4
  • Windows11;23H2
  • Arduino UNO R4 WiFi 

SHT45のおもなスペック

  • 湿度 ±1% typ(25~75%)
  • 温度 ±0.1 °C typ(0~75 °C)
  • 供給電圧 1.08~3.6V
  • インターフェース I2C(0~400kHz)
  • スレーブ・アドレス 0x44(固定)

(typはtypicalの省略形で、代表的は値を示している)

接続

 温湿度センサSHT45は、AdafruitのStemma QT/Qwiicボードを利用します。

  Adafruit Sensirion SHT45 Precision Temperature & Humidity Sensor - STEMMA QT / Qwiic

  このボードは、3.3/5Vの両方の電源電圧に対応しており、信号もレベル・シフト回路が入っているので、3.3/5Vのどちらのロジック電圧でも利用できます。

 Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。

 コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。

 OLEDグラフィック・ボード(裏面)にもコネクタが2か所ついています。

 4線のケーブルでつなぎます。プルアップ抵抗は、どちらのボードも切り離していません。

I2Cデバイスはスレーブ・アドレスで区別される

 バスにつながれたデバイスは、バスを監視しています。自分のスレーブ・アドレスがバスに現れると、やり取りを始めます。なので、スレーブ・アドレスがどのデバイスも異なっていなければなりません。

 つながっているデバイスのスレーブ・アドレスが、デバイスのスペックに書かれています。また、i2cScannerと呼ばれるスケッチを利用して表示できますが、多くがWire1に対応していません。古くから、Arduino DUEというマイコン・ボードには二つのI2Cバスがあったので、このボードに対応したスケッチを探します。

  How to Scan and Detect I2C Addresses

 このサイトにある I2C scanner sketch をArduino IDEにコピペし、説明にあるように、

  #define WIRE Wire1

の1行を修正し保存します。i2cScannerという名前にして保存しました。

  実行します。

 二つのスレーブ・アドレスを見つけてきました。0x3DがOLEDグラフィック・ディスプレイ、0x44が温湿度センサSHT45です。

専用のライブラリを利用

 温湿度センサSHT45は、専用のライブラリを利用します。SHT4xという表現が出てきますが、これは、SensirionのSHT40/41/45が同じようにI2Cバスでアクセスできるために、つけられた名称です。

 ライブラリの検索欄に「SHT4x」と入れると、複数のライブラリが検出します。画面下のほうにSensirionの純正ライブラリが見えていますが、ここは、Adafruit SHT4x Libraryをインストールします。

 インストールの途中、必要な追加のライブラリのパネルが出るので、全てをインストールします。

 サンプル例をインストールします。

  スケッチ例->Adafruit SHT4x Library -> SHT4test

 このままだと、QWIICでないほうのI2Cバスになってしまうので、22行目の、sht4.begin()を修正します。

  if (! sht4.begin(&Wire1)) {

 実行します。

測定値をOLEグラフィック・ディスプレイに表示

 上記のスケッチを、温湿度を読む部分を関数にしました。

#include "Adafruit_SHT4x.h"

Adafruit_SHT4x sht4 = Adafruit_SHT4x();
sensors_event_t humidity, temp;

void setup() {
  Serial.begin(115200);
  delay(1000); 
  Serial.println("Adafruit SHT4x read");
  if (! sht4.begin(&Wire1)) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);

  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  sht4.setHeater(SHT4X_NO_HEATER);
}

void readData(){
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
}

void loop() {
  readData();
  Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");
  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
  Serial.println("");
  delay(1000);
}

 前回の最後のOLEグラフィック・ディスプレイに電圧を表示するところを、温湿度に変更しました。

#include "Adafruit_SHT4x.h"
#include  <SparkFun_Qwiic_OLED.h> 

Adafruit_SHT4x sht4 = Adafruit_SHT4x();
sensors_event_t humidity, temp;
Qwiic1in3OLED myOLED;

void setup() {
  Serial.begin(115200);
  delay(1000); 
  Serial.println("Adafruit SHT4x read OLED Display");
  if (! sht4.begin(&Wire1)) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);

  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  sht4.setHeater(SHT4X_NO_HEATER);

  Wire1.begin();
      if (myOLED.begin(Wire1) == false){
        Serial.println("Device begin failed. Freezing...");
        while (true) ;
    }
  Serial.println("OLED Begin success");
  myOLED.rectangleFill(4, 4, myOLED.getWidth() - 8, myOLED.getHeight() - 8);
 
    String hello = "SHT45 Temperature & "; // top line message
    String hello1 = "Humidity";
    // Draw the text - color of black (0)
    myOLED.text(5, 5, hello, 0);
    myOLED.text(42, 15, hello1, 0);
    myOLED.display();
}

void readData(){
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
}

void loop() {
  readData();
  Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");
  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
  Serial.println("");

  String temp0 = (String)(temp.temperature);
  String humi0 = (String)(humidity.relative_humidity);
    myOLED.rectangleFill(4, 24, 50, 20, 1); 
    myOLED.text(5, 25, temp0, 0);
    myOLED.text(5, 35, humi0, 0);
    myOLED.display();

  delay(1000);
}

 実行します。

前へ

今から始める電子工作 ⑬ データを表示する その3 OLEDディスプレイの描画コマンド

次へ

今から始める電子工作 ⑮ I2Cバス その1-2 温湿度センサSHT45 + OLEDグラフィック・ボード