エンジニア風味 (Engineer-taste)

電子系エンジニアのメモ帳

気圧センサSCP1000-D01にMATLABからArduino経由でアクセスする(SPI通信)

前に気圧センサMPL112A2をArduino経由でMATLABのアドオンからアクセスする記事を書きました。
あれは、インターフェースがI2Cでの通信でしたが、今回のSCP1000-D01はSPIでの通信です。
UnoとSCP1000の接続は下記のようにしました。SCP1000-D01は秋月電子のモジュールを用いました。
SCP1000は電源電圧が5Vでは使えないので3.3Vで使います。データ&クロックも間にレベル変換器を入れてあります。

f:id:engineer-paju:20190321103343p:plain
SCP1000-D01の接続

% arduinoオブジェクトを作る。COMポートは6、ArduinoはUnoを使っているとする
%(適宜変更してください) 
a=arduino('COM6','Uno','Libraries','SPI');

% SCP1000のデバイスセレクトがD10pinに接続されている。
% クロックモードは0(CLKは通常0で、CLKの立ち上がりエッジでデータを取り込む)
% シリアル出力はMSBが先で、最後がLSB
% 転送レートは400k
SCP1000=spidev(a,'D10','mode',0,'bitorder','msbfirst','bitrate',4000000);

% ソフトウェアリセットをかけてみる(必要ないかも)
writeRead(SCP1000, [4*hex2dec('06')+2, 1], 'uint8');
pause(0.5);
FF=0;
Fnum=0;
% リセット状態から復帰したかを調べる
while (FF ~= 0 && Fnum<6)
    F=writeRead(SCP1000, [4*hex2dec('07'), zeros(1,1)], 'uint8');
    FF=double(F(2))
    pause(1);
    Fnum=Fnum+1;
end

% 高精度(17bit)気圧出力モードを指定
writeRead(SCP1000, [hex2dec('0e'), hex2dec('0a')], 'uint8');
pause(2);

% 温度データを取得
T=writeRead(SCP1000, [4*hex2dec('21'), zeros(1,2)], 'uint8');

% 気圧データのMSB3ビットを取得
PM=writeRead(SCP1000, [4*hex2dec('1f'), zeros(1,1)], 'uint8');

% 気圧データの残りを取得
PL=writeRead(SCP1000, [4*hex2dec('20'), zeros(1,2)], 'uint8');

% 気温データの符号(0℃より大きいか小さいか)を取得
Sn=double(bitshift(T(2),-5));

% 気温データ部分を切り出す
T(2)=bitand(T(2),31);

% uint8のデータをdoubleに変換。uint8のまま使うと0~255までしか演算されない
TT=double(T);

% 気温データに換算
Temp=(TT(2)*256+TT(3))*0.05*(-1)^Sn;

% 気圧データに換算
PMM=double(bitand(PM(2),7));
PLL=(256*double(PL(2))+double(PL(3)));
Press=(PMM*256*256+PLL)/400;

% 表示
fprintf('気温: %.1f [℃]\n',Temp);
fprintf('気圧: %.1f [hPa]\n',Press);
pause(0.5);

% デバイス消去
clear SCP1000 a;

MATLABアドオンのSPI関係のコマンドは、spidev と writeRead しかないようです。
SPIデバイスへの書き込みは、8bitを1ブロックとし、ブロックの数だけ行われ、同じ数だけの戻り値が返ってきます。
なので、例えば気温を取得するときには、3つの戻り値のうちの1つ目は捨てて、2つめ、3つめから温度に換算します。