とある科学の備忘録

とある科学の備忘録

CやPythonのプログラミング、Arduino等を使った電子工作をメインに書いています。また、木製CNCやドローンの自作製作記も更新中です。たまに機械学習とかもやってます。

【Arduino】PmodNAVをつかって加速度などを読み取る

この章では、PmodNAVというセンサーを使います。それがこちらです。

f:id:pythonjacascript:20180724230134p:plain

このPmodNavは、加速度、ジャイロ、方向(magnetic field)、気圧センサーが一つになっているモジュールです。
ArduinoとはSPI通信を行い、それぞれのセンサーのデータを送ります。そして、そのデータをPCにシリアル通信で送り、シリアルモニター表示する、ということをやってみます。

ハードウェア

次のピンをつないでください。

Arduino UNO の場合:

PmodNAV<---> Arduino
pin 6     3.3V
pin 5     GND
pin 4     A5
pin 2     A4

Arduino Due の場合

PmodNAV<---> Arduino
pin 6     3.3V
pin 5     GND
pin 4     21(SCLピン)
pin 2     20(SDAピン)


ソフトウェア

全て載せると長くなるので、重要な部分だけ載せます。
全文は、このページの一番下で確認を。

#include <Wire.h>
#include <SparkFunLSM9DS1.h>

// Déclaration des adresses du module
#define LSM9DS1_M 0x1E
#define LSM9DS1_AG 0x6B

LSM9DS1 imu; // Creation of the object imu
#define PRINT_SPEED 250
static unsigned long lastPrint = 0;
#define DECLINATION -0.74 // déclinaison (en degrés) pour Japan.

void setup(void){
  Serial.begin(115200); // initialization of serial communication
  imu.settings.device.commInterface = IMU_MODE_I2C; // initialization of the module
  imu.settings.device.mAddress = LSM9DS1_M;
  imu.settings.device.agAddress = LSM9DS1_AG;
  if (!imu.begin())
  {
    Serial.println("Probleme de communication avec le LSM9DS1.");
    while (1);
  }
}

void loop(){
  if (imu.gyroAvailable())
    imu.readGyro(); // acquisition des données du gyroscope
  
  if (imu.accelAvailable())
    imu.readAccel(); //Acquisition of accelerometer data
  
  if (imu.magAvailable())
    imu.readMag(); // Acquisition of the magnetometer

  if ((lastPrint + PRINT_SPEED) < millis()){
    printGyro(); // Print "G: gx, gy, gz"
    printAccel(); // Print "A: ax, ay, az"
    printMag(); // Print "M: mx, my, mz"
    printAttitude(imu.ax, imu.ay, imu.az,-imu.my, -imu.mx, imu.mz);
    Serial.println();
    lastPrint = millis();
 }
}

実行結果

シリアルモニタに、センサーの値が表示される。
f:id:pythonjacascript:20180724230515p:plain


ソースコード全文

/**************************************************************************
* Description: Pmod_NAV
* All data (accelerometer, gyroscope, magnetometer) are displayed
*
* Wiring
* Module<----------> Arduino
* pin 6 3.3V
* pin 5 GND
* pin 4 A5
* pin 2 A4
************************************************************************/

#include <Wire.h>
#include <SparkFunLSM9DS1.h>

// Déclaration des adresses du module
#define LSM9DS1_M 0x1E
#define LSM9DS1_AG 0x6B

LSM9DS1 imu; // Creation of the object imu

#define PRINT_SPEED 250
static unsigned long lastPrint = 0;

// The earth's magnetic field varies according to its location.
// of the magnetic field using the following site
// http://www.ngdc.noaa.gov/geomag-web/#declination
#define DECLINATION -0.74 // déclinaison (en degrés) pour Japan.

void setup(void)
{
  Serial.begin(115200); // initialization of serial communication
  imu.settings.device.commInterface = IMU_MODE_I2C; // initialization of the module
  imu.settings.device.mAddress = LSM9DS1_M;
  imu.settings.device.agAddress = LSM9DS1_AG;
  if (!imu.begin())
  {
    Serial.println("Probleme de communication avec le LSM9DS1.");
    while (1);
  }
}

void loop(){
  if (imu.gyroAvailable())
    imu.readGyro(); // acquisition des données du gyroscope
  
  if (imu.accelAvailable())
    imu.readAccel(); //Acquisition of accelerometer data
  
  if (imu.magAvailable())
    imu.readMag(); // Acquisition of the magnetometer

  if ((lastPrint + PRINT_SPEED) < millis()){
    printGyro(); // Print "G: gx, gy, gz"
    printAccel(); // Print "A: ax, ay, az"
    printMag(); // Print "M: mx, my, mz"
    printAttitude(imu.ax, imu.ay, imu.az,-imu.my, -imu.mx, imu.mz);
    Serial.println();
    lastPrint = millis();
 }
}

void printGyro(){
  Serial.print("G: ");
  Serial.print(imu.calcGyro(imu.gx), 2);
  Serial.print(", ");
  Serial.print(imu.calcGyro(imu.gy), 2);
  Serial.print(", ");
  Serial.print(imu.calcGyro(imu.gz), 2);
  Serial.println(" deg/s");

  Serial.print(imu.gx);
  Serial.print(", ");
  Serial.print(imu.gy);
  Serial.print(", ");
  Serial.println(imu.gz);
}


void printAccel(){
 Serial.print("A: ");
 Serial.print(imu.calcAccel(imu.ax), 2);
 Serial.print(", ");
 Serial.print(imu.calcAccel(imu.ay), 2);
 Serial.print(", ");
 Serial.print(imu.calcAccel(imu.az), 2);
 Serial.println(" g");
 Serial.print(imu.ax);
 Serial.print(", ");
 Serial.print(imu.ay);
 Serial.print(", ");
 Serial.println(imu.az);
}


void printMag(){
 Serial.print("M: ");
 Serial.print(imu.calcMag(imu.mx), 2);
 Serial.print(", ");
 Serial.print(imu.calcMag(imu.my), 2);
 Serial.print(", ");
 Serial.print(imu.calcMag(imu.mz), 2);
 Serial.println(" gauss");
 Serial.print(imu.mx);
 Serial.print(", ");
 Serial.print(imu.my);
 Serial.print(", ");
 Serial.println(imu.mz);
}

void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
{
 float roll = atan2(ay, az);
 float pitch = atan2(-ax, sqrt(ay * ay + az * az));
 float heading;
 if (my == 0)
  heading = (mx < 0) ? PI : 0;
 else
  heading = atan2(mx, my);
  heading -= DECLINATION * PI / 180;
  if (heading > PI) heading -= (2 * PI);
  else if (heading < -PI) heading += (2 * PI);
  else if (heading < 0) heading += 2 * PI;
  heading *= 180.0 / PI;
  pitch *= 180.0 / PI;
  roll *= 180.0 / PI;
 Serial.print("Pitch, Roll: ");
 Serial.print(pitch, 2);
 Serial.print(", ");
 Serial.println(roll, 2);
 Serial.print("Heading: "); Serial.println(heading, 2);
}