matlabでBLEを使う④SHT31-SMART-GADGET

　温湿度センサSHT31とLCD、BLEを搭載したボードが、デバイス・メーカ自身センシリオンから販売されています。Digi-KeyやMouserで購入できますが、送料を考慮し、マルツで入手しました。【SHT31-SMART-GADGET】Sensirion 温度 / 湿度センサ（3,140円）BLEモジュールには技適のマークが印刷されています。
　データシートは[同社のダウンロードセンター](https://www.sensirion.com/jp/download-center/humidity-sensors/development-kit/)から入手できます。UUIDの構成は、[GitHubにありました](https://github.com/Sensirion/SmartGadget-Firmware/blob/master/Simple_BLE_Profile_Description.pdf)。
![IMG_3951.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/faf2b6cb-5693-3293-6ac2-bdea6abd0a3a.jpeg)


# 起動
　ボード上にはCR2032電池があって、絶縁シートが挟まれているので抜きます。動き出します。タクト・スイッチをクリックすると表示が変わります。ダブルクリックすると、BLEが動き出しました。Bluetoothのアイコンが点滅している状態はアドバタイジングをしているようです。
# 見つける

```matlab
clear
scan = blelist("Timeout", 20);
```

でscanします。10秒だと見つけられませんでした。

```matlab
SHT31_address = "Smart Humigadget"
b = ble(SHT31_address);
bb = b.Characteristics;
```

scanの値を見ます。1個しかないのでnameでアクセスします。複数同時に使うならaddressでアクセスします。
bbの値を見ます。GitHubにあるUUIDの図と同じ情報が見れます。
![スクリーンショット 2020-06-25 07.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/77d0c8a1-84a3-f667-794c-9a841e0aa20c.png)



　読み出す温湿度データのサービスとキャラクトリスティックは次の四つのUUIDです。

```matlab
SHT31_Humi_ServiceUUID = "00001234-B38D-4985-720E-0F993A68EE41" ;
SHT31_Temp_ServiceUUID = "00002234-B38D-4985-720E-0F993A68EE41" ;
bb18_CharacteristicUUID = "00001235-B38D-4985-720E-0F993A68EE41" ;
bb19_CharacteristicUUID = "00002235-B38D-4985-720E-0F993A68EE41" ;
```

# 温度と湿度を読み出す
　データシートのロギングのところに値はfloat32と書かれています。固定小数点形式の4バイトです。matlabの関数を探すとhex2numが使えそうでしたが、だめでした。倍精度だけを対象としています。そこで、単精度用処理関数を作りました。
　読み出したデータは10進なので2進に変更し、1バイト＝8桁の文字列にします。リトルエンディアンなので、逆順で結合して32ビットの文字列を作ります。次の図は、単精度浮動小数点IEEE 754-2008のフォーマットです。
![IEEE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/e9785fe4-29fe-a726-0c15-43e5424217c1.png)
　最上位ビットは符号です。次は指数です。22ビットから0ビットが仮数ですが、暗黙のビットが最上位にあるので、実際は24ビットです。
　関数はhex2numSという名前にしました。matlabは、それまでシフトJISでしたが、2020バージョンからUTF-8になったそうです。コメントを日本語で書いても文字化けの心配はありません。


```matlab
function  shortF = hex2numS(decimal4)
    data11 = num2str( dec2bin( decimal4(1),8  ));
    data12 = num2str( dec2bin( decimal4(2),8  ));
    data13 = num2str( dec2bin( decimal4(3),8  ));
    data14 = num2str( dec2bin( decimal4(4),8  ));
    data111 = strcat(data14,data13,data12,data11);
 
    f = (-1)^str2num(data111(1));        % 符号
 
    sisuu = data111(2:1:9);
    kasuu = ("1"+data111(10:1:end));
    k = bin2dec(kasuu)/(2^23) ;          % 仮数
    s = 2 ^ (bin2dec(sisuu) -127) ;      % 指数
 
    shortF = f * k * s;
 end
```
参考資料；[単精度浮動小数点数](https://ja.wikipedia.org/wiki/%E5%8D%98%E7%B2%BE%E5%BA%A6%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0)
[IEEE単精度実数形式から10進数への変換](https://ja.stackoverflow.com/questions/46870/ieee%e5%8d%98%e7%b2%be%e5%ba%a6%e5%ae%9f%e6%95%b0%e5%bd%a2%e5%bc%8f%e3%81%8b%e3%82%8910%e9%80%b2%e6%95%b0%e3%81%b8%e3%81%ae%e5%a4%89%e6%8f%9b)
[Pythonで浮動小数点数floatと16進数表現の文字列を相互に変換](https://note.nkmk.me/python-float-hex/)
[Floating Point to Hex Converter](https://gregstoll.dyndns.org/~gregstoll/floattohex/)

# グラフを描く
　2軸のグラフにしました。
![スクリーンショット 2020-06-24 18.58.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/9812893d-bed4-3d2d-88f1-9f09f716425f.png)


# 全体のプログラム

```matlab
clear
scan = blelist("Timeout", 20);
SHT31_address = "Smart Humigadget"
b = ble(SHT31_address);
% bb = b.Characteristics;

SHT31_Humi_ServiceUUID  = "00001234-B38D-4985-720E-0F993A68EE41" ;
SHT31_Temp_ServiceUUID  = "00002234-B38D-4985-720E-0F993A68EE41" ;
bb18_CharacteristicUUID = "00001235-B38D-4985-720E-0F993A68EE41" ;
bb19_CharacteristicUUID = "00002235-B38D-4985-720E-0F993A68EE41" ;
temperature = [];
humidity = [];
count = 20;
c18 = characteristic(b, SHT31_Humi_ServiceUUID, bb18_CharacteristicUUID);
c19 = characteristic(b, SHT31_Temp_ServiceUUID, bb19_CharacteristicUUID);

for i = 1:count
    humidity(i) =  hex2numS(read(c18));
    temperature(i) = hex2numS(read(c19));
    pause(1)
end

figure
x=[1:count];
yyaxis left
plot(x, temperature,'-o')
ylabel('Temp[C]')
yyaxis right
plot(x, humidity, '-x')
ylabel('Humi[RH]')
title('SHT31 temperature &  humidity')
xlabel('x')

grid on

 function  shortF = hex2numS(decimal4)
    data11 = num2str( dec2bin( decimal4(1),8  ));
    data12 = num2str( dec2bin( decimal4(2),8  ));
    data13 = num2str( dec2bin( decimal4(3),8  ));
    data14 = num2str( dec2bin( decimal4(4),8  ));
    data111 = strcat(data14,data13,data12,data11);
 
    f = (-1)^str2num(data111(1));        % 符号
 
    sisuu = data111(2:1:9);
    kasuu = ("1"+data111(10:1:end));
    k = bin2dec(kasuu)/(2^23) ;          % 仮数
    s = 2 ^ (bin2dec(sisuu) -127) ;      % 指数
 
    shortF = f * k * s;
 end
```
　20回の測定をしています。