Arduino MKR WiFi 1010をデータ入力に使う⑬I2C 9軸IMU LSM9DS1

 Arduinoで利用できるIMU(加速度センサなど)はたくさんあります。加速度、磁界、角速度の全部が読み取れるセンサは9軸IMUと呼ばれます。MPU-9250、LSM9DS1、BNO055がライブラリの用意されているセンサです。

 ここでは、STMicroelectronicsのLSM9DS1を使います。チップは一つですが、二つのデバイスが内蔵されているようで、I2Cアドレスが二つあります。

LSM9DS1の主なスペック

 アウトブレーク・ボードはAdafruitの製品を使いました。

  • 電源電圧範囲 1.9~3.6V。アウトブレーク・ボードは3.3/5.0V
  • 測定レンジ(加速度 acceleration) ±2/±4/±6/±8/±16g
  •  ジャイロ angular rate ±245/±500/±2000dps
  •  磁力 magnetic ±4/±8/±12/±16gauss
  • インターフェース I2C(100/400 kHz、スレーブ・アドレス0x1e、0x6b)、SPI

接続

 I2Cバスでつなげます。筆者の購入した時点ではSTEMMA QTタイプはなかったのですが、現時点では用意されているので、コネクタをつなぐだけで接続ができます。

プログラム

 9軸の読み出しです。


clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
imu = lsm9ds1(a,'I2CAddress',[0x1e,0x6b]);

accelReadings = readAcceleration(imu)
gyroReadings = readAngularVelocity(imu)
magneticReading = readMagneticField(imu)


 出力例です。

 3Dの表示は、

  Estimating Orientation Using Inertial Sensor Fusion and MPU-9250

を参照しました。この表示には、Sensor Fusion and Tracking ToolboxもしくはNavigation Toolboxが必要です。ホーム・ライセンスではNavigation Toolboxが購入できます。

 次のルーチンは、最初stopTimer = 100;で実行します。ボードを水平に持ち。8の字型に方向をずらします。北の方向が確定します。

 一度行えばいいはずなので、二度目以降は、stopTimer = 10;にして、すぐ通過できるように修正します。


tic;
stopTimer = 10;
magReadings=[];
while(toc<stopTimer)
    % Rotate the sensor around x axis from 0 to 360 degree.
    % Take 2-3 rotations to improve accuracy.
    % For other axes, rotate around that axis.
    [accel, mag] = read(imu);
    magReadings = [magReadings;mag];
end

% For y axis, use magReadings (:,2) and for z axis use magReadings(:,3);
magx_min = min(magReadings(:,1));
magx_max = max(magReadings(:,1));
magx_correction = (magx_max+magx_min)/2;

 ahrsfilterは、加速度計、ジャイロスコープ、磁力計のセンサ・データを融合して、デバイスの向きと角速度を推定するための間接カルマンフィルタ・システム・オブジェクトを返します。フィルタは、12要素の状態ベクトルを使用して、方向、ジャイロスコープのバイアス、線形加速度、および磁気擾乱の推定誤差を追跡します。

 このプログラムを開始する前に、センサは静止している必要があります。


% GyroscopeNoise and AccelerometerNoise is determined from datasheet.
GyroscopeNoiselsm9ds1 = 3.0462e-06; % GyroscopeNoise (variance value) in units of rad/s
AccelerometerNoiselsm9ds1 = 0.0061; % AccelerometerNoise(variance value)in units of m/s^2
viewer = HelperOrientationViewer('Title',{'AHRS Filter'});
FUSE = ahrsfilter('SampleRate',imu.SampleRate, 'GyroscopeNoise',GyroscopeNoiselsm9ds1,'AccelerometerNoise',AccelerometerNoiselsm9ds1);
stopTimer = 2000;

 次のプログラムは、図形を2000カウントの間、ボードの方向を読み取って、中央の四角い物体を動かし続けます。


% Use ahrsfilter to estimate orientation and update the viewer as the
% sensor moves for time specified by stopTimer
disp('start');
tic;
while(toc < stopTimer)
    accelReadings = readAcceleration(imu);
    gyroReadings = readAngularVelocity(imu);
    magneticReading = readMagneticField(imu);
    pause(0.1);
    rotators = FUSE(accelReadings,gyroReadings,magneticReading);
    for j = numel(rotators)
        viewer(rotators(j));
        pause(0.1);
    end
end

 全体のプログラムです。


clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
imu = lsm9ds1(a,'I2CAddress',[0x1e,0x6b]);

tic;
stopTimer = 10;
magReadings=[];
while(toc<stopTimer)
    % Rotate the sensor around x axis from 0 to 360 degree.
    % Take 2-3 rotations to improve accuracy.
    % For other axes, rotate around that axis.
    [accel, mag] = read(imu);
    magReadings = [magReadings;mag];
end

% For y axis, use magReadings (:,2) and for z axis use magReadings(:,3);
magx_min = min(magReadings(:,1));
magx_max = max(magReadings(:,1));
magx_correction = (magx_max+magx_min)/2;
    
% GyroscopeNoise and AccelerometerNoise is determined from datasheet.
GyroscopeNoiselsm9ds1 = 3.0462e-06; % GyroscopeNoise (variance value) in units of rad/s
AccelerometerNoiselsm9ds1 = 0.0061; % AccelerometerNoise(variance value)in units of m/s^2
viewer = HelperOrientationViewer('Title',{'AHRS Filter'});
FUSE = ahrsfilter('SampleRate',imu.SampleRate, 'GyroscopeNoise',GyroscopeNoiselsm9ds1,'AccelerometerNoise',AccelerometerNoiselsm9ds1);
stopTimer = 2000;

% Use ahrsfilter to estimate orientation and update the viewer as the
% sensor moves for time specified by stopTimer
disp('start');
tic;
while(toc < stopTimer)
    accelReadings = readAcceleration(imu);
    gyroReadings = readAngularVelocity(imu);
    magneticReading = readMagneticField(imu);
    pause(0.1);
    rotators = FUSE(accelReadings,gyroReadings,magneticReading);
    for j = numel(rotators)
        viewer(rotators(j));
        pause(0.1);
    end
end

前へ

Arduino MKR WiFi 1010をデータ入力に使う⑫SPI白金測温抵抗体+MAX31865

次へ

Nano 33 BLE Senseをデータ入力に使う<BLE>①温湿度センサ<BLEペリフェラル>