Hi. I upload IMU_DMP_Quat6.ino to board. I can see yaw pitch roll but there is no log file in sd card ?
Have ı to change anything on IMU_DMP_Quat6.ino file ?
Hi. I upload IMU_DMP_Quat6.ino to board. I can see yaw pitch roll but there is no log file in sd card ?
Have ı to change anything on IMU_DMP_Quat6.ino file ?
Hi uygarkuzuoglu,
This is quite a complicated project for your first project with Arduino and OpenLog Artemis…
The standard OpenLog Artemis firmware (v1.11) can only log the DMP Quarternion Quat6 or Quat9 data to SD card. It does not calculate the roll, pitch and yaw for you. You will need to calculate that yourself manually using the Q1-Q3 values.
The IMU_DMP_Quat6.ino example does calculate the roll, pitch and yaw but does not log to SD card.
What you are asking for is something in between: that calculates the roll, pitch and yaw and logs it to SD card. You will need to write that code yourself.
Best wishes,
Paul
So , it is possible like this but i have to write code like “imu_dmp_quat6.ino” myself for logging to sd card.
I understood , ı cant do this with artemis so ı bought arduino mega 2560 and connect with TX/RX pins with OLA.
But ı dont know how to setup tx/rx pins on this codes ;
/****************************************************************
Example6_DMP_Quat9_Orientation.ino
ICM 20948 Arduino Library Demo
Initialize the DMP based on the TDK InvenSense ICM20948_eMD_nucleo_1.0 example-icm20948
Paul Clark, April 25th, 2021
Based on original code by:
Owen Lyke @ SparkFun Electronics
Original Creation Date: April 17 2019
** This example is based on InvenSense’s confidential Application Note “Programming Sequence for DMP Hardware Functions”.
** We are grateful to InvenSense for sharing this with us.
** Important note: by default the DMP functionality is disabled in the library
** as the DMP firmware takes up 14301 Bytes of program memory.
** To use the DMP, you will need to:
** Edit ICM_20948_C.h
** Uncomment line 29: #define ICM_20948_USE_DMP
** Save changes
** If you are using Windows, you can find ICM_20948_C.h in:
** Documents\Arduino\libraries\SparkFun_ICM-20948_ArduinoLibrary\src\util
Please see License.md for the license information.
Distributed as-is; no warranty is given.
***************************************************************/
//#define QUAT_ANIMATION // Uncomment this line to output data in the correct format for ZaneL’s Node.js Quaternion animation tool: https://github.com/ZaneL/quaternion_sensor_3d_nodejs
#include “ICM_20948.h” // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU
//#define USE_SPI // Uncomment this to use SPI
#define SERIAL_PORT Serial
#define SPI_PORT SPI // Your desired SPI port. Used only when “USE_SPI” is defined
#define CS_PIN 2 // Which pin you connect CS to. Used only when “USE_SPI” is defined
#define WIRE_PORT Wire // Your desired Wire port. Used when “USE_SPI” is not defined
#define AD0_VAL 1 // The value of the last bit of the I2C address. \
// On the SparkFun 9DoF IMU breakout the default is 1, and when \
// the ADR jumper is closed the value becomes 0
#ifdef USE_SPI
ICM_20948_SPI myICM; // If using SPI create an ICM_20948_SPI object
#else
ICM_20948_I2C myICM; // Otherwise create an ICM_20948_I2C object
#endif
void setup()
{
SERIAL_PORT.begin(115200); // Start the serial console
#ifndef QUAT_ANIMATION
SERIAL_PORT.println(F(“ICM-20948 Example”));
#endif
delay(100);
#ifndef QUAT_ANIMATION
while (SERIAL_PORT.available()) // Make sure the serial RX buffer is empty
SERIAL_PORT.read();
SERIAL_PORT.println(F(“Press any key to continue…”));
while (!SERIAL_PORT.available()) // Wait for the user to press a key (send any serial character)
;
#endif
#ifdef USE_SPI
SPI_PORT.begin();
#else
WIRE_PORT.begin();
WIRE_PORT.setClock(400000);
#endif
#ifndef QUAT_ANIMATION
//myICM.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
#endif
bool initialized = false;
while (!initialized)
{
// Initialize the ICM-20948
// If the DMP is enabled, .begin performs a minimal startup. We need to configure the sample mode etc. manually.
#ifdef USE_SPI
myICM.begin(CS_PIN, SPI_PORT);
#else
myICM.begin(WIRE_PORT, AD0_VAL);
#endif
#ifndef QUAT_ANIMATION
SERIAL_PORT.print(F("Initialization of the sensor returned: "));
SERIAL_PORT.println(myICM.statusString());
#endif
if (myICM.status != ICM_20948_Stat_Ok)
{
#ifndef QUAT_ANIMATION
SERIAL_PORT.println(F(“Trying again…”));
#endif
delay(500);
}
else
{
initialized = true;
}
}
#ifndef QUAT_ANIMATION
SERIAL_PORT.println(F(“Device connected!”));
#endif
bool success = true; // Use success to show if the DMP configuration was successful
// Initialize the DMP. initializeDMP is a weak function. You can overwrite it if you want to e.g. to change the sample rate
success &= (myICM.initializeDMP() == ICM_20948_Stat_Ok);
// DMP sensor options are defined in ICM_20948_DMP.h
// INV_ICM20948_SENSOR_ACCELEROMETER (16-bit accel)
// INV_ICM20948_SENSOR_GYROSCOPE (16-bit gyro + 32-bit calibrated gyro)
// INV_ICM20948_SENSOR_RAW_ACCELEROMETER (16-bit accel)
// INV_ICM20948_SENSOR_RAW_GYROSCOPE (16-bit gyro + 32-bit calibrated gyro)
// INV_ICM20948_SENSOR_MAGNETIC_FIELD_UNCALIBRATED (16-bit compass)
// INV_ICM20948_SENSOR_GYROSCOPE_UNCALIBRATED (16-bit gyro)
// INV_ICM20948_SENSOR_STEP_DETECTOR (Pedometer Step Detector)
// INV_ICM20948_SENSOR_STEP_COUNTER (Pedometer Step Detector)
// INV_ICM20948_SENSOR_GAME_ROTATION_VECTOR (32-bit 6-axis quaternion)
// INV_ICM20948_SENSOR_ROTATION_VECTOR (32-bit 9-axis quaternion + heading accuracy)
// INV_ICM20948_SENSOR_GEOMAGNETIC_ROTATION_VECTOR (32-bit Geomag RV + heading accuracy)
// INV_ICM20948_SENSOR_GEOMAGNETIC_FIELD (32-bit calibrated compass)
// INV_ICM20948_SENSOR_GRAVITY (32-bit 6-axis quaternion)
// INV_ICM20948_SENSOR_LINEAR_ACCELERATION (16-bit accel + 32-bit 6-axis quaternion)
// INV_ICM20948_SENSOR_ORIENTATION (32-bit 9-axis quaternion + heading accuracy)
// Enable the DMP orientation sensor
success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_ORIENTATION) == ICM_20948_Stat_Ok);
// Enable any additional sensors / features
//success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_RAW_GYROSCOPE) == ICM_20948_Stat_Ok);
//success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_RAW_ACCELEROMETER) == ICM_20948_Stat_Ok);
//success &= (myICM.enableDMPSensor(INV_ICM20948_SENSOR_MAGNETIC_FIELD_UNCALIBRATED) == ICM_20948_Stat_Ok);
// Configuring DMP to output data at multiple ODRs:
// DMP is capable of outputting multiple sensor data at different rates to FIFO.
// Setting value can be calculated as follows:
// Value = (DMP running rate / ODR ) - 1
// E.g. For a 5Hz ODR rate when DMP is running at 55Hz, value = (55/5) - 1 = 10.
success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Quat9, 0) == ICM_20948_Stat_Ok); // Set to the maximum
//success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Accel, 0) == ICM_20948_Stat_Ok); // Set to the maximum
//success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Gyro, 0) == ICM_20948_Stat_Ok); // Set to the maximum
//success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Gyro_Calibr, 0) == ICM_20948_Stat_Ok); // Set to the maximum
//success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Cpass, 0) == ICM_20948_Stat_Ok); // Set to the maximum
//success &= (myICM.setDMPODRrate(DMP_ODR_Reg_Cpass_Calibr, 0) == ICM_20948_Stat_Ok); // Set to the maximum
// Enable the FIFO
success &= (myICM.enableFIFO() == ICM_20948_Stat_Ok);
// Enable the DMP
success &= (myICM.enableDMP() == ICM_20948_Stat_Ok);
// Reset DMP
success &= (myICM.resetDMP() == ICM_20948_Stat_Ok);
// Reset FIFO
success &= (myICM.resetFIFO() == ICM_20948_Stat_Ok);
// Check success
if (success)
{
#ifndef QUAT_ANIMATION
SERIAL_PORT.println(F(“DMP enabled!”));
#endif
}
else
{
SERIAL_PORT.println(F(“Enable DMP failed!”));
SERIAL_PORT.println(F(“Please check that you have uncommented line 29 (#define ICM_20948_USE_DMP) in ICM_20948_C.h…”));
while (1)
; // Do nothing more
}
}
void loop()
{
// Read any DMP data waiting in the FIFO
// Note:
// readDMPdataFromFIFO will return ICM_20948_Stat_FIFONoDataAvail if no data is available.
// If data is available, readDMPdataFromFIFO will attempt to read one frame of DMP data.
// readDMPdataFromFIFO will return ICM_20948_Stat_FIFOIncompleteData if a frame was present but was incomplete
// readDMPdataFromFIFO will return ICM_20948_Stat_Ok if a valid frame was read.
// readDMPdataFromFIFO will return ICM_20948_Stat_FIFOMoreDataAvail if a valid frame was read and the FIFO contains more (unread) data.
icm_20948_DMP_data_t data;
myICM.readDMPdataFromFIFO(&data);
if ((myICM.status == ICM_20948_Stat_Ok) || (myICM.status == ICM_20948_Stat_FIFOMoreDataAvail)) // Was valid data available?
{
//SERIAL_PORT.print(F(“Received data! Header: 0x”)); // Print the header in HEX so we can see what data is arriving in the FIFO
//if ( data.header < 0x1000) SERIAL_PORT.print( “0” ); // Pad the zeros
//if ( data.header < 0x100) SERIAL_PORT.print( “0” );
//if ( data.header < 0x10) SERIAL_PORT.print( “0” );
//SERIAL_PORT.println( data.header, HEX );
if ((data.header & DMP_header_bitmap_Quat9) > 0) // We have asked for orientation data so we should receive Quat9
{
// Q0 value is computed from this equation: Q0^2 + Q1^2 + Q2^2 + Q3^2 = 1.
// In case of drift, the sum will not add to 1, therefore, quaternion data need to be corrected with right bias values.
// The quaternion data is scaled by 2^30.
//SERIAL_PORT.printf(“Quat9 data is: Q1:%ld Q2:%ld Q3:%ld Accuracy:%d\r\n”, data.Quat9.Data.Q1, data.Quat9.Data.Q2, data.Quat9.Data.Q3, data.Quat9.Data.Accuracy);
// Scale to +/- 1
double q1 = ((double)data.Quat9.Data.Q1) / 1073741824.0; // Convert to double. Divide by 2^30
double q2 = ((double)data.Quat9.Data.Q2) / 1073741824.0; // Convert to double. Divide by 2^30
double q3 = ((double)data.Quat9.Data.Q3) / 1073741824.0; // Convert to double. Divide by 2^30
double q0 = sqrt(1.0 - ((q1 * q1) + (q2 * q2) + (q3 * q3)));
#ifndef QUAT_ANIMATION
SERIAL_PORT.print(F(“Q1:”));
SERIAL_PORT.print(q1, 3);
SERIAL_PORT.print(F(" Q2:"));
SERIAL_PORT.print(q2, 3);
SERIAL_PORT.print(F(" Q3:"));
SERIAL_PORT.print(q3, 3);
SERIAL_PORT.print(F(" Accuracy:"));
SERIAL_PORT.println(data.Quat9.Data.Accuracy);
#else
// Output the Quaternion data in the format expected by ZaneL’s Node.js Quaternion animation tool
SERIAL_PORT.print(F(“{"quat_w":”));
SERIAL_PORT.print(q0, 3);
SERIAL_PORT.print(F(“, "quat_x":”));
SERIAL_PORT.print(q1, 3);
SERIAL_PORT.print(F(“, "quat_y":”));
SERIAL_PORT.print(q2, 3);
SERIAL_PORT.print(F(“, "quat_z":”));
SERIAL_PORT.print(q3, 3);
SERIAL_PORT.println(F(“}”));
#endif
}
}
if (myICM.status != ICM_20948_Stat_FIFOMoreDataAvail) // If more data is available then we should read it right away - and not delay
{
delay(10);
}
}