diff --git a/src/LSM9DS1.cpp b/src/LSM9DS1.cpp index 8b378e3..504a475 100644 --- a/src/LSM9DS1.cpp +++ b/src/LSM9DS1.cpp @@ -1,10 +1,10 @@ -/* +/* This file is part of the Arduino_LSM9DS1 library. - This version written by Femme Verbeek, Pijnacker, the Netherlands + This version written by Femme Verbeek, Pijnacker, the Netherlands Released to the public domain version 2 Release Date 10 July 2020 - + Original notice: Copyright (c) 2019 Arduino SA. All rights reserved. @@ -22,9 +22,9 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - + + */ #include "LSM9DS1.h" @@ -110,7 +110,7 @@ void LSM9DS1Class::setOneShotMode() { writeRegister(LSM9DS1_ADDRESS, 0x23, 0x00); // Disable continuous mode writeRegister(LSM9DS1_ADDRESS, 0x2E, 0x00); - + continuousMode = false; } @@ -119,24 +119,24 @@ void LSM9DS1Class::end() writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG3_M, 0x03); writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G, 0x00); writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL, 0x00); - - _wire->end(); - - // There has been a problem with the power usage of the Arduino Nano BLE boards. + + _wire->end(); + + // There has been a problem with the power usage of the Arduino Nano BLE boards. // Due to a switch in pinnumbers the pull-ups keep drawing current after the call to IMU.end(); // This shortens battery life. Most likely future updates solve the problem. // see https://forum.arduino.cc/index.php?topic=691488.15 // code for if the old value is used #if defined(ARDUINO_ARDUINO_NANO33BLE) && PIN_ENABLE_SENSORS_3V3 == 32 pinMode(PIN_ENABLE_I2C_PULLUP, OUTPUT); // this restores the energy usage to very low power - digitalWrite(PIN_ENABLE_I2C_PULLUP, HIGH); -#endif + digitalWrite(PIN_ENABLE_I2C_PULLUP, HIGH); +#endif } //************************************ Acceleration ***************************************** int LSM9DS1Class::readAccel(float& x, float& y, float& z) // return calibrated data in a unit of choise -{ if (!readRawAccel(x,y,z)) return 0; +{ if (!readRawAccel(x,y,z)) return 0; // See releasenotes read = Unit * Slope * (FS / 32786 * Data - Offset ) x = accelUnit * accelSlope[0] * (x - accelOffset[0]); y = accelUnit * accelSlope[1] * (y - accelOffset[1]); @@ -144,19 +144,31 @@ int LSM9DS1Class::readAccel(float& x, float& y, float& z) // return calibrated return 1; } -int LSM9DS1Class::readRawAccel(float& x, float& y, float& z) // return raw uncalibrated data +int LSM9DS1Class::readRawAccel(float& x, float& y, float& z) // return raw uncalibrated data { int16_t data[3]; - if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_XL, (uint8_t*)data, sizeof(data))) + if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_XL, (uint8_t*)data, sizeof(data))) { x = NAN; y = NAN; z = NAN; return 0; } // See releasenotes read = Unit * Slope * (PFS / 32786 * Data - Offset ) - float scale = getAccelFS()/32768.0 ; + float scale = getAccelFS()/32768.0 ; x = scale * data[0]; y = scale * data[1]; z = scale * data[2]; return 1; } +int LSM9DS1Class::readRawAccelInt16(int16_t& x, int16_t& y, int16_t& z) // return raw uncalibrated data +{ int16_t data[3]; + if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_XL, (uint8_t*)data, sizeof(data))) + { x = 0; y = 0; z = 0; return 0; + } + // See releasenotes read = Unit * Slope * (PFS / 32786 * Data - Offset ) + x = data[0]; + y = data[1]; + z = data[2]; + return 1; +} + int LSM9DS1Class::accelAvailable() { @@ -176,37 +188,37 @@ int LSM9DS1Class::accelAvailable() // modified: the void is no longer for translating half calibrated measurements into offsets // in stead the voids rawAccel() rawGyro() and rawMagnet must be used for calibration purposes -void LSM9DS1Class::setAccelOffset(float x, float y, float z) -{ accelOffset[0] = x /(accelUnit * accelSlope[0]); +void LSM9DS1Class::setAccelOffset(float x, float y, float z) +{ accelOffset[0] = x /(accelUnit * accelSlope[0]); accelOffset[1] = y /(accelUnit * accelSlope[1]); accelOffset[2] = z /(accelUnit * accelSlope[2]); } //Slope is already dimensionless, so it can be stored as is. -void LSM9DS1Class::setAccelSlope(float x, float y, float z) +void LSM9DS1Class::setAccelSlope(float x, float y, float z) { if (x==0) x=1; //zero slope not allowed if (y==0) y=1; if (z==0) z=1; - accelSlope[0] = x ; + accelSlope[0] = x ; accelSlope[1] = y ; accelSlope[2] = z ; } -// range 0: switch off Accel and Gyro write in CTRL_REG6_XL; -// range !=0: switch on Accel: write range in CTRL_REG6_XL ; -// Operational mode Accel + Gyro: write setting in CTRL_REG1_G, shared ODR +// range 0: switch off Accel and Gyro write in CTRL_REG6_XL; +// range !=0: switch on Accel: write range in CTRL_REG6_XL ; +// Operational mode Accel + Gyro: write setting in CTRL_REG1_G, shared ODR int LSM9DS1Class::setAccelODR(uint8_t range) //Sample Rate 0:off, 1:10Hz, 2:50Hz, 3:119Hz, 4:238Hz, 5:476Hz, 6:952Hz { if (range >= 7) return 0; uint8_t setting = ((readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL) & 0b00011111) | (range << 5)); - if (writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL,setting)==0) return 0; + if (writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL,setting)==0) return 0; switch (getOperationalMode()) { case 0 : { accelODR=0; - gyroODR=0; + gyroODR=0; break; } case 1 : { accelODR= measureAccelGyroODR(); gyroODR = 0; break; - } + } case 2 : { setting = ((readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G) & 0b00011111) | (range << 5) ); writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G,setting) ; accelODR= measureAccelGyroODR(); @@ -214,7 +226,7 @@ int LSM9DS1Class::setAccelODR(uint8_t range) //Sample Rate 0:off, 1:10Hz, 2:50Hz } } return 1; -} +} float LSM9DS1Class::getAccelODR() { return accelODR; @@ -234,11 +246,11 @@ float LSM9DS1Class::getAccelBW() //Bandwidth setting 0,1,2,3 see documentation { float autoRange[] ={0.0, 408.0, 408.0, 50.0, 105.0, 211.0, 408.0, 0.0 }; float BWXLRange[] ={ 408.0, 211.0, 105.0, 50.0 }; uint8_t RegIs = readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL); - if (bitRead(RegIs,2)) return BWXLRange [RegIs & 0b00000011]; + if (bitRead(RegIs,2)) return BWXLRange [RegIs & 0b00000011]; else return autoRange [ RegIs >> 5 ]; } -int LSM9DS1Class::setAccelFS(uint8_t range) // 0: ±2g ; 1: ±16g ; 2: ±4g ; 3: ±8g +int LSM9DS1Class::setAccelFS(uint8_t range) // 0: ±2g ; 1: ±16g ; 2: ±4g ; 3: ±8g { if (range >=4) return 0; range = (range & 0b00000011) << 3; uint8_t setting = ((readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL) & 0xE7) | range); @@ -254,7 +266,7 @@ float LSM9DS1Class::getAccelFS() // Full scale dimensionless, but its value corr //************************************ Gyroscope ***************************************** int LSM9DS1Class::readGyro(float& x, float& y, float& z) // return calibrated data in a unit of choise -{ +{ if (!readRawGyro(x,y,z)) return 0; //get the register values x = gyroUnit * gyroSlope[0] * (x - gyroOffset[0]); y = gyroUnit * gyroSlope[1] * (y - gyroOffset[1]); @@ -264,7 +276,7 @@ int LSM9DS1Class::readGyro(float& x, float& y, float& z) // return calibrated int LSM9DS1Class::readRawGyro(float& x, float& y, float& z) // return raw data for calibration purposes { int16_t data[3]; - if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_G, (uint8_t*)data, sizeof(data))) + if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_G, (uint8_t*)data, sizeof(data))) { x = NAN; y = NAN; z = NAN; return 0; } float scale = getGyroFS() / 32768.0; @@ -273,6 +285,18 @@ int LSM9DS1Class::readRawGyro(float& x, float& y, float& z) // return raw data z = scale * data[2]; return 1; } + +int LSM9DS1Class::readRawGyroInt16(int16_t& x, int16_t& y, int16_t& z) // return raw data for calibration purposes +{ int16_t data[3]; + if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_G, (uint8_t*)data, sizeof(data))) + { x = 0; y = 0; z = 0; return 0; + } + x = data[0]; + y = data[1]; + z = data[2]; + return 1; +} + int LSM9DS1Class::gyroAvailable() { if (readRegister(LSM9DS1_ADDRESS, LSM9DS1_STATUS_REG) & 0x02) { @@ -283,16 +307,16 @@ int LSM9DS1Class::gyroAvailable() // modified: the void is no longer for translating half calibrated measurements into offsets // Instead the voids rawAccel() rawGyro() and rawMagnet must be used for calibration purposes -void LSM9DS1Class::setGyroOffset(float x, float y, float z) -{ gyroOffset[0] = x; +void LSM9DS1Class::setGyroOffset(float x, float y, float z) +{ gyroOffset[0] = x; gyroOffset[1] = y; gyroOffset[2] = z; } //Slope is already dimensionless, so it can be stored as is. -void LSM9DS1Class::setGyroSlope(float x, float y, float z) +void LSM9DS1Class::setGyroSlope(float x, float y, float z) { if (x==0) x=1; //zero slope not allowed if (y==0) y=1; - if (z==0) z=1; + if (z==0) z=1; gyroSlope[0] = x ; gyroSlope[1] = y ; gyroSlope[2] = z ; @@ -305,26 +329,26 @@ int LSM9DS1Class::getOperationalMode() //0=off , 1= Accel only , 2= Gyro +Accel else return 2; } -// range ==0 : switch off gyroscope - write 0 in CTRL_REG1_G; +// range ==0 : switch off gyroscope - write 0 in CTRL_REG1_G; // range !0 : switch on Accel+Gyro mode- write in CTRL_REG6_XL and CTRL_REG1_G; - + int LSM9DS1Class::setGyroODR(uint8_t range) // 0:off, 1:10Hz, 2:50Hz, 3:119Hz, 4:238Hz, 5:476Hz, 6:952Hz { if (range >= 7) return 0; uint8_t setting = ((readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G) & 0b00011111) | (range << 5 ) ); - writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G,setting); + writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G,setting); if (range > 0 ) { setting = ((readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL) & 0b00011111) | (range << 5)); - writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL,setting); + writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL,setting); } switch (getOperationalMode()) { case 0: { accelODR=0; //off - gyroODR=0; + gyroODR=0; break; } case 1: { accelODR= measureAccelGyroODR(); //accelerometer only gyroODR = 0; break; - } + } case 2: { accelODR= measureAccelGyroODR(); //shared ODR gyroODR = accelODR; } @@ -343,13 +367,13 @@ int LSM9DS1Class::setGyroBW(uint8_t range) { if (range >=4) return 0; range = range & 0b00000011; uint8_t setting = readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G) & 0b11111100; - return writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G,setting | range) ; + return writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G,setting | range) ; } #define ODRrows 8 #define BWcols 4 -float BWtable[ ODRrows ][ BWcols ] = // acc to table 47 dataheet - { { 0, 0, 0, 0 }, +float BWtable[ ODRrows ][ BWcols ] = // acc to table 47 dataheet + { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }, { 14, 31, 31, 31 }, @@ -364,10 +388,10 @@ float LSM9DS1Class::getGyroBW() uint8_t BW = setting & 0b00000011; return BWtable[ODR][BW]; } - + int LSM9DS1Class::setGyroFS(uint8_t range) // (0: 245 dps; 1: 500 dps; 2: 1000 dps; 3: 2000 dps) { if (range >=4) return 0; - range = (range & 0b00000011) << 3; + range = (range & 0b00000011) << 3; uint8_t setting = ((readRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G) & 0xE7) | range ); return writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G,setting) ; } @@ -391,7 +415,7 @@ int LSM9DS1Class::readMagneticField(float& x, float& y, float& z) // return ca // return raw data for calibration purposes int LSM9DS1Class::readRawMagnet(float& x, float& y, float& z) { int16_t data[3]; - if (!readRegisters(LSM9DS1_ADDRESS_M, LSM9DS1_OUT_X_L_M, (uint8_t*)data, sizeof(data))) + if (!readRegisters(LSM9DS1_ADDRESS_M, LSM9DS1_OUT_X_L_M, (uint8_t*)data, sizeof(data))) { x = NAN; y = NAN; z = NAN; return 0; } float scale = getMagnetFS() / 32768.0; @@ -401,6 +425,17 @@ int LSM9DS1Class::readRawMagnet(float& x, float& y, float& z) return 1; } +int LSM9DS1Class::readRawMagnetInt16(int16_t& x, int16_t& y, int16_t& z) +{ int16_t data[3]; + if (!readRegisters(LSM9DS1_ADDRESS_M, LSM9DS1_OUT_X_L_M, (uint8_t*)data, sizeof(data))) + { x = 0; y = 0; z = 0; return 0; + } + x = data[0] ; + y = data[1] ; + z = data[2] ; + return 1; +} + int LSM9DS1Class::magneticFieldAvailable() { //return (readRegister(LSM9DS1_ADDRESS_M, LSM9DS1_STATUS_REG_M) & 0x08)==0x08; @@ -413,13 +448,13 @@ int LSM9DS1Class::magneticFieldAvailable() // modified: the void is no longer for translating half calibrated measurements into offsets // Instead the voids rawAccel() rawGyro() and rawMagnet must be used for calibration purposes -void LSM9DS1Class::setMagnetOffset(float x, float y, float z) -{ magnetOffset[0] = x ; +void LSM9DS1Class::setMagnetOffset(float x, float y, float z) +{ magnetOffset[0] = x ; magnetOffset[1] = y ; magnetOffset[2] = z ; } //Slope is already dimensionless, so it can be stored as is. -void LSM9DS1Class::setMagnetSlope(float x, float y, float z) +void LSM9DS1Class::setMagnetSlope(float x, float y, float z) { if (x==0) x=1; //zero slope not allowed if (y==0) y=1; if (z==0) z=1; @@ -427,10 +462,10 @@ void LSM9DS1Class::setMagnetSlope(float x, float y, float z) magnetSlope[1] = y ; magnetSlope[2] = z ; } - + int LSM9DS1Class::setMagnetFS(uint8_t range) // 0=400.0; 1=800.0; 2=1200.0 , 3=1600.0 (µT) { if (range >=4) return 0; - range = (range & 0b00000011) << 5; + range = (range & 0b00000011) << 5; return writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG2_M,range) ; } @@ -444,7 +479,7 @@ int LSM9DS1Class::setMagnetODR(uint8_t range) // range (0..8) = {0.625,1.25,2.5 { if (range >=16) return 0; uint8_t setting = ((range & 0b00000111) << 2) | ((range & 0b00001000) >> 2); // bit 2..4 see table 111, bit 1 = FAST_ODR setting = setting | (readRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG1_M) & 0b11100001) ; - writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG1_M,setting) ; + writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG1_M,setting) ; uint16_t duration = 1750 / (range + 1); // 1750,875,666,500,400,333,285,250,222 calculate measuring time magnetODR= measureMagnetODR(duration); //measure the actual ODR value } @@ -459,7 +494,7 @@ float LSM9DS1Class::getMagnetODR() // Output {0.625, 1.25, 2.5, 5.0, 10.0, 20.0 //************************************ Private functions ***************************************** void LSM9DS1Class::measureODRcombined() //Combined measurement for faster startUp. -{ float x, y, z; +{ float x, y, z; unsigned long lastEventTimeA,lastEventTimeM,startA,startM; long countA=-3, countM = -2, countiter=0; //Extra cycles to compensate for slow startup unsigned long start = micros(); @@ -467,14 +502,14 @@ void LSM9DS1Class::measureODRcombined() //Combined measurement for faster { countiter++; if (accelAvailable()) { lastEventTimeA = micros(); - readAccel(x, y, z); - countA++; + readAccel(x, y, z); + countA++; if (countA==0) {startA=lastEventTimeA; start=lastEventTimeA;} } if (magnetAvailable()) { lastEventTimeM = micros(); - readMagnet(x, y, z); + readMagnet(x, y, z); countM++; if (countM==0) startM=lastEventTimeM; } @@ -485,45 +520,45 @@ void LSM9DS1Class::measureODRcombined() //Combined measurement for faster // Serial.println("countiter= "+String(countiter) ); // Serial.println("dTa= "+String(lastEventTimeA-startA) ); // Serial.println("dTb= "+String(lastEventTimeM-startM) ); - + accelODR= (1000000.0*float(countA)/float(lastEventTimeA-startA) ); gyroODR = accelODR; magnetODR= (1000000.0*float(countM)/float(lastEventTimeM-startM) ); -} +} float LSM9DS1Class::measureAccelGyroODR() { if (getOperationalMode()==0) return 0; float x, y, z; //dummies - unsigned long lastEventTime, - start=micros(); - long count = -3; + unsigned long lastEventTime, + start=micros(); + long count = -3; int fifoEna=continuousMode; //store FIFO status setOneShotMode(); //switch off FIFO while ((micros()- start) < ODRCalibrationTime) // measure { if (accelAvailable()) { lastEventTime = micros(); - readAccel(x, y, z); + readAccel(x, y, z); count++; if (count<=0) start=lastEventTime; } } // Serial.println("measureAccelGyroODR Count "+String( count ) ); // Serial.println("dTa= "+String(lastEventTime-start) ); -// Serial.println("ODR= "+String(1000000.0*float(count)/float(lastEventTime-start)) ); - if (fifoEna) setContinuousMode(); +// Serial.println("ODR= "+String(1000000.0*float(count)/float(lastEventTime-start)) ); + if (fifoEna) setContinuousMode(); return (1000000.0*float(count)/float(lastEventTime-start) ); } float LSM9DS1Class::measureMagnetODR(unsigned long duration) { float x, y, z; //dummies - unsigned long lastEventTime, - start =micros(); + unsigned long lastEventTime, + start =micros(); long count = -2; // waste current registervalue and running cycle duration *=1000; //switch to micros while ((micros()- start) < duration) // measure { if (magnetAvailable()) { lastEventTime = micros(); - readMagnet(x, y, z); + readMagnet(x, y, z); count++; if (count<=0) start=lastEventTime; } diff --git a/src/LSM9DS1.h b/src/LSM9DS1.h index 51e526d..6570797 100644 --- a/src/LSM9DS1.h +++ b/src/LSM9DS1.h @@ -1,11 +1,11 @@ /* This file is part of the Arduino_LSM9DS1 library. - New version written by Femme Verbeek, Pijnacker, the Netherlands + New version written by Femme Verbeek, Pijnacker, the Netherlands Released to the public domain version 2 Release Date 5 june 2020 - + Original notice: Copyright (c) 2019 Arduino SA. All rights reserved. @@ -22,12 +22,12 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - + */ #ifndef LSM9DS1_V2 #define LSM9DS1_V2 -#endif +#endif #define accelerationSampleRate getAccelODR #define gyroscopeSampleRate getGyroODR @@ -45,7 +45,7 @@ #define setGyroscopeFullScale setGyroFS //development #define setMagneticFieldFullScale setMagnetFS //development -#define readAcceleration readAccel +#define readAcceleration readAccel #define readGyroscope readGyro #define readMagneticField readMagnet @@ -55,14 +55,14 @@ #include #include -#define GAUSS 0.01 +#define GAUSS 0.01 #define MICROTESLA 1.0 // default -#define NANOTESLA 1000.0 +#define NANOTESLA 1000.0 #define GRAVITY 1.0 // default -#define METERPERSECOND2 9.81 +#define METERPERSECOND2 9.81 #define DEGREEPERSECOND 1.0 //default #define RADIANSPERSECOND 3.141592654/180 -#define REVSPERMINUTE 60.0/360.0 +#define REVSPERMINUTE 60.0/360.0 #define REVSPERSECOND 1.0/360.0 class LSM9DS1Class { @@ -81,9 +81,10 @@ class LSM9DS1Class { // Accelerometer float accelOffset[3] = {0,0,0}; // zero point offset correction factor for calibration float accelSlope[3] = {1,1,1}; // slope correction factor for calibration - float accelUnit = GRAVITY; // GRAVITY OR METERPERSECOND2 + float accelUnit = GRAVITY; // GRAVITY OR METERPERSECOND2 virtual int readAccel(float& x, float& y, float& z); // Return calibrated data in unit of choise G or m/s2. - virtual int readRawAccel(float& x, float& y, float& z); // Return uncalibrated results + virtual int readRawAccelInt16(int16_t& x, int16_t& y, int16_t& z); + virtual int readRawAccel(float& x, float& y, float& z); // Return uncalibrated results virtual int accelAvailable(); // Number of samples in the FIFO. virtual void setAccelOffset(float x, float y, float z); //Store zero-point measurements as offset virtual void setAccelSlope(float x, float y, float z); //Store measurements as slope @@ -92,37 +93,39 @@ class LSM9DS1Class { virtual float setAccelBW(uint8_t range); //0,1,2,3 Override autoBandwidth setting see doc.table 67 virtual float getAccelBW(); //Bandwidth setting 0,1,2,3 see documentation table 67 virtual int setAccelFS(uint8_t range); // 0: ±2g ; 1: ±24g ; 2: ±4g ; 3: ±8g - virtual float getAccelFS(); // Full Scale setting (output = 2.0, 24.0 , 4.0 , 8.0) + virtual float getAccelFS(); // Full Scale setting (output = 2.0, 24.0 , 4.0 , 8.0) // Gyroscope float gyroOffset[3] = {0,0,0}; // zero point offset correction factor for calibration float gyroSlope[3] = {1,1,1}; // slope correction factor for calibration float gyroUnit = DEGREEPERSECOND; // DEGREEPERSECOND RADIANSPERSECOND REVSPERMINUTE REVSPERSECOND virtual int readGyro(float& x, float& y, float& z); // Return calibrated data in in unit of choise °/s or rad/s. - virtual int readRawGyro(float& x, float& y, float& z); // Return uncalibrated results + virtual int readRawGyro(float& x, float& y, float& z); // Return uncalibrated results + virtual int readRawGyroInt16(int16_t& x, int16_t& y, int16_t& z); virtual int gyroAvailable(); // Number of samples in the FIFO. virtual void setGyroOffset(float x, float y, float z); //Store zero-point measurements as offset virtual void setGyroSlope(float x, float y, float z); //Store measurements as slope - virtual int setGyroODR(uint8_t range); //Sample Rate Hz 0:off,1:10,2:50 3:119,4:238,5:476,6:does not work 952Hz + virtual int setGyroODR(uint8_t range); //Sample Rate Hz 0:off,1:10,2:50 3:119,4:238,5:476,6:does not work 952Hz virtual float getGyroODR(); // Measured Sample rate of the sensor. virtual int setGyroBW(uint8_t range); //Bandwidth setting 0,1,2,3 see documentation table 46 and 47 virtual float getGyroBW(); //Bandwidth setting 0,1,2,3 see documentation table 46 and 47 virtual int setGyroFS(uint8_t range); // (0= ±245 dps; 1= ±500 dps; 2= ±1000 dps; 3= ±2000 dps) - virtual float getGyroFS(); // (output = 245.0, 500.0 , 1000.0, 2000.0) + virtual float getGyroFS(); // (output = 245.0, 500.0 , 1000.0, 2000.0) // Magnetometer float magnetOffset[3] = {0,0,0}; // zero point offset correction factor for calibration float magnetSlope[3] = {1,1,1}; // slope correction factor for calibration float magnetUnit = MICROTESLA; // GAUSS, MICROTESLA NANOTESLA - virtual int readMagnet(float& x, float& y, float& z); // Return calibrated data in unit of choise µT , nT or G - virtual int readRawMagnet(float& x, float& y, float& z); // Return uncalibrated results + virtual int readMagnet(float& x, float& y, float& z); // Return calibrated data in unit of choise µT , nT or G + virtual int readRawMagnet(float& x, float& y, float& z); // Return uncalibrated results + virtual int readRawMagnetInt16(int16_t& x, int16_t& y, int16_t& z); virtual int magnetAvailable(); // Number of samples in the FIFO. virtual void setMagnetOffset(float x, float y, float z); //Store zero-point measurements as offset virtual void setMagnetSlope(float x, float y, float z); //Store measurements as slope virtual int setMagnetODR(uint8_t range); // Sampling rate (0..8)->{0.625,1.25,2.5,5.0,10,20,40,80,400}Hz virtual float getMagnetODR(); // Sampling rate of the sensor in Hz. virtual int setMagnetFS(uint8_t range); // 0=±400.0; 1=±800.0; 2=±1200.0 , 3=±1600.0 (µT) - virtual float getMagnetFS(); // get chip's full scale setting + virtual float getMagnetFS(); // get chip's full scale setting private: unsigned long ODRCalibrationTime=250000; //µs