1
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からデータを持ってくる③SPI その2

Last updated at Posted at 2020-08-21

 前回は、泥縄的にA-DコンバータADS1256のプログラムを書きました。ここでは、レジスタの読み書きを関数にし、本体のプログラム部分をすっきりさせます。

接続

 アナログ入力端子は8本あります。デフォルトではch0-ch1の差動入力になっています。24ビットの分解能を考え、ノイズに弱いシングルエンド入力は避け、差動のまま利用します。

本プログラムでのチャネルch 入力端子 data
0 ch0-ch1 0b00000001
1 ch2-ch3 0b00100011
2 ch4-ch5 0b01000101
3 ch6-ch7 0b01100111

 ch0にはTL431の出力約2.5V、ch2には単4電池1個の約1.5V、ch1とch3は相互にショートし、0V入力としました。

プログラム

 作った関数は次のとおりです。

関数名 機 能
sendCommand(x) 1バイトのコマンドを送る
writeRegister(address, value) レジスタに1バイト書き込む
writeRegister3(address, value) レジスタに3バイト書き込む
readD = readRegister(address) レジスタから1バイトと読む
readD3 = readRegister3(address) レジスタから3バイトと読む
readADC() アナログ値を読む
selectCH(channel) 0~3のチャネルを指定する

 初期設定値です。

  • Auto-Calibration
  • PGA x1
  • DataRate 2.5SPS

 PGAは2倍とかを設定できますが、プログラムではその分を計算していません。増幅したら、その分readADC()の結果voltを割ってください。
 DataRateは、データシートにあるどの値でも正常に動作すると思います。2.5SPSは一番遅いレートです。データが用意できたというDRDY信号は見ていないので、十分な時間待ち時間を入れています。
 SPIのデータ転送速度は100kbpsと遅いです。細かなディレイを入れて、データシートのタイミングを確保できないので、これ以上のスピードではうまく読み書きができないかもしれません。

 コメントアウトしているのが、OFC(Offset Calibration)とFSC(Full–scale Calibration)の24ビットの値です。データシートを読んでも、これを設定しなければならないのか、自己キャリブレーションに任せればよいのかが読み取れませんでした。なので、3か所で読み出すようにして確認作業をしていましたが、それでも解決していません。
 
 ステータス・レジスタのAuto-CalibrationをONにしていますが、これが何をしているかは不明です。
 1回の測定のたびにsendCommand(SELFCAL);を実行しています。SELFCALは、自己オフセットおよび自己ゲイン・キャリブレーションの実行コマンドです。これを毎回実行しないと、DataRateをいろいろな数値に変更したら、読み出すデータがでたらめになるケースが増えました。

 ADCの読み出しは、4チャネルの読み出しを100回繰り返しています。

clear all
a = arduino('COM10', 'MKRZero', 'Libraries', 'SPI');
global ads1256;
ads1256 = device(a, 'SPIChipSelectPin', 'D7', 'SPIMode', 1, 'BitRate', 100000, 'BitOrder', 'msbfirst');

statusRegister_address = 0x00;
autoCaliblation = 0b00000100;
RESET = 0xfe;
ADDataRateReg_address = 0x03;
PGAReg_address = 0x02;
RDATAC = 0x03;
SELFCAL = 0xf0;
OFC0 = 0x05;
FSC0 = 0x08;

%% main
global readD;
global readD3;
sendCommand(RESET);
pause(0.5);

% readRegister3(OFC0);
% d = double(bitshift(int32(readD3(3)), 16))  + double(bitshift(int32(readD3(2)), 8)) + double(readD3(1));
% fprintf('read OFC is %08s \n', dec2hex(d));  

% readRegister3(FSC0);
% d = double(bitshift(int32(readD3(3)), 16))  + double(bitshift(int32(readD3(2)), 8)) + double(readD3(1));
% fprintf('read FSC is %08s \n', dec2hex(d)); 

% readRegister(statusRegister_address);
% fprintf('read status  is %08s \n', dec2bin(readD(3)));

writeRegister(statusRegister_address, 0b00000100);  % Auto-Calibration
readRegister(statusRegister_address);
fprintf('read New status  is %08s \n', dec2bin(readD(3)));

writeRegister(PGAReg_address, 0b00100000);  % PGA x1
pause(0.1);
readRegister(PGAReg_address);
fprintf('read PGA is %08s \n', dec2bin(readD(3)));

writeRegister(ADDataRateReg_address, 0b00000011);  % 2.5SPS
pause(0.5);
readRegister(ADDataRateReg_address);
fprintf('read DataRate is %08s \n', dec2bin(readD(3)));
pause(0.5);
sendCommand(SELFCAL);
pause(1);

% readRegister3(OFC0);
% d = double(bitshift(int32(readD3(3)), 16))  + double(bitshift(int32(readD3(2)), 8)) + double(readD3(1));
% fprintf('read OFC is %08s \n', dec2hex(d)); 

% readRegister3(FSC0);
% d = double(bitshift(int32(readD3(3)), 16))  + double(bitshift(int32(readD3(2)), 8)) + double(readD3(1));
% fprintf('read FSC is %08s \n', dec2hex(d)); 

global volt;
for j=0:100
    for i=0:3
        selectCH(i);
        readADC();
        fprintf('read ch=%d  is %.8f \n', i, volt);
        sendCommand(SELFCAL);
        pause(0.9);
    end
    fprintf('---\n');
end

% readRegister3(OFC0);
% d = double(bitshift(int32(readD3(3)), 16))  + double(bitshift(int32(readD3(2)), 8)) + double(readD3(1));
% fprintf('read OFC is %08s \n', dec2hex(d)); 

% readRegister3(FSC0);
% d = double(bitshift(int32(readD3(3)), 16))  + double(bitshift(int32(readD3(2)), 8)) + double(readD3(1));
% fprintf('read FSC is %08s \n', dec2hex(d)); 

function sendCommand(x)
    global ads1256;
    writeRead(ads1256, x);
end

function writeRegister(address, value) % 1byte
    global ads1256;
    WREG = 0x50;
    wdata = bitor(WREG, address);
    out = [wdata 0 value];
    writeRead(ads1256, out, 'uint8') ; % write 
end

function writeRegister3(address, value) % 3byte
    global ads1256;
    WREG = 0x50;
    wdata = bitor(WREG, address);
    out = [wdata 2 value];
    writeRead(ads1256, out, 'uint8') ; % write 
end

function readD = readRegister(address) % 1byte
    global ads1256;
    global readD;
    RREG = 0x10;
    rdata = bitor(RREG, address);
    out = [rdata 0 0xff];
    readD = writeRead(ads1256, out, 'uint8') ;
end

function readD3 = readRegister3(address) % 3byte
    global ads1256;
    global readD3;
    RREG = 0x10;
    rdata = bitor(RREG, address);
    out = [rdata 2 0xff];
    readD3 = writeRead(ads1256, out, 'uint8');
end

function volt = readADC()
    global ads1256;
    global volt;
    Vref  = 2.5 - 0.003;
    out = [0x01,0xff 0xff 0xff];
    readD = writeRead(ads1256, out, 'uint8');
    ad = double(bitshift(int32(readD(2)), 16))  + double(bitshift(int32(readD(3)), 8)) + double(readD(4));
    volt = 2 * Vref * ( ad / 8388607.0);
end

function selectCH(channel)  % channel = 0(default), 1, 2, 3 only
     Input_Multiplexer_Control_Register_address = 0x01;
     SYNC = 0xfc;
     WAKEUP = 0x00;
     % select ch0-ch1 0000 0001, ch2-ch3 0010 0011, ch4-ch5 0100 0101, ch6-ch7 0110 0111
     switch channel
         case 0
             CH = 0b00000001;
         case 1
             CH = 0b00100011;
         case 2
             CH = 0b01000101;
         case 3
             CH = 0b01100111;
         otherwise
             CH = 0x01;             
     end
     writeRegister(Input_Multiplexer_Control_Register_address, CH) ; 
     sendCommand(SYNC);
     sendCommand(WAKEUP);
     pause(0.5);
end

(注) データシート https://www.tij.co.jp/jp/lit/ds/symlink/ads1256.pdf?ts=1597979092052&ref_url=https%253A%252F%252Fwww.tij.co.jp%252Fproduct%252Fjp%252FADS1256

global 変数の指定は、関数(ローカル)内とその外側の両方に宣言する。
関数の定義は、利用する後に行う。

1
1
1

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
1
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?