matlabでArduinoからデータを持ってくる①I2C

　温度、湿度、気圧、などいろいろな物理情報を得るにはセンサを使います。多くの事象はゆっくり変化するので、データの転送は急ぎません。センサICの多くはI2CもしくはSPIです。I2Cと言っても、メーカによってレジスタなどの構成が異なり、簡単にデータを読み出せないこともあります。
　気圧センサは、その昔、10個近い補正データを生で出力してきたので、受け取るデータの項目も多く、演算も簡単に処理できませんでした（[5ドル！ラズパイ・ゼロ（Raspberry pi Zero）でIoT　(40)　気圧センサ2　SPI MPL115A1](https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot402spi-mpl115a1.html)）。
　ボッシュのBME280（[SpresenseでLチカから始める (24) Wireライブラリ 温度気圧BMP280](https://www.denshi.club/cookbook/arduino/spresense/spresensel-24-wire.html)）などは、補正データも少なくなり、扱いやすくなりました。ここで使用するSTマイクロのLPS25は、24ビット・データを読み出したら、4096で割るだけで、hPaの気圧データが得られます。
###気圧センサLPS25HBの特徴
　ICは手はんだしずらい形状なので、秋月電子通商から[ブレークアウト・ボード](http://akizukidenshi.com/catalog/g/gK-13460/)を入手しました。

<img width="250" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b3d6b57b-c60a-70dc-b65e-a36c28c31cb0.png">





- 動作電圧　3.3V（デバイスは1.7～3.6 V）
- 消費電流　約2mA（LED分を含む。ハイレゾ、1Hz測定間隔時25uA）
- 測定範囲　260～1260hPa
- 確度　±0.1hPa（25℃）、±1hPa（0～80℃）
- インターフェース　SPI、I2C。I2C用プルアップ抵抗は実装、デフォルトは切り離し
 
　ボードの[AE-LPS25HB取扱説明書](http://akizukidenshi.com/download/ds/akizuki/ae-lps25hb.pdf)から、CS（5ピン）を VDD に接続してI2Cを利用します。SA0（4 ピン）をVddにつなぎ、スレーブ・アドレスを0x5dにします。
###マイコンはMKRZero
　matlabのアドオンMATLAB Support Package for Arduino Hardware（無償で使える）は、Matalbを起動しているときに、ArduinoをUSBケーブルで挿したら検出され、メッセージの通りにインストールします。
　情報は、アドオンマネージャの管理を立ち上げ、MATLAB Support Package for Arduino Hardwareのドキュメンテーションをクリックします。
![スクリーンショット 2020-07-23 07.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/7e87fc74-0391-3073-4df8-bde39776e99b.png)

　Examplesのタブが見えています。Functionsのタブに、利用できる関数一覧があります。
　MKRZeroは、Cortex-M0（アトメルSAMD21）を搭載した幅の狭いMKRシリーズの一つで、無線の機能がありません。Arduino UNOより[価格は安い](http://akizukidenshi.com/catalog/g/gM-13031/)です。メモリも比較的多いので、利用上のストレスは少ないです。
![IMG_1398.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/5808cb84-2a04-fa24-1a41-ca467cf3e7d4.png)

　R2019bから[サポート](https://jp.mathworks.com/hardware-support/arduino-matlab.html)されています。Wi-FiやBLEが使えるモデルはありますが、現時点で、無線はサポートされていないようです。BLEは、別途BLEボードをシリアル（UART）でつなぐ方法のようです。
　現在コスト・パフォーマンスがよいので利用が多いESP32ボードもサポートされていないようです。
###配線とプログラミングのスタート
　先ほどのドキュメンテーションのExamplesから「I2C Devices — Examples」を選べばいいのですが、SPIを選んでしまいました。そのまま進めます。それぞれのExamplesの右下のOpen Live Scriptをクリックすると、ライブエディタが開きます。

　AE-LPS25HBボードの裏側で、I2C信号のプルアップ抵抗を有効にするため、J1、J2のランドをはんだをもってショートします。AE-LPS25HBボードの1ピンVDDをMKRZeroのVCCへ、8ピンGNDはGNDへ、2ピンSCLはSCLへ、3ピンSDAはSDAへつなぎます。合計4本です。
![IMG_1377.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/04ba6cb1-6f11-bf71-c353-8704299df60a.png)


　初期設定部分です。

```matlab
clear all
a = arduino('COM10', 'MKRZero', 'Libraries', 'I2C');
LPS25 = device(a, 'I2CAddress', 0x5d, 'BitRate', 400000); % 4pin-Vcc
```


　最近まで、パラメータは10進で渡す記述だったのですが、今は16進が直接書けます。
　最初に、スリープしているので、0x20レジスタに0x90を書き込みます。
　単純に**気圧press**は、0x28レジスタから3バイトを読みますが、うまく読めません。GitHubにあるいろいろなソースを読むと、0x28 | 0x80で正しく読めるようです。
　**温度temp**のデータは読み出した後の計算方法の説明が見当たりません。秋月の[補足説明](http://akizukidenshi.com/download/ds/akizuki/lps25_appendix.pdf)の計算式を利用しました。しかし、相当変な温度データを読み出します。
　気圧から**高度altitude**を求めていますが、基準となる海面の気圧、温度が大幅に変化することから、実用化は、もっと工夫しないといけないです。温度は急には変わりませんし、測定前に高度をリセットすれば、絶対的な高さの変化は求まります。分解能は24ビットなので、階段の段差も測定できるかもしれません。
　countsは測定回数です。
data=のところは間違っています。グラフはこのままでは正しく描画できません。後で修正します。

```matlab
data=[];
counts = 100;
writeRegister(LPS25, 0x20, 0x90, 'uint8')
pause(0.5);
for i=1:counts
    PRESS_OUT = bitor(0x28, 0x80);
    write(LPS25, PRESS_OUT, 'uint8')
    RegisterData = read(LPS25, 3, 'uint8');
    % fprintf('\nread data  is %d \n', RegisterData);
    press = (double(bitshift(RegisterData(3), 16)) + double(bitshift(RegisterData(2), 8)) + double(RegisterData(1))) / 4096;
    % fprintf('\nLPS25HB %.3f hPa ', press);
    TEMP_OUT = 0x2b;
    write(LPS25, TEMP_OUT, 'uint8')
    RegisterDatat = read(LPS25, 2, 'uint8');
    %fprintf(' read data  is %d \n', RegisterDatat);
    temp = (double(bitshift(RegisterDatat(2), 8)) + double(RegisterDatat(1)))/480 + 42.5;
    %fprintf('  %.1f C ', temp);
    altitude = ((power((1013.25 / press), (1 / 5.257)) - 1) * (temp + 273.15)) / 0.0065;
    %fprintf('  %.3f m\n', altitude);
    fprintf('\nLPS25HB %.3fhPa  %.3fm  %.1f C ', press, altitude, temp);
    data = altitude;
    pause(0.1);
end
```

　グラフです。工夫してください。

```matlab
x = linspace(1, counts, counts);
plot(x, data, '-o')
```

　終了処理です。

```
clear a
```