6
2

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 1 year has passed since last update.

SimulinkでCO2センサのSCD30を動かす

Last updated at Posted at 2022-12-10

 Simulink Support Package for Raspberry Piをmatlabにインストールをして、ラズパイ4のI2CバスにAdafruitのSCD30センサ・ボードを接続しました。
ファイル名

環境

  • matlab home License R2022b update2
  • Simulink Support Package for Raspberry Pi Hardware バージョン22.2.0
  • Windows 10 Pro 22H2 メモリ40Gバイト
  • Raspberry Pi 4 Model B 2MB

 インストールは、次の記事を参照してください。
  Simulink Support Package for Raspberry Pi ① インストール

動作確認

 ライブラリを使わず(存在しない?)、レジスタをたたいてセンサのデータを得ます。下記のマニュアルを参照しました。
  Sensirion_CO2_Sensors_SCD30_Interface_Description.pdf
 動作を確認するため、CircuitPythonでアクセスしました。
  CircuitPython 10行プログラミング Step9 (7) CO2センサSCD30

プログラム

IEEE754 単精度浮動小数点数の形式:binary32 の実数への変換

 センサから読み取ったCO2、温度、湿度の値は、4バイトで構成されるbinary32の形式です。Pythonはstructのunpackで簡単に変換できます。
 simulinkのfunctionでは、
  matlab SimulinkのBLE functionを作ってみた その2 備忘録
でプログラムを実装しましたが、今現在、 extrinsic declarationsがエラーになってしまいます。そこで、ブロックを組み合わせて、サブシステムを作ります。
 この実数表現は、メモリの中では32ビットの領域を使います。

  • 符号ビット: 1ビット
  • 指数部の幅: 8ビット
  • 仮数部の幅: 23ビット

IEEE.png
  IEEE754 単精度浮動小数点数の形式:binary32 の変換

 この記事にあるように、共用体unionを使う方法、ポインタを使う方法がありますが、どうも、matlabでは実現できないようです。
 メーカのプログラムではunionを使っていました。
 そこで、オーソドックスに、符号、指数、仮数をそれぞれ計算して、最後に掛け合わせて実数に変換する方法をとりました。
 Arduinoだと、次のコードになります。iiがbinary32のデータです。

int8_t f = pow(-1, int(bitRead(ii,31)));
double  k = 1 + (double)((((ii<<1)<<8)>>9))/pow(2,23); 
float s = (float)pow(2,(int8_t)((uint8_t)((ii<<1)>>24)-127));
Serial.print("内部形式を実数に戻した ");Serial.println(f*k*s,6);

 ほぼ、上記のスケッチを実装しました。
  ウキ「単精度浮動小数点数」
も参考になります。
 動作を確認して、サブシステムにしました。
co104a.png

メインのプログラム

co104.png

 左上から、順にパラメタを示します。

co201.png

co202.png

co203.png

co204.png

co205.png

co206.png

co207.png

 functionです。18バイトを読み取り、2バイトごとにCRCが入っているので、そこをスキップして、4バイトごとにデータをまとめています。

function [c,t,h]= fcn(u)

persistent c1;
persistent c2;
persistent c3;
persistent c4;

persistent t1;
persistent t2;
persistent t3;
persistent t4;

persistent h1;
persistent h2;
persistent h3;
persistent h4;

c1=u(1)*256*256*256;
c2=u(2)*256*256;
c3=u(4)*256;
c4=u(5);
c = uint32(c1+c2+c3+c4);

t1=u(7)*256*256*256;
t2=u(8)*256*256;
t3=u(10)*256;
t4=u(11);
t = uint32(t1+t2+t3+t4);

h1=u(13)*256*256*256;
h2=u(14)*256*256;
h3=u(16)*256;
h4=u(17);
h = uint32(h1+h2+h3+h4);

配置と実行順

 試行錯誤していると、配置が乱雑になって、デバッグの情報のオーバーレイ、実行順序を実行すると、変な順番に並んでいることがあります。修正する方法がわからないので、あたらしい空のモデルを作り、順番にコピペしていきます。また、プロパティの優先順位も、順番に数値を振っておきます。
でも、readコマンドを送ったのに読み取りができないとかが起こることがあります。
 I2Cバスの転送速度は100kHzですが、50kHzに変更する方法を見つけていません。SCLクロック・ストレッチは実装されているようですが、時々変なデータ(0xff)を読むのは、クロックが早いのが理由かもしれません。

I2Cバスでの確認

image.png
 正しいデータが読めていませんが、シーケンスは正しい順番で実行されています。
image.png
 このデバイス、ヒータがあるのが理由かもしれませんが、1か月ほど連続使用したら、読み出した値がおかしくなっていました。
 その後、電源を入れて数分は正常な値が返えることが多くあります。壊れかけのようです。

6
2
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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?