Arduino MKR WiFi 1010をデータ入力に使う⑨I2C温湿度センサSHTC3

 前回の温湿度センサHTS221は、ライブラリが入っていたので、すぐに使えました。Sensirionの温湿度センサSHT3Cは、Sensirionの温湿度センサSHT31などとほぼ同じに使えます。Adafruitのブレークアウト・ボードを入手しました。

  SHTC3 SHT31
電源電圧[V] 1.62~3.6 2.15~5.5
消費電流[uA] アイドル時45(typ)、測定時430(typ) アイドル時0.2(typ)、測定時600(typ)
湿度[%RH] 確度±2、分解能0.01 確度±2、分解能0.01
温度[℃] 確度±0.2(0~90)、分解能0.01 確度±0.2(0~60)、分解能0.01
外形[mm] 2×2×0.75 2.5×2.5×0.9

 ボードには、5V->3.3Vのレギュレータと3.3<->5V信号レベル変換回路が入っています。4ピンのコネクタ(I2C)でArduino MKR WiFi 1010と接続します。第4回の気圧センサLPS25HBの接続と同じです。

 裏面に印刷してあるように、アドレスは0x70です。

プログラム-step1

 このデバイスは、電源が入ったのちスリープします。プログラムの最初に起こします。

 I2CのクロックSCLをLowにしたまま時間を稼ぐクロック・ストレッチを利用できますが、ここでは、配線の距離が短いので使いません。送られるデータを、湿度、温度の順にするコマンドが0x58E0です。

 readで6バイト読んできます。最初の2バイトが湿度データで、そのCRCが3バイト目に入っています。次の2バイトが温度で、そのCRCが6バイト目に入っています。

 とりあえず、CRCは無視します。データシートに書かれている換算式で、湿度と温度を得ます。


clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
shtc3 = device(a, 'I2CAddress', 0x70);

wakeup    = [0x35,0x17];
write(shtc3, wakeup, 'uint8');

Measurement_H = [0x58,0xE0];  % no clockstretch,Humi first read
write(shtc3, Measurement_H, 'uint8');
rdata = read(shtc3, 6, 'uint8')

sleep = [0xB0,0x98];
write(shtc3, sleep, 'uint8');

    humi =  double(bitshift(uint16(rdata(1)), 8)) + double(rdata(2));
    RH = 100 * humi / 65535
    tempT =  double(bitshift(uint16(rdata(4)), 8)) + double(rdata(5));
    temperature = -45 + tempT * 175 / 65535

 実行結果です。

プログラム-step2

 CRCの計算をして、測定値と比較します。

 CRCの計算は関数にしました。


clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
shtc3 = device(a, 'I2CAddress', 0x70);

wakeup = [0x35,0x17];
write(shtc3, wakeup, 'uint8');

Measurement_H = [0x58,0xE0];  % no clockstretch,Humi first read
write(shtc3, Measurement_H, 'uint8');
rdata = read(shtc3, 6, 'uint8');

sleep = [0xB0,0x98];
write(shtc3, sleep, 'uint8');

    humi =  double(bitshift(uint16(rdata(1)), 8)) + double(rdata(2));
    RH = 100 * humi / 65535;
    tempT =  double(bitshift(uint16(rdata(4)), 8)) + double(rdata(5));
    temperature = -45 + tempT * 175 / 65535;
    fprintf('    humidity=%.1fRH   readCRC= 0x%s 0x%s <-calcCRC' ...
        , RH, dec2hex(rdata(3)), dec2hex(CRC8(humi)) );
    fprintf(' temperature=%.2f`C  readCRC= 0x%s 0x%s <-calcCRC' ...
        , temperature, dec2hex(rdata(6)), dec2hex(CRC8(tempT)) );
    

 function [data] = CRC8(inputData)
% CRC-8 Dallas/Maxim/AnalogDevices
% x^8+X^5+X^4+1. X=2, Polynomial=0x131=[1 0 0 1 1 0 0 0 1]
% 初期化(InitialConditions)=0xff 反射入力(ReflectInputBytes)=false 
% 反射出力(ReflectChecksums)=false 最終XOR(FinalXOR)=0x00

    Polynomial = 0x131;
    initialConditions = 0xff00;
    % init XOR
    data = bitxor(inputData,  initialConditions);
    Polynomial = uint32(Polynomial);
    % '0000000' zero padding input data
    data = bitshift(uint32(data),8);

    for i = 1:12
        length_data = length(de2bi(data, 'left-msb'));
        if length_data < 9  % 8ビット
            break
        end
        length_Polynomial = length(de2bi(Polynomial, 'left-msb'));
        Polynomial = bitshift(Polynomial, length_data-length_Polynomial);
        data = bitxor(data, Polynomial);
    end
end

 実行結果です。

  CRCの計算で、ループを12回まわしていますが、終了条件の判断が甘く、余分にループが回り、まれに、計算を間違えることがあります。

プログラム-step3

 前回と同様にグラフを描きます。

 プログラムです。readの前に100msの時間をおいています。Measurementトリガのすぐ後に読み出すとエラーが出る場合がありました。


clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
shtc3 = device(a, 'I2CAddress', 0x70);

h = animatedline('MaximumNumPoints',20, 'Color', 'g', 'LineWidth', 2);
t = animatedline('MaximumNumPoints',20, 'Color', 'r', 'LineWidth', 2);

counter = 1:100;
RH = (counter);
temperature = (counter);
for k = counter
    wakeup = [0x35,0x17];
    write(shtc3, wakeup, 'uint8');
    Measurement_H = [0x58,0xE0];  % no clockstretch,Humi first read
    write(shtc3, Measurement_H, 'uint8');
    pause(0.1)
    rdata = read(shtc3, 6, 'uint8');
    humi =  double(bitshift(uint16(rdata(1)), 8)) + double(rdata(2));
    RH(k) = 100 * humi / 65535;
    addpoints(h, counter(k), RH(k));
    tempT =  double(bitshift(uint16(rdata(4)), 8)) + double(rdata(5));
    temperature(k) = -45 + tempT * 175 / 65535;
    addpoints(t, counter(k), temperature(k));
    
    drawnow
    pause(2);
    
    sleep = [0xB0,0x98];
    write(shtc3, sleep, 'uint8');
end

前へ

Arduino MKR WiFi 1010をデータ入力に使う⑧I2C温湿度センサHTS221

次へ

Arduino MKR WiFi 1010をデータ入力に使う⑩I2C温湿度センサAHT20