4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-23

 温度、湿度、気圧、などいろいろな物理情報を得るにはセンサを使います。多くの事象はゆっくり変化するので、データの転送は急ぎません。センサICの多くはI2CもしくはSPIです。I2Cと言っても、メーカによってレジスタなどの構成が異なり、簡単にデータを読み出せないこともあります。
 気圧センサは、その昔、10個近い補正データを生で出力してきたので、受け取るデータの項目も多く、演算も簡単に処理できませんでした(5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (40) 気圧センサ2 SPI MPL115A1)。
 ボッシュのBME280(SpresenseでLチカから始める (24) Wireライブラリ 温度気圧BMP280)などは、補正データも少なくなり、扱いやすくなりました。ここで使用するSTマイクロのLPS25は、24ビット・データを読み出したら、4096で割るだけで、hPaの気圧データが得られます。

気圧センサLPS25HBの特徴

 ICは手はんだしずらい形状なので、秋月電子通商からブレークアウト・ボードを入手しました。

ファイル名
  • 動作電圧 3.3V(デバイスは1.7~3.6 V)
  • 消費電流 約2mA(LED分を含む。ハイレゾ、1Hz測定間隔時25uA)
  • 測定範囲 260~1260hPa
  • 確度 ±0.1hPa(25℃)、±1hPa(0~80℃)
  • インターフェース SPI、I2C。I2C用プルアップ抵抗は実装、デフォルトは切り離し

 ボードのAE-LPS25HB取扱説明書から、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

 Examplesのタブが見えています。Functionsのタブに、利用できる関数一覧があります。
 MKRZeroは、Cortex-M0(アトメルSAMD21)を搭載した幅の狭いMKRシリーズの一つで、無線の機能がありません。Arduino UNOより価格は安いです。メモリも比較的多いので、利用上のストレスは少ないです。
IMG_1398.png

 R2019bからサポートされています。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

 初期設定部分です。

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のデータは読み出した後の計算方法の説明が見当たりません。秋月の補足説明の計算式を利用しました。しかし、相当変な温度データを読み出します。
 気圧から高度altitudeを求めていますが、基準となる海面の気圧、温度が大幅に変化することから、実用化は、もっと工夫しないといけないです。温度は急には変わりませんし、測定前に高度をリセットすれば、絶対的な高さの変化は求まります。分解能は24ビットなので、階段の段差も測定できるかもしれません。
 countsは測定回数です。
data=のところは間違っています。グラフはこのままでは正しく描画できません。後で修正します。

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

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

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

 終了処理です。

clear a
4
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?