Arduino UNO R4 Minimaでセンサ・インターフェーシング ㊲ 加速度計/磁力計LSM303AGR
Adafruitの3軸加速度計/3軸磁力計 LSM303AGR(ST Microelectronics)を利用します。
●AdafruitのStemma QT/Qwiicボード
Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。
コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。
●LSM303AGRのおもなスペック
- 動作電圧 1.71~3.6V
- 動作温度範囲 -40~+85°C
- 加速度測定範囲 ±2g、±4g、±8g、±16g;16ビット
- 磁気センサ ダイナミック・レンジ:±50gauss、感度:1.5mGauss
- インターフェース I2C(最大3.4MHz)、SPI
- スレーブ・アドレス 加速度;0x19、磁気;0x1e
●使用環境
- Arduino UNO R4 Minima
- Arduino IDE 2.2.1
- Windows10 22H2
●接続
Arduino UNO R4 MinimaのI2C信号とセンサ・ボードをJSTコネクタでつなぎます(Stemma QT/Qwiicボードの写真の比率は異なる)。
●スレーブ・アドレスを確認
従来からよく使われているi2cScanner.inoを動かしてスレーブ・アドレスを確認します。電源は3.3Vです。
0x19と0x1eを見つけてきました。
●ライブラリの用意
LSM303 Accelで検索して、見つかった Adafruit LSM303 Accelライブラリをインストールします。加速度計用です。
LIS2MDLで検索して、見つかった Adafruit LIS2MDLライブラリをインストールします。磁力計用です。
インストールを始めたとき、関連のライブラリや依存関係をインストールするかというパネルが出た場合は、全てをインストールします。
●サンプル・スケッチ①
メニューのファイル->スケッチ例から、Adafruit LSM303 Accelから accelsensor.inoを選択します。
コンパイル、実行します。
●サンプル・スケッチ②
メニューのファイル->スケッチ例から、Adafruit LIS2MDLのmagsensor.inoを選択します。
コンパイル、実行します。
上記の二つのスケッチを合体します。
#include <Adafruit_LSM303_Accel.h>
#include <Adafruit_LIS2MDL.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(54321);
Adafruit_LIS2MDL lis2mdl = Adafruit_LIS2MDL(12345);
void displaySensorDetails(void) {
sensor_t sensor;
accel.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print("Sensor: ");
Serial.println(sensor.name);
Serial.print("Driver Ver: ");
Serial.println(sensor.version);
Serial.print("Unique ID: ");
Serial.println(sensor.sensor_id);
Serial.print("Max Value: ");
Serial.print(sensor.max_value);
Serial.println(" m/s^2");
Serial.print("Min Value: ");
Serial.print(sensor.min_value);
Serial.println(" m/s^2");
Serial.print("Resolution: ");
Serial.print(sensor.resolution);
Serial.println(" m/s^2");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
void setup(void) {
Serial.begin(9600);
while (!Serial)
delay(10);
Serial.println("Accelerometer Magnetometer");
Serial.println("");
/* Initialise the sensor */
if (!accel.begin()) {
/* There was a problem detecting the ADXL345 ... check your connections */
Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
while (1)
;
}
/* Display some basic information on this sensor */
displaySensorDetails();
accel.setRange(LSM303_RANGE_4G);
Serial.print("Range set to: ");
lsm303_accel_range_t new_range = accel.getRange();
switch (new_range) {
case LSM303_RANGE_2G:
Serial.println("+- 2G");
break;
case LSM303_RANGE_4G:
Serial.println("+- 4G");
break;
case LSM303_RANGE_8G:
Serial.println("+- 8G");
break;
case LSM303_RANGE_16G:
Serial.println("+- 16G");
break;
}
accel.setMode(LSM303_MODE_NORMAL);
Serial.print("Mode set to: ");
lsm303_accel_mode_t new_mode = accel.getMode();
switch (new_mode) {
case LSM303_MODE_NORMAL:
Serial.println("Normal");
break;
case LSM303_MODE_LOW_POWER:
Serial.println("Low Power");
break;
case LSM303_MODE_HIGH_RESOLUTION:
Serial.println("High Resolution");
break;
}
/* Enable auto-gain */
lis2mdl.enableAutoRange(true);
/* Initialise the sensor */
if (!lis2mdl.begin()) { // I2C mode
/* There was a problem detecting the LIS2MDL ... check your connections */
Serial.println("Ooops, no LIS2MDL detected ... Check your wiring!");
while (1) delay(10);
}
/* Display some basic information on this sensor */
lis2mdl.printSensorDetails();
}
void loop(void) {
/* Get a new sensor event */
sensors_event_t event;
accel.getEvent(&event);
sensors_event_t event2;
lis2mdl.getEvent(&event2);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("\nX: ");
Serial.print(event.acceleration.x);
Serial.print(" ");
Serial.print("Y: ");
Serial.print(event.acceleration.y);
Serial.print(" ");
Serial.print("Z: ");
Serial.print(event.acceleration.z);
Serial.print(" ");
Serial.println("m/s^2");
/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("\nX: ");
Serial.print(event2.magnetic.x);
Serial.print(" ");
Serial.print("Y: ");
Serial.print(event.magnetic.y);
Serial.print(" ");
Serial.print("Z: ");
Serial.print(event2.magnetic.z);
Serial.print(" ");
Serial.println("uT");
/* Delay before the next sample */
delay(500);
}
●グラフィック・ディスプレイに測定結果を表示
次の記事を参考に、グラフィック・ディスプレイに測定した値を表示します。
Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑤ 温湿度センサSi7021の測定結果をグラフィック・ディスプレイに表示
スケッチです。
#include <Adafruit_LSM303_Accel.h>
#include <Adafruit_LIS2MDL.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(54321);
Adafruit_LIS2MDL lis2mdl = Adafruit_LIS2MDL(12345);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
void displaySensorDetails(void) {
sensor_t sensor;
accel.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print("Sensor: ");
Serial.println(sensor.name);
Serial.print("Driver Ver: ");
Serial.println(sensor.version);
Serial.print("Unique ID: ");
Serial.println(sensor.sensor_id);
Serial.print("Max Value: ");
Serial.print(sensor.max_value);
Serial.println(" m/s^2");
Serial.print("Min Value: ");
Serial.print(sensor.min_value);
Serial.println(" m/s^2");
Serial.print("Resolution: ");
Serial.print(sensor.resolution);
Serial.println(" m/s^2");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
void setup(void) {
Serial.begin(9600);
while (!Serial)
delay(10);
Serial.println("Accelerometer Magnetometer");
Serial.println("");
/* Initialise the sensor */
if (!accel.begin()) {
/* There was a problem detecting the ADXL345 ... check your connections */
Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
while (1)
;
}
/* Display some basic information on this sensor */
displaySensorDetails();
accel.setRange(LSM303_RANGE_4G);
Serial.print("Range set to: ");
lsm303_accel_range_t new_range = accel.getRange();
switch (new_range) {
case LSM303_RANGE_2G:
Serial.println("+- 2G");
break;
case LSM303_RANGE_4G:
Serial.println("+- 4G");
break;
case LSM303_RANGE_8G:
Serial.println("+- 8G");
break;
case LSM303_RANGE_16G:
Serial.println("+- 16G");
break;
}
accel.setMode(LSM303_MODE_NORMAL);
Serial.print("Mode set to: ");
lsm303_accel_mode_t new_mode = accel.getMode();
switch (new_mode) {
case LSM303_MODE_NORMAL:
Serial.println("Normal");
break;
case LSM303_MODE_LOW_POWER:
Serial.println("Low Power");
break;
case LSM303_MODE_HIGH_RESOLUTION:
Serial.println("High Resolution");
break;
}
/* Enable auto-gain */
lis2mdl.enableAutoRange(true);
/* Initialise the sensor */
if (!lis2mdl.begin()) { // I2C mode
/* There was a problem detecting the LIS2MDL ... check your connections */
Serial.println("Ooops, no LIS2MDL detected ... Check your wiring!");
while (1) delay(10);
}
/* Display some basic information on this sensor */
lis2mdl.printSensorDetails();
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
delay(500); // Pause for 2 seconds
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
display.clearDisplay();
}
void loop(void) {
/* Get a new sensor event */
sensors_event_t event;
accel.getEvent(&event);
sensors_event_t event2;
lis2mdl.getEvent(&event2);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("\nX: ");
Serial.print(event.acceleration.x);
Serial.print(" ");
Serial.print("Y: ");
Serial.print(event.acceleration.y);
Serial.print(" ");
Serial.print("Z: ");
Serial.print(event.acceleration.z);
Serial.print(" ");
Serial.println("m/s^2");
/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("\nX: ");
Serial.print(event2.magnetic.x);
Serial.print(" ");
Serial.print("Y: ");
Serial.print(event.magnetic.y);
Serial.print(" ");
Serial.print("Z: ");
Serial.print(event2.magnetic.z);
Serial.print(" ");
Serial.println("uT");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Accelerometer - m/s^2");
display.print(event.acceleration.x, 1);
display.print(", ");
display.print(event.acceleration.y, 1);
display.print(", ");
display.print(event.acceleration.z, 1);
display.println("");
display.println("");
display.println("Magnetic vector values - uT");
display.print(event2.magnetic.x, 1);
display.print(", ");
display.print(event2.magnetic.y, 1);
display.print(", ");
display.print(event2.magnetic.z, 1);
display.println("");
display.display();
/* Delay before the next sample */
delay(500);
}