GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
GR-ROSEにはPMOD用インタフェースがありますが、NAV (9軸)を動作させてみました。
リンク:秋月、Digilent
DigilentのArduino使用例のページではSparkFunのライブラリを使ってますので、これをインポートして使いました。
しかし、デフォルトのままでは動きませんでした。少し調べた結果、SPIのクロック分周のところを変更する必要がありました。この辺はボードのクロック周波数に依存しないようにSPISettingsを使ってくれると嬉しいのですけどね。まぁ昔はなかったので仕方ないです。ちなみにGR-ROSEのSPIの分周設定はスケッチリファレンスのSPIを参照してください。分周なしの場合、30MHzとなります。
インポート後に「SparkFunLSM9DS1.cpp」を開き、1141行目にあるSPI.setClockDivider(SPI_CLOCK_DIV2)を以下のように変更してください。
IDE for GRにライブラリをインポートした場合、Windowsの場合は「C:\Users\(ユーザー名)\Documents\Arduino\libraries」にあります。Macの場合「~/Documents/Arduino/libraries/」です。#ifdefをきることで、Arduinoで使用時に影響を与えません。
#ifndef GRROSESPI.setClockDivider(SPI_CLOCK_DIV2);#elseSPI.setClockDivider(SPI_CLOCK_DIV6);#endif
一応、ライブラリのソース変更が面倒な方のために、変更を加えたライブラリを以下に置いておきます。
SparkFun_LSM9DS1.zip
実行結果
以下、実行したサンプルです。用意されたサンプル「LSM9DS1_Basic_SPI」ほぼそのままですが、SPIのCS_PINの#defineを変えてますので転記します。GR-ROSEに接続時、CS A/Gはピン10、CS Mはピン20です。
/*****************************************************************LSM9DS1_Basic_SPI.inoSFE_LSM9DS1 Library Simple Example Code - SPI InterfaceJim Lindblom @ SparkFun ElectronicsOriginal Creation Date: April 29, 2015github.com/.../LSM9DS1_BreakoutThe LSM9DS1 is a versatile 9DOF sensor. It has a built-inaccelerometer, gyroscope, and magnetometer. Very cool! Plus itfunctions over either SPI or I2C.This Arduino sketch is a demo of the simple side of theSFE_LSM9DS1 library. It'll demo the following:* How to create a LSM9DS1 object, using a constructor (global variables section).* How to use the begin() function of the LSM9DS1 class.* How to read the gyroscope, accelerometer, and magnetometer using the readGryo(), readAccel(), readMag() functions and the gx, gy, gz, ax, ay, az, mx, my, and mz variables.* How to calculate actual acceleration, rotation speed, magnetic field strength using the calcAccel(), calcGyro() and calcMag() functions.* How to use the data from the LSM9DS1 to calculate orientation and heading.Hardware setup: This example demonstrates how to use theLSM9DS1 with an SPI interface. The pin-out is as follows: LSM9DS1 --------- Arduino CS_AG ------------- 9 CS_M ------------- 10 SDO_AG ----------- 12 SDO_M ------------ 12 (tied to SDO_AG) SCL -------------- 13 SDA -------------- 11 VDD -------------- 3.3V GND -------------- GNDThe LSM9DS1 has a maximum voltage of 3.6V. Make sure you power itoff the 3.3V rail! Signals going into the LSM9DS1, at least,should be level shifted down to 3.3V - that's CSG, CSXM,SCL, and SDA.Better yet, use a 3.3V Arduino (e.g. the Pro or Pro Mini)!Development environment specifics: IDE: Arduino 1.6.3 Hardware Platform: Arduino Pro 3.3V LSM9DS1 Breakout Version: 1.0This code is beerware. If you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!Distributed as-is; no warranty is given.*****************************************************************/// The SFE_LSM9DS1 library requires both Wire and SPI be// included BEFORE including the 9DS1 library.#include <Wire.h>#include <SPI.h>#include <SparkFunLSM9DS1.h>//////////////////////////// LSM9DS1 Library Init ////////////////////////////// Use the LSM9DS1 class to create an object. [imu] can be// named anything, we'll refer to that throught the sketch.LSM9DS1 imu;///////////////////////// Example SPI Setup /////////////////////////// Define the pins used for our SPI chip selects. We're// using hardware SPI, so other signal pins are set in stone.#define LSM9DS1_M_CS 20 // Can be any digital pin#define LSM9DS1_AG_CS 10 // Can be any other digital pin////////////////////////////// Sketch Output Settings //////////////////////////////#define PRINT_CALCULATED//#define PRINT_RAW#define PRINT_SPEED 250 // 250 ms between prints// Earth's magnetic field varies by location. Add or subtract // a declination to get a more accurate heading. Calculate // your's here:// www.ngdc.noaa.gov/.../#define DECLINATION -8.58 // Declination (degrees) in Boulder, CO.//Function definitionsvoid printGyro();void printAccel();void printMag();void printAttitude(float ax, float ay, float az, float mx, float my, float mz);void setup() { Serial.begin(115200); // imu.beginSPI(), which verifies communication with the IMU // and turns it on. if (imu.beginSPI(LSM9DS1_AG_CS, LSM9DS1_M_CS) == false) // note, we need to sent this our CS pins (defined above) { Serial.println("Failed to communicate with LSM9DS1."); Serial.println("Double-check wiring."); Serial.println("Default settings in this sketch will " \ "work for an out of the box LSM9DS1 " \ "Breakout, but may need to be modified " \ "if the board jumpers are."); while (1) ; }}void loop(){ printGyro(); // Print "G: gx, gy, gz" printAccel(); // Print "A: ax, ay, az" printMag(); // Print "M: mx, my, mz" // Print the heading and orientation for fun! // Call print attitude. The LSM9DS1's magnetometer x and y // axes are opposite to the accelerometer, so my and mx are // substituted for each other. printAttitude(imu.ax, imu.ay, imu.az, -imu.my, -imu.mx, imu.mz); Serial.println(); delay(PRINT_SPEED);}void printGyro(){ // To read from the gyroscope, you must first call the // readGyro() function. When this exits, it'll update the // gx, gy, and gz variables with the most current data. imu.readGyro(); // Now we can use the gx, gy, and gz variables as we please. // Either print them as raw ADC values, or calculated in DPS. Serial.print("G: ");#ifdef PRINT_CALCULATED // If you want to print calculated values, you can use the // calcGyro helper function to convert a raw ADC value to // DPS. Give the function the value that you want to convert. Serial.print(imu.calcGyro(imu.gx), 2); Serial.print(", "); Serial.print(imu.calcGyro(imu.gy), 2); Serial.print(", "); Serial.println(imu.calcGyro(imu.gz), 2);#elif defined PRINT_RAW Serial.print(imu.gx); Serial.print(", "); Serial.print(imu.gy); Serial.print(", "); Serial.println(imu.gz);#endif}void printAccel(){ // To read from the accelerometer, you must first call the // readAccel() function. When this exits, it'll update the // ax, ay, and az variables with the most current data. imu.readAccel(); // Now we can use the ax, ay, and az variables as we please. // Either print them as raw ADC values, or calculated in g's. Serial.print("A: ");#ifdef PRINT_CALCULATED // If you want to print calculated values, you can use the // calcAccel helper function to convert a raw ADC value to // g's. Give the function the value that you want to convert. Serial.print(imu.calcAccel(imu.ax), 2); Serial.print(", "); Serial.print(imu.calcAccel(imu.ay), 2); Serial.print(", "); Serial.println(imu.calcAccel(imu.az), 2);#elif defined PRINT_RAW Serial.print(imu.ax); Serial.print(", "); Serial.print(imu.ay); Serial.print(", "); Serial.println(imu.az);#endif}void printMag(){ // To read from the magnetometer, you must first call the // readMag() function. When this exits, it'll update the // mx, my, and mz variables with the most current data. imu.readMag(); // Now we can use the mx, my, and mz variables as we please. // Either print them as raw ADC values, or calculated in Gauss. Serial.print("M: ");#ifdef PRINT_CALCULATED // If you want to print calculated values, you can use the // calcMag helper function to convert a raw ADC value to // Gauss. Give the function the value that you want to convert. Serial.print(imu.calcMag(imu.mx), 2); Serial.print(", "); Serial.print(imu.calcMag(imu.my), 2); Serial.print(", "); Serial.println(imu.calcMag(imu.mz), 2);#elif defined PRINT_RAW Serial.print(imu.mx); Serial.print(", "); Serial.print(imu.my); Serial.print(", "); Serial.println(imu.mz);#endif}// Calculate pitch, roll, and heading.// Pitch/roll calculations take from this app note:// cache.freescale.com/.../AN3461.pdf// Heading calculations taken from this app note:// www51.honeywell.com/.../AN203_Compass_Heading_Using_Magnetometers.pdfvoid 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); // Convert everything from radians to degrees: 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);}