SparkFunLSM6DS3.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. /******************************************************************************
  2. SparkFunLSM6DS3.cpp
  3. LSM6DS3 Arduino and Teensy Driver
  4. Marshall Taylor @ SparkFun Electronics
  5. May 20, 2015
  6. https://github.com/sparkfun/LSM6DS3_Breakout
  7. https://github.com/sparkfun/SparkFun_LSM6DS3_Arduino_Library
  8. Resources:
  9. Uses Wire.h for i2c operation
  10. Uses SPI.h for SPI operation
  11. Either can be omitted if not used
  12. Development environment specifics:
  13. Arduino IDE 1.6.4
  14. Teensy loader 1.23
  15. This code is released under the [MIT License](http://opensource.org/licenses/MIT).
  16. Please review the LICENSE.md file included with this example. If you have any questions
  17. or concerns with licensing, please contact techsupport@sparkfun.com.
  18. Distributed as-is; no warranty is given.
  19. ******************************************************************************/
  20. //See SparkFunLSM6DS3.h for additional topology notes.
  21. #include "SparkFunLSM6DS3.h"
  22. #include "stdint.h"
  23. #include "Wire.h"
  24. #include "SPI.h"
  25. //****************************************************************************//
  26. //
  27. // LSM6DS3Core functions.
  28. //
  29. // Construction arguments:
  30. // ( uint8_t busType, uint8_t inputArg ),
  31. //
  32. // where inputArg is address for I2C_MODE and chip select pin
  33. // number for SPI_MODE
  34. //
  35. // For SPI, construct LSM6DS3Core myIMU(SPI_MODE, 10);
  36. // For I2C, construct LSM6DS3Core myIMU(I2C_MODE, 0x6B);
  37. //
  38. // Default construction is I2C mode, address 0x6B.
  39. //
  40. //****************************************************************************//
  41. LSM6DS3Core::LSM6DS3Core( uint8_t busType, uint8_t inputArg) : commInterface(I2C_MODE), I2CAddress(0x6B), chipSelectPin(10)
  42. {
  43. commInterface = busType;
  44. if( commInterface == I2C_MODE )
  45. {
  46. I2CAddress = inputArg;
  47. }
  48. if( commInterface == SPI_MODE )
  49. {
  50. chipSelectPin = inputArg;
  51. }
  52. }
  53. status_t LSM6DS3Core::beginCore(void)
  54. {
  55. status_t returnError = IMU_SUCCESS;
  56. switch (commInterface) {
  57. case I2C_MODE:
  58. Wire.begin();
  59. break;
  60. case SPI_MODE:
  61. // start the SPI library:
  62. SPI.begin();
  63. // Maximum SPI frequency is 10MHz, could divide by 2 here:
  64. SPI.setClockDivider(SPI_CLOCK_DIV4);
  65. // Data is read and written MSb first.
  66. SPI.setBitOrder(MSBFIRST);
  67. // Data is captured on rising edge of clock (CPHA = 0)
  68. // Base value of the clock is HIGH (CPOL = 1)
  69. // MODE3 for 328p operation
  70. #ifdef __AVR__
  71. SPI.setDataMode(SPI_MODE3);
  72. #else
  73. #endif
  74. // MODE0 for Teensy 3.1 operation
  75. #ifdef __MK20DX256__
  76. SPI.setDataMode(SPI_MODE0);
  77. #else
  78. #endif
  79. // initalize the data ready and chip select pins:
  80. pinMode(chipSelectPin, OUTPUT);
  81. digitalWrite(chipSelectPin, HIGH);
  82. break;
  83. default:
  84. break;
  85. }
  86. //Spin for a few ms
  87. volatile uint8_t temp = 0;
  88. for( uint16_t i = 0; i < 10000; i++ )
  89. {
  90. temp++;
  91. }
  92. //Check the ID register to determine if the operation was a success.
  93. uint8_t readCheck;
  94. readRegister(&readCheck, LSM6DS3_ACC_GYRO_WHO_AM_I_REG);
  95. if( readCheck != 0x69 )
  96. {
  97. returnError = IMU_HW_ERROR;
  98. }
  99. return returnError;
  100. }
  101. //****************************************************************************//
  102. //
  103. // ReadRegisterRegion
  104. //
  105. // Parameters:
  106. // *outputPointer -- Pass &variable (base address of) to save read data to
  107. // offset -- register to read
  108. // length -- number of bytes to read
  109. //
  110. // Note: Does not know if the target memory space is an array or not, or
  111. // if there is the array is big enough. if the variable passed is only
  112. // two bytes long and 3 bytes are requested, this will over-write some
  113. // other memory!
  114. //
  115. //****************************************************************************//
  116. status_t LSM6DS3Core::readRegisterRegion(uint8_t *outputPointer , uint8_t offset, uint8_t length)
  117. {
  118. status_t returnError = IMU_SUCCESS;
  119. //define pointer that will point to the external space
  120. uint8_t i = 0;
  121. uint8_t c = 0;
  122. uint8_t tempFFCounter = 0;
  123. switch (commInterface) {
  124. case I2C_MODE:
  125. Wire.beginTransmission(I2CAddress);
  126. Wire.write(offset);
  127. if( Wire.endTransmission() != 0 )
  128. {
  129. returnError = IMU_HW_ERROR;
  130. }
  131. else //OK, all worked, keep going
  132. {
  133. // request 6 bytes from slave device
  134. Wire.requestFrom(I2CAddress, length);
  135. while ( (Wire.available()) && (i < length)) // slave may send less than requested
  136. {
  137. c = Wire.read(); // receive a byte as character
  138. *outputPointer = c;
  139. outputPointer++;
  140. i++;
  141. }
  142. }
  143. break;
  144. case SPI_MODE:
  145. // take the chip select low to select the device:
  146. digitalWrite(chipSelectPin, LOW);
  147. // send the device the register you want to read:
  148. SPI.transfer(offset | 0x80); //Ored with "read request" bit
  149. while ( i < length ) // slave may send less than requested
  150. {
  151. c = SPI.transfer(0x00); // receive a byte as character
  152. if( c == 0xFF )
  153. {
  154. //May have problem
  155. tempFFCounter++;
  156. }
  157. *outputPointer = c;
  158. outputPointer++;
  159. i++;
  160. }
  161. if( tempFFCounter == i )
  162. {
  163. //Ok, we've recieved all ones, report
  164. returnError = IMU_ALL_ONES_WARNING;
  165. }
  166. // take the chip select high to de-select:
  167. digitalWrite(chipSelectPin, HIGH);
  168. break;
  169. default:
  170. break;
  171. }
  172. return returnError;
  173. }
  174. //****************************************************************************//
  175. //
  176. // ReadRegister
  177. //
  178. // Parameters:
  179. // *outputPointer -- Pass &variable (address of) to save read data to
  180. // offset -- register to read
  181. //
  182. //****************************************************************************//
  183. status_t LSM6DS3Core::readRegister(uint8_t* outputPointer, uint8_t offset) {
  184. //Return value
  185. uint8_t result;
  186. uint8_t numBytes = 1;
  187. status_t returnError = IMU_SUCCESS;
  188. switch (commInterface) {
  189. case I2C_MODE:
  190. Wire.beginTransmission(I2CAddress);
  191. Wire.write(offset);
  192. if( Wire.endTransmission() != 0 )
  193. {
  194. returnError = IMU_HW_ERROR;
  195. }
  196. Wire.requestFrom(I2CAddress, numBytes);
  197. while ( Wire.available() ) // slave may send less than requested
  198. {
  199. result = Wire.read(); // receive a byte as a proper uint8_t
  200. }
  201. break;
  202. case SPI_MODE:
  203. // take the chip select low to select the device:
  204. digitalWrite(chipSelectPin, LOW);
  205. // send the device the register you want to read:
  206. SPI.transfer(offset | 0x80); //Ored with "read request" bit
  207. // send a value of 0 to read the first byte returned:
  208. result = SPI.transfer(0x00);
  209. // take the chip select high to de-select:
  210. digitalWrite(chipSelectPin, HIGH);
  211. if( result == 0xFF )
  212. {
  213. //we've recieved all ones, report
  214. returnError = IMU_ALL_ONES_WARNING;
  215. }
  216. break;
  217. default:
  218. break;
  219. }
  220. *outputPointer = result;
  221. return returnError;
  222. }
  223. //****************************************************************************//
  224. //
  225. // readRegisterInt16
  226. //
  227. // Parameters:
  228. // *outputPointer -- Pass &variable (base address of) to save read data to
  229. // offset -- register to read
  230. //
  231. //****************************************************************************//
  232. status_t LSM6DS3Core::readRegisterInt16( int16_t* outputPointer, uint8_t offset )
  233. {
  234. uint8_t myBuffer[2];
  235. status_t returnError = readRegisterRegion(myBuffer, offset, 2); //Does memory transfer
  236. int16_t output = (int16_t)myBuffer[0] | int16_t(myBuffer[1] << 8);
  237. *outputPointer = output;
  238. return returnError;
  239. }
  240. //****************************************************************************//
  241. //
  242. // writeRegister
  243. //
  244. // Parameters:
  245. // offset -- register to write
  246. // dataToWrite -- 8 bit data to write to register
  247. //
  248. //****************************************************************************//
  249. status_t LSM6DS3Core::writeRegister(uint8_t offset, uint8_t dataToWrite) {
  250. status_t returnError = IMU_SUCCESS;
  251. switch (commInterface) {
  252. case I2C_MODE:
  253. //Write the byte
  254. Wire.beginTransmission(I2CAddress);
  255. Wire.write(offset);
  256. Wire.write(dataToWrite);
  257. if( Wire.endTransmission() != 0 )
  258. {
  259. returnError = IMU_HW_ERROR;
  260. }
  261. break;
  262. case SPI_MODE:
  263. // take the chip select low to select the device:
  264. digitalWrite(chipSelectPin, LOW);
  265. // send the device the register you want to read:
  266. SPI.transfer(offset);
  267. // send a value of 0 to read the first byte returned:
  268. SPI.transfer(dataToWrite);
  269. // decrement the number of bytes left to read:
  270. // take the chip select high to de-select:
  271. digitalWrite(chipSelectPin, HIGH);
  272. break;
  273. //No way to check error on this write (Except to read back but that's not reliable)
  274. default:
  275. break;
  276. }
  277. return returnError;
  278. }
  279. status_t LSM6DS3Core::embeddedPage( void )
  280. {
  281. status_t returnError = writeRegister( LSM6DS3_ACC_GYRO_RAM_ACCESS, 0x80 );
  282. return returnError;
  283. }
  284. status_t LSM6DS3Core::basePage( void )
  285. {
  286. status_t returnError = writeRegister( LSM6DS3_ACC_GYRO_RAM_ACCESS, 0x00 );
  287. return returnError;
  288. }
  289. //****************************************************************************//
  290. //
  291. // Main user class -- wrapper for the core class + maths
  292. //
  293. // Construct with same rules as the core ( uint8_t busType, uint8_t inputArg )
  294. //
  295. //****************************************************************************//
  296. LSM6DS3::LSM6DS3( uint8_t busType, uint8_t inputArg ) : LSM6DS3Core( busType, inputArg )
  297. {
  298. //Construct with these default settings
  299. settings.gyroEnabled = 1; //Can be 0 or 1
  300. settings.gyroRange = 2000; //Max deg/s. Can be: 125, 245, 500, 1000, 2000
  301. settings.gyroSampleRate = 416; //Hz. Can be: 13, 26, 52, 104, 208, 416, 833, 1666
  302. settings.gyroBandWidth = 400; //Hz. Can be: 50, 100, 200, 400;
  303. settings.gyroFifoEnabled = 1; //Set to include gyro in FIFO
  304. settings.gyroFifoDecimation = 1; //set 1 for on /1
  305. settings.accelEnabled = 1;
  306. settings.accelODROff = 1;
  307. settings.accelRange = 16; //Max G force readable. Can be: 2, 4, 8, 16
  308. settings.accelSampleRate = 416; //Hz. Can be: 13, 26, 52, 104, 208, 416, 833, 1666, 3332, 6664, 13330
  309. settings.accelBandWidth = 100; //Hz. Can be: 50, 100, 200, 400;
  310. settings.accelFifoEnabled = 1; //Set to include accelerometer in the FIFO
  311. settings.accelFifoDecimation = 1; //set 1 for on /1
  312. settings.tempEnabled = 1;
  313. //Select interface mode
  314. settings.commMode = 1; //Can be modes 1, 2 or 3
  315. //FIFO control data
  316. settings.fifoThreshold = 3000; //Can be 0 to 4096 (16 bit bytes)
  317. settings.fifoSampleRate = 10; //default 10Hz
  318. settings.fifoModeWord = 0; //Default off
  319. allOnesCounter = 0;
  320. nonSuccessCounter = 0;
  321. }
  322. //****************************************************************************//
  323. //
  324. // Configuration section
  325. //
  326. // This uses the stored SensorSettings to start the IMU
  327. // Use statements such as "myIMU.settings.commInterface = SPI_MODE;" or
  328. // "myIMU.settings.accelEnabled = 1;" to configure before calling .begin();
  329. //
  330. //****************************************************************************//
  331. status_t LSM6DS3::begin()
  332. {
  333. //Check the settings structure values to determine how to setup the device
  334. uint8_t dataToWrite = 0; //Temporary variable
  335. //Begin the inherited core. This gets the physical wires connected
  336. status_t returnError = beginCore();
  337. //Setup the accelerometer******************************
  338. dataToWrite = 0; //Start Fresh!
  339. if ( settings.accelEnabled == 1) {
  340. //Build config reg
  341. //First patch in filter bandwidth
  342. switch (settings.accelBandWidth) {
  343. case 50:
  344. dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_50Hz;
  345. break;
  346. case 100:
  347. dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_100Hz;
  348. break;
  349. case 200:
  350. dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_200Hz;
  351. break;
  352. default: //set default case to max passthrough
  353. case 400:
  354. dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_400Hz;
  355. break;
  356. }
  357. //Next, patch in full scale
  358. switch (settings.accelRange) {
  359. case 2:
  360. dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_2g;
  361. break;
  362. case 4:
  363. dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_4g;
  364. break;
  365. case 8:
  366. dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_8g;
  367. break;
  368. default: //set default case to 16(max)
  369. case 16:
  370. dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_16g;
  371. break;
  372. }
  373. //Lastly, patch in accelerometer ODR
  374. switch (settings.accelSampleRate) {
  375. case 13:
  376. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_13Hz;
  377. break;
  378. case 26:
  379. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_26Hz;
  380. break;
  381. case 52:
  382. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_52Hz;
  383. break;
  384. default: //Set default to 104
  385. case 104:
  386. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_104Hz;
  387. break;
  388. case 208:
  389. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_208Hz;
  390. break;
  391. case 416:
  392. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_416Hz;
  393. break;
  394. case 833:
  395. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_833Hz;
  396. break;
  397. case 1660:
  398. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_1660Hz;
  399. break;
  400. case 3330:
  401. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_3330Hz;
  402. break;
  403. case 6660:
  404. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_6660Hz;
  405. break;
  406. case 13330:
  407. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_13330Hz;
  408. break;
  409. }
  410. }
  411. else
  412. {
  413. //dataToWrite already = 0 (powerdown);
  414. }
  415. //Now, write the patched together data
  416. writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite);
  417. //Set the ODR bit
  418. readRegister(&dataToWrite, LSM6DS3_ACC_GYRO_CTRL4_C);
  419. dataToWrite &= ~((uint8_t)LSM6DS3_ACC_GYRO_BW_SCAL_ODR_ENABLED);
  420. if ( settings.accelODROff == 1) {
  421. dataToWrite |= LSM6DS3_ACC_GYRO_BW_SCAL_ODR_ENABLED;
  422. }
  423. writeRegister(LSM6DS3_ACC_GYRO_CTRL4_C, dataToWrite);
  424. //Setup the gyroscope**********************************************
  425. dataToWrite = 0; //Start Fresh!
  426. if ( settings.gyroEnabled == 1) {
  427. //Build config reg
  428. //First, patch in full scale
  429. switch (settings.gyroRange) {
  430. case 125:
  431. dataToWrite |= LSM6DS3_ACC_GYRO_FS_125_ENABLED;
  432. break;
  433. case 245:
  434. dataToWrite |= LSM6DS3_ACC_GYRO_FS_G_245dps;
  435. break;
  436. case 500:
  437. dataToWrite |= LSM6DS3_ACC_GYRO_FS_G_500dps;
  438. break;
  439. case 1000:
  440. dataToWrite |= LSM6DS3_ACC_GYRO_FS_G_1000dps;
  441. break;
  442. default: //Default to full 2000DPS range
  443. case 2000:
  444. dataToWrite |= LSM6DS3_ACC_GYRO_FS_G_2000dps;
  445. break;
  446. }
  447. //Lastly, patch in gyro ODR
  448. switch (settings.gyroSampleRate) {
  449. case 13:
  450. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_13Hz;
  451. break;
  452. case 26:
  453. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_26Hz;
  454. break;
  455. case 52:
  456. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_52Hz;
  457. break;
  458. default: //Set default to 104
  459. case 104:
  460. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_104Hz;
  461. break;
  462. case 208:
  463. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_208Hz;
  464. break;
  465. case 416:
  466. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_416Hz;
  467. break;
  468. case 833:
  469. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_833Hz;
  470. break;
  471. case 1660:
  472. dataToWrite |= LSM6DS3_ACC_GYRO_ODR_G_1660Hz;
  473. break;
  474. }
  475. }
  476. else
  477. {
  478. //dataToWrite already = 0 (powerdown);
  479. }
  480. //Write the byte
  481. writeRegister(LSM6DS3_ACC_GYRO_CTRL2_G, dataToWrite);
  482. //Setup the internal temperature sensor
  483. if ( settings.tempEnabled == 1) {
  484. }
  485. //Return WHO AM I reg //Not no mo!
  486. uint8_t result;
  487. readRegister(&result, LSM6DS3_ACC_GYRO_WHO_AM_I_REG);
  488. return returnError;
  489. }
  490. //****************************************************************************//
  491. //
  492. // Accelerometer section
  493. //
  494. //****************************************************************************//
  495. int16_t LSM6DS3::readRawAccelX( void )
  496. {
  497. int16_t output;
  498. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTX_L_XL );
  499. if( errorLevel != IMU_SUCCESS )
  500. {
  501. if( errorLevel == IMU_ALL_ONES_WARNING )
  502. {
  503. allOnesCounter++;
  504. }
  505. else
  506. {
  507. nonSuccessCounter++;
  508. }
  509. }
  510. return output;
  511. }
  512. float LSM6DS3::readFloatAccelX( void )
  513. {
  514. float output = calcAccel(readRawAccelX());
  515. return output;
  516. }
  517. int16_t LSM6DS3::readRawAccelY( void )
  518. {
  519. int16_t output;
  520. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTY_L_XL );
  521. if( errorLevel != IMU_SUCCESS )
  522. {
  523. if( errorLevel == IMU_ALL_ONES_WARNING )
  524. {
  525. allOnesCounter++;
  526. }
  527. else
  528. {
  529. nonSuccessCounter++;
  530. }
  531. }
  532. return output;
  533. }
  534. float LSM6DS3::readFloatAccelY( void )
  535. {
  536. float output = calcAccel(readRawAccelY());
  537. return output;
  538. }
  539. int16_t LSM6DS3::readRawAccelZ( void )
  540. {
  541. int16_t output;
  542. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTZ_L_XL );
  543. if( errorLevel != IMU_SUCCESS )
  544. {
  545. if( errorLevel == IMU_ALL_ONES_WARNING )
  546. {
  547. allOnesCounter++;
  548. }
  549. else
  550. {
  551. nonSuccessCounter++;
  552. }
  553. }
  554. return output;
  555. }
  556. float LSM6DS3::readFloatAccelZ( void )
  557. {
  558. float output = calcAccel(readRawAccelZ());
  559. return output;
  560. }
  561. float LSM6DS3::calcAccel( int16_t input )
  562. {
  563. float output = (float)input * 0.061 * (settings.accelRange >> 1) / 1000;
  564. return output;
  565. }
  566. //****************************************************************************//
  567. //
  568. // Gyroscope section
  569. //
  570. //****************************************************************************//
  571. int16_t LSM6DS3::readRawGyroX( void )
  572. {
  573. int16_t output;
  574. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTX_L_G );
  575. if( errorLevel != IMU_SUCCESS )
  576. {
  577. if( errorLevel == IMU_ALL_ONES_WARNING )
  578. {
  579. allOnesCounter++;
  580. }
  581. else
  582. {
  583. nonSuccessCounter++;
  584. }
  585. }
  586. return output;
  587. }
  588. float LSM6DS3::readFloatGyroX( void )
  589. {
  590. float output = calcGyro(readRawGyroX());
  591. return output;
  592. }
  593. int16_t LSM6DS3::readRawGyroY( void )
  594. {
  595. int16_t output;
  596. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTY_L_G );
  597. if( errorLevel != IMU_SUCCESS )
  598. {
  599. if( errorLevel == IMU_ALL_ONES_WARNING )
  600. {
  601. allOnesCounter++;
  602. }
  603. else
  604. {
  605. nonSuccessCounter++;
  606. }
  607. }
  608. return output;
  609. }
  610. float LSM6DS3::readFloatGyroY( void )
  611. {
  612. float output = calcGyro(readRawGyroY());
  613. return output;
  614. }
  615. int16_t LSM6DS3::readRawGyroZ( void )
  616. {
  617. int16_t output;
  618. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTZ_L_G );
  619. if( errorLevel != IMU_SUCCESS )
  620. {
  621. if( errorLevel == IMU_ALL_ONES_WARNING )
  622. {
  623. allOnesCounter++;
  624. }
  625. else
  626. {
  627. nonSuccessCounter++;
  628. }
  629. }
  630. return output;
  631. }
  632. float LSM6DS3::readFloatGyroZ( void )
  633. {
  634. float output = calcGyro(readRawGyroZ());
  635. return output;
  636. }
  637. float LSM6DS3::calcGyro( int16_t input )
  638. {
  639. uint8_t gyroRangeDivisor = settings.gyroRange / 125;
  640. if ( settings.gyroRange == 245 ) {
  641. gyroRangeDivisor = 2;
  642. }
  643. float output = (float)input * 4.375 * (gyroRangeDivisor) / 1000;
  644. return output;
  645. }
  646. //****************************************************************************//
  647. //
  648. // Temperature section
  649. //
  650. //****************************************************************************//
  651. int16_t LSM6DS3::readRawTemp( void )
  652. {
  653. int16_t output;
  654. readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUT_TEMP_L );
  655. return output;
  656. }
  657. float LSM6DS3::readTempC( void )
  658. {
  659. float output = (float)readRawTemp() / 16; //divide by 16 to scale
  660. output += 25; //Add 25 degrees to remove offset
  661. return output;
  662. }
  663. float LSM6DS3::readTempF( void )
  664. {
  665. float output = (float)readRawTemp() / 16; //divide by 16 to scale
  666. output += 25; //Add 25 degrees to remove offset
  667. output = (output * 9) / 5 + 32;
  668. return output;
  669. }
  670. //****************************************************************************//
  671. //
  672. // FIFO section
  673. //
  674. //****************************************************************************//
  675. void LSM6DS3::fifoBegin( void ) {
  676. //CONFIGURE THE VARIOUS FIFO SETTINGS
  677. //
  678. //
  679. //This section first builds a bunch of config words, then goes through
  680. //and writes them all.
  681. //Split and mask the threshold
  682. uint8_t thresholdLByte = settings.fifoThreshold & 0x00FF;
  683. uint8_t thresholdHByte = (settings.fifoThreshold & 0x0F00) >> 8;
  684. //Pedo bits not configured (ctl2)
  685. //CONFIGURE FIFO_CTRL3
  686. uint8_t tempFIFO_CTRL3 = 0;
  687. if (settings.gyroFifoEnabled == 1)
  688. {
  689. //Set up gyro stuff
  690. //Build on FIFO_CTRL3
  691. //Set decimation
  692. tempFIFO_CTRL3 |= (settings.gyroFifoDecimation & 0x07) << 3;
  693. }
  694. if (settings.accelFifoEnabled == 1)
  695. {
  696. //Set up accelerometer stuff
  697. //Build on FIFO_CTRL3
  698. //Set decimation
  699. tempFIFO_CTRL3 |= (settings.accelFifoDecimation & 0x07);
  700. }
  701. //CONFIGURE FIFO_CTRL4 (nothing for now-- sets data sets 3 and 4
  702. uint8_t tempFIFO_CTRL4 = 0;
  703. //CONFIGURE FIFO_CTRL5
  704. uint8_t tempFIFO_CTRL5 = 0;
  705. switch (settings.fifoSampleRate) {
  706. default: //set default case to 10Hz(slowest)
  707. case 10:
  708. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_10Hz;
  709. break;
  710. case 25:
  711. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_25Hz;
  712. break;
  713. case 50:
  714. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_50Hz;
  715. break;
  716. case 100:
  717. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_100Hz;
  718. break;
  719. case 200:
  720. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_200Hz;
  721. break;
  722. case 400:
  723. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_400Hz;
  724. break;
  725. case 800:
  726. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_800Hz;
  727. break;
  728. case 1600:
  729. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_1600Hz;
  730. break;
  731. case 3300:
  732. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_3300Hz;
  733. break;
  734. case 6600:
  735. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_6600Hz;
  736. break;
  737. }
  738. //Hard code the fifo mode here:
  739. tempFIFO_CTRL5 |= settings.fifoModeWord = 6; //set mode:
  740. //Write the data
  741. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL1, thresholdLByte);
  742. //Serial.println(thresholdLByte, HEX);
  743. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL2, thresholdHByte);
  744. //Serial.println(thresholdHByte, HEX);
  745. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL3, tempFIFO_CTRL3);
  746. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL4, tempFIFO_CTRL4);
  747. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL5, tempFIFO_CTRL5);
  748. }
  749. void LSM6DS3::fifoClear( void ) {
  750. //Drain the fifo data and dump it
  751. while( (fifoGetStatus() & 0x1000 ) == 0 ) {
  752. fifoRead();
  753. }
  754. }
  755. int16_t LSM6DS3::fifoRead( void ) {
  756. //Pull the last data from the fifo
  757. uint8_t tempReadByte = 0;
  758. uint16_t tempAccumulator = 0;
  759. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_DATA_OUT_L);
  760. tempAccumulator = tempReadByte;
  761. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_DATA_OUT_H);
  762. tempAccumulator |= ((uint16_t)tempReadByte << 8);
  763. return tempAccumulator;
  764. }
  765. uint16_t LSM6DS3::fifoGetStatus( void ) {
  766. //Return some data on the state of the fifo
  767. uint8_t tempReadByte = 0;
  768. uint16_t tempAccumulator = 0;
  769. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_STATUS1);
  770. tempAccumulator = tempReadByte;
  771. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_STATUS2);
  772. tempAccumulator |= (tempReadByte << 8);
  773. return tempAccumulator;
  774. }
  775. void LSM6DS3::fifoEnd( void ) {
  776. // turn off the fifo
  777. writeRegister(LSM6DS3_ACC_GYRO_FIFO_STATUS1, 0x00); //Disable
  778. }