Use example
/*
A transaction on the SPI bus consists of five phases, any of which may be skipped:
The command phase. In this phase, a command (0-16 bit) is clocked out.
The address phase. In this phase, an address (0-64 bit) is clocked out.
The read phase. The slave sends data to the master.
The write phase. The master sends data to the slave.
In full duplex, the read and write phases are combined, causing the SPI host to read and write data simultaneously.
The command and address phase are optional in that not every SPI device will need to be sent a command and/or address.
Tis is reflected in the device configuration: when the command_bits or data_bits fields are set to zero, no command or address phase is done.
Something similar is true for the read and write phase: not every transaction needs both data to be written as well as data to be read.
When rx_buffer is NULL (and SPI_USE_RXDATA) is not set) the read phase is skipped.
When tx_buffer is NULL (and SPI_USE_TXDATA) is not set) the write phase is skipped.
*/
void fGetIMU( void *pvParameters )
{
if ( fInitializeDevice( ) )
{
Serial.println ( " device init " );
if ( fInitializeAG() )
{
Serial.println( "AG init" );
if ( fDO_AG_ID() )
{
Serial.println ( " AG self ID'd " );
if ( fInitializeM() )
{
Serial.println( "Init Magnetometer" );
if ( fDO_M_ID() )
{
Serial.print ( " M self ID'd: " );
Serial.println( getMAG_ID_OK() );
fReboot();
vTaskDelay( 50 );
if ( fEnableGandA() == false ) // enable gyros and accelerometers
{
Serial.print( " Fail: Enable Gyro and Accelerometer " );
}
if ( fEnableM() == false ) // enable gyros and accelerometers
{
Serial.println( " Fail: Enable Magnetometer" );
}
if ( setupAccelScale( LSM9DS1_ACCELRANGE_8G ) )
{
Serial.println( " Fail: SetupAccelScale" );
}
if ( setupGyroScale ( LSM9DS1_GYROSCALE_500DPS ) )
{
Serial.println( " Fail: setupGyroScale" );
}
if (setupMagScale( LSM9DS1_MAGGAIN_12GAUSS ) )
{
Serial.println( "FailL setupMagScale" );
}
// calibrate();
// Serial.print( " aXbias = " );
// Serial.print( get_aXbias(), 6 );
// Serial.print( " aYbias = " );
// Serial.print( get_aYbias(), 6 );
// Serial.print( " aZias = " );
// Serial.print( get_aZbias(), 6 );
// Serial.print( " gXbias ");
// Serial.print( get_gXbias(), 6 );
// Serial.print( " gYbias = " );
// Serial.print( get_gYbias(), 6 );
// Serial.print( " gZbias = " );
// Serial.println( get_gZbias(), 6 );
} // if ( fDO_M_ID )
else
{
Serial.print( "fDO_M_ID, fail: ");
Serial.print( returnHighBits(), BIN ); //each LSMDS1 may have its own ID
Serial.println( );
}
} // if ( fInitializeM() )
} // if ( fDO_AG_ID() )
else
{
Serial.print( "fDO_AG_ID, fail: ");
Serial.print( returnHighBits(), BIN ); //each LSMDS1 may have its own ID
Serial.println( );
}
} // if ( fInitializeAG() )
} // if ( fInitializeDevice( ) )
////
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS( 35 );
// Initialise the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount();
float TimePast = esp_timer_get_time();
float TimeNow = esp_timer_get_time();
////
float Max = 0.0f;
while (1)
{
vTaskDelayUntil( &xLastWakeTime, xFrequency );
// Serial.println ( " doing a loop " );
if ( getLSM9DS1_ID_OK() && getMAG_ID_OK() ) // then do things
{
//TimeNow = xTaskGetTickCount();
TimeNow = esp_timer_get_time() / 1000000.0f;
// TimeNow = micros() / 1000000.0f;
deltat = ( TimeNow - TimePast);
// Serial.println( deltat,6 );
////
fReadAccelerometers();
fReadGyros();
fReadMagnetometer();
// Serial.print ( "aX= ");
Serial.print( get_aX(), 6 );
Serial.print ( ", ");
// Serial.print ( " aY= ");
Serial.print( get_aY(), 6 );
Serial.print ( ", ");
// Serial.print ( " aZ= ");
Serial.print( get_aZ(), 6 );
Serial.print ( ", ");
// Serial.print ( " gX= ");
Serial.print( get_gX(), 6 );
Serial.print ( ", ");
// Serial.print ( " gY= ");
Serial.print( get_gY(), 6 );
Serial.print ( ", ");
// Serial.print ( " gZ= ");
Serial.print( get_gZ(), 6 );
Serial.print ( ", ");
// Serial.print ( " mX= ");
Serial.print( get_mX(), 6 );
Serial.print ( ", ");
// Serial.print ( " mY= ");
Serial.print( get_mY(), 6 );
Serial.print ( ", ");
// Serial.print ( " mZ= ");
Serial.print( get_mZ(), 6 );
Serial.println();
// roll = atan2f( get_aX(), sqrtf( (get_aY() * get_aY()) + (get_aZ() * get_aZ())) );
// pitch = atan2f( get_aY(), sqrtf( (get_aX() * get_aX()) + (get_aZ() * get_aZ())) );
MahonyQuaternionUpdate ( get_aX(), get_aY(), get_aZ(), get_gX() * PI / 180.0f, get_gY() * PI / 180.0f, get_gZ() * PI / 180.0f, get_mX(), get_mY(), get_mZ() );
// Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
// In this coordinate system, the positive z-axis is down toward Earth.
// Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise.
// Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
// Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
// These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
// Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
// applied in the correct order which for this configuration is yaw, pitch, and then roll.
// For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
// yaw = atan2f(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);
pitch = -asinf(2.0f * (q[1] * q[3] - q[0] * q[2]));
roll = atan2f(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
Serial.print( roll, 6 );
Serial.print( ", " );
Serial.print( pitch, 6 );
Serial.println( );
// log_i( " interrupt Count %d", IntCount );
TimePast = TimeNow;
} // if ( LSM9DS1_ID_OK && M_ID_OK ) // then do things
else
{
Serial.print ( " LSM9DS1_ID_NOT_OK ");
Serial.print ( getLSM9DS1_ID_OK() );
Serial.print ( " or MAG_ID_OK not OK " );
Serial.println( getMAG_ID_OK() );
}
xLastWakeTime = xTaskGetTickCount();
}
vTaskDelete(NULL);
} // void fGetIMU( void *pvParameters )