LoginSignup
1
1

More than 3 years have passed since last update.

matlabでラズパイにつないだ温湿度センサSHT31からデータをもってくる

Posted at

 こちらの記事でも使っていましたが、Sensirionの温湿度センサSHT31をラズパイにつないで温度と湿度をもってきます。
 I2Cインターフェースは10~20cm以内で使うものだと認識していましたが、写真のように、長めのケーブルが付いた製品が、アマゾンで入手できます。農業用などとコマーシャル・トークが書かれていますが、このデバイスは、雷に打たれ強いとは思われません。筐体に入れた製品が屋外で使う製品はたくさん市販されています。ケーブルを延長して利用するやり方には不安が残ります。
IMG_4827.png

SHT31のおもなスペック

  • 電源電圧;2.4~5.5V
  • インターフェース;I2C(最大データ転送速度1MHz)
  • 温度;-40~+125℃(確度±0.2℃)、分解能0.015℃
  • 相対湿度;0~100%(0~90℃時)、分解能0.01%
  • データ・ビット長;16ビット
  • スレーブ・アドレス;ADDRピンをプルアップで0x45、GNDへつなぐと0x44

 アマゾンから入手しました。
  防塵土壌デジタル温度湿度センサーステンレス鋼プラスチックハウジングI2C出力FS400-SHT3X高精度低消費(SHT31)

接続

 ケーブルの先はオスだったので、切り取り、メスのジャンパ・ケーブルを取り付けました。

SHT31ケーブル ラズパイ
赤色 3.3V 1番ピン
黒色 GND 9番ピン
青色 SDA 3番ピン
黄色 SCL 5番ピン

CRCデータも送られてくる

 設定用のコマンドを送るときには必要ありませんが、読み出したデータにはCRCのチェックサムがついています。無視してもかまいません。
 matlabには、CRCを計算する新旧二つの関数がありますが、うまく使えませんでした。なので、XORによる手計算を模してプログラムを作りました。処理速度は気にしていません。
 SHT31のデータシートによれば、初期値0xff、CRC-8の多項式はX^8+X^5+X^4+1、反射入力はfalse、反射出力はfalseなので、MSBfirstのデータです。最終XORは0x00なので、何もしません。この条件でプログラムを作りました。
 動作確認は、http://www.sunshine2k.de/coding/javascript/crc/crc_js.html で行いました。次の画面は、データシートに載っている0xBEEFを入れて、CRCデータ0x92を算出した様子です。
スクリーンショット 2020-10-31 15.27.34aa.png

まずスレーブ・アドレスを知る

clear all
rpi = raspi('192.168.111.114', 'pi', 'raspberry'); % host name raspberrypi-uMchsTIvew
for i = 1:length(rpi.AvailableI2CBuses)
    scanI2CBus(rpi, rpi.AvailableI2CBuses{i})
end

 0x44でした。

sht31D = i2cdev(rpi, 'i2c-1', '0x44');

 データシートの「表9 周期的連続測定コマンド」に書かれている設定コマンドを送ります。送るデータによっては、期待しないデータが送られてくる場合があります。ここでは、

  • 測定頻度[mps] (測定回数/秒)が4:0x23
  • 繰返し精度レベル 高い:0x34
Ctrl_OUT = [0x23,0x34]; 
write(sht31D, Ctrl_OUT, 'uint8');
pause(0.5);

本体です

 10回繰り返しました。

for i = 1:10
    Ctrl_OUT = [0xe0, 0]; 
    write(sht31D, Ctrl_OUT, 'uint8');
    rdata = readRegister(sht31D, 0, 6);  % 0=dummy
    tempT =  double(bitshift(uint16(rdata(1)), 8)) + double(rdata(2));
    temperature = -45 + tempT * 175 / 65535;
    humi =  double(bitshift(uint16(rdata(4)), 8)) + double(rdata(5));
    RH = 100 * humi / 65535;
    fprintf(' temperature=%.2f`C  readCRC= 0x%s 0x%s <-calcCRC', temperature, dec2hex(rdata(3)), dec2hex(CRC8(tempT)) );
    fprintf('    humidity=%.1fRH   readCRC= 0x%s 0x%s <-calcCRC', RH, dec2hex(rdata(6)), dec2hex(CRC8(humi)) );
    pause(1);
end

CRC関数です

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
%
    %inputData = 0xBEEF
    Polynomial = 0x131;
    initialConditions = 0xff00;
    % init XOR
    data = bitxor(inputData,  initialConditions);
    % fprintf('Get the xor of data and initialConditions %0s',dec2bin(data));

    Polynomial = uint32(Polynomial);
    % fprintf('CRC-8 Polynomial is %0s',dec2bin(Polynomial));

    % '0000000' zero padding input data
    data = bitshift(uint32(data),8);
    % fprintf('zero padding(8) -> 24bit data %0s',dec2bin(data));

    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'));
        % fprintf('zero padding input data       %0s',dec2bin(data));
        Polynomial = bitshift(Polynomial, length_data-length_Polynomial);
        data = bitxor(data, Polynomial);
        % fprintf('zero padding Polynomial       %0s', dec2bin(Polynomial));
        % fprintf('xor                           %0s    0x%x', dec2bin(data),data);
    end
    % fprintf('input=0x%x CRC=0x%x', inputData, data);
end

 実行例です。不一致だったら、再度読み込むという使いかただと思います。
スクリーンショット 2020-10-31 16.33.14.png

CRC 参考にしたところ

CRC(Cyclic Redundancy Check)の初期値とかシフト方向とか出力とか
Cyclic Redundancy Check(CRC)を理解する
CRC8 ATMの計算方法
2.CRC(巡回冗長検査・巡回冗長符号)
CRC(巡回冗長検査)で適正なデータ通信を実現

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1