SparkFunLSM6DS3.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  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 == LSM6DS3_ACC_GYRO_WHO_AM_I || readCheck == LSM6DS3_C_ACC_GYRO_WHO_AM_I))
  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. //Return WHO AM I reg //Not no mo!
  483. uint8_t result;
  484. readRegister(&result, LSM6DS3_ACC_GYRO_WHO_AM_I_REG);
  485. //Setup the internal temperature sensor
  486. if ( settings.tempEnabled == 1) {
  487. if(result == LSM6DS3_ACC_GYRO_WHO_AM_I) //0x69 LSM6DS3
  488. settings.tempSensitivity = 16; // Sensitivity to scale 16
  489. else if(result == LSM6DS3_C_ACC_GYRO_WHO_AM_I) //0x6A LSM6dS3-C
  490. settings.tempSensitivity = 256; // Sensitivity to scale 256
  491. }
  492. return returnError;
  493. }
  494. //****************************************************************************//
  495. //
  496. // Accelerometer section
  497. //
  498. //****************************************************************************//
  499. int16_t LSM6DS3::readRawAccelX( void )
  500. {
  501. int16_t output;
  502. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTX_L_XL );
  503. if( errorLevel != IMU_SUCCESS )
  504. {
  505. if( errorLevel == IMU_ALL_ONES_WARNING )
  506. {
  507. allOnesCounter++;
  508. }
  509. else
  510. {
  511. nonSuccessCounter++;
  512. }
  513. }
  514. return output;
  515. }
  516. float LSM6DS3::readFloatAccelX( void )
  517. {
  518. float output = calcAccel(readRawAccelX());
  519. return output;
  520. }
  521. int16_t LSM6DS3::readRawAccelY( void )
  522. {
  523. int16_t output;
  524. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTY_L_XL );
  525. if( errorLevel != IMU_SUCCESS )
  526. {
  527. if( errorLevel == IMU_ALL_ONES_WARNING )
  528. {
  529. allOnesCounter++;
  530. }
  531. else
  532. {
  533. nonSuccessCounter++;
  534. }
  535. }
  536. return output;
  537. }
  538. float LSM6DS3::readFloatAccelY( void )
  539. {
  540. float output = calcAccel(readRawAccelY());
  541. return output;
  542. }
  543. int16_t LSM6DS3::readRawAccelZ( void )
  544. {
  545. int16_t output;
  546. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTZ_L_XL );
  547. if( errorLevel != IMU_SUCCESS )
  548. {
  549. if( errorLevel == IMU_ALL_ONES_WARNING )
  550. {
  551. allOnesCounter++;
  552. }
  553. else
  554. {
  555. nonSuccessCounter++;
  556. }
  557. }
  558. return output;
  559. }
  560. float LSM6DS3::readFloatAccelZ( void )
  561. {
  562. float output = calcAccel(readRawAccelZ());
  563. return output;
  564. }
  565. float LSM6DS3::calcAccel( int16_t input )
  566. {
  567. float output = (float)input * 0.061 * (settings.accelRange >> 1) / 1000;
  568. return output;
  569. }
  570. //****************************************************************************//
  571. //
  572. // Gyroscope section
  573. //
  574. //****************************************************************************//
  575. int16_t LSM6DS3::readRawGyroX( void )
  576. {
  577. int16_t output;
  578. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTX_L_G );
  579. if( errorLevel != IMU_SUCCESS )
  580. {
  581. if( errorLevel == IMU_ALL_ONES_WARNING )
  582. {
  583. allOnesCounter++;
  584. }
  585. else
  586. {
  587. nonSuccessCounter++;
  588. }
  589. }
  590. return output;
  591. }
  592. float LSM6DS3::readFloatGyroX( void )
  593. {
  594. float output = calcGyro(readRawGyroX());
  595. return output;
  596. }
  597. int16_t LSM6DS3::readRawGyroY( void )
  598. {
  599. int16_t output;
  600. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTY_L_G );
  601. if( errorLevel != IMU_SUCCESS )
  602. {
  603. if( errorLevel == IMU_ALL_ONES_WARNING )
  604. {
  605. allOnesCounter++;
  606. }
  607. else
  608. {
  609. nonSuccessCounter++;
  610. }
  611. }
  612. return output;
  613. }
  614. float LSM6DS3::readFloatGyroY( void )
  615. {
  616. float output = calcGyro(readRawGyroY());
  617. return output;
  618. }
  619. int16_t LSM6DS3::readRawGyroZ( void )
  620. {
  621. int16_t output;
  622. status_t errorLevel = readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUTZ_L_G );
  623. if( errorLevel != IMU_SUCCESS )
  624. {
  625. if( errorLevel == IMU_ALL_ONES_WARNING )
  626. {
  627. allOnesCounter++;
  628. }
  629. else
  630. {
  631. nonSuccessCounter++;
  632. }
  633. }
  634. return output;
  635. }
  636. float LSM6DS3::readFloatGyroZ( void )
  637. {
  638. float output = calcGyro(readRawGyroZ());
  639. return output;
  640. }
  641. float LSM6DS3::calcGyro( int16_t input )
  642. {
  643. uint8_t gyroRangeDivisor = settings.gyroRange / 125;
  644. if ( settings.gyroRange == 245 ) {
  645. gyroRangeDivisor = 2;
  646. }
  647. float output = (float)input * 4.375 * (gyroRangeDivisor) / 1000;
  648. return output;
  649. }
  650. //****************************************************************************//
  651. //
  652. // Temperature section
  653. //
  654. //****************************************************************************//
  655. int16_t LSM6DS3::readRawTemp( void )
  656. {
  657. int16_t output;
  658. readRegisterInt16( &output, LSM6DS3_ACC_GYRO_OUT_TEMP_L );
  659. return output;
  660. }
  661. float LSM6DS3::readTempC( void )
  662. {
  663. float output = (float)readRawTemp() / settings.tempSensitivity; //divide by tempSensitivity to scale
  664. output += 25; //Add 25 degrees to remove offset
  665. return output;
  666. }
  667. float LSM6DS3::readTempF( void )
  668. {
  669. float output = (float)readRawTemp() / settings.tempSensitivity; //divide by tempSensitivity to scale
  670. output += 25; //Add 25 degrees to remove offset
  671. output = (output * 9) / 5 + 32;
  672. return output;
  673. }
  674. //****************************************************************************//
  675. //
  676. // FIFO section
  677. //
  678. //****************************************************************************//
  679. void LSM6DS3::fifoBegin( void ) {
  680. //CONFIGURE THE VARIOUS FIFO SETTINGS
  681. //
  682. //
  683. //This section first builds a bunch of config words, then goes through
  684. //and writes them all.
  685. //Split and mask the threshold
  686. uint8_t thresholdLByte = settings.fifoThreshold & 0x00FF;
  687. uint8_t thresholdHByte = (settings.fifoThreshold & 0x0F00) >> 8;
  688. //Pedo bits not configured (ctl2)
  689. //CONFIGURE FIFO_CTRL3
  690. uint8_t tempFIFO_CTRL3 = 0;
  691. if (settings.gyroFifoEnabled == 1)
  692. {
  693. //Set up gyro stuff
  694. //Build on FIFO_CTRL3
  695. //Set decimation
  696. tempFIFO_CTRL3 |= (settings.gyroFifoDecimation & 0x07) << 3;
  697. }
  698. if (settings.accelFifoEnabled == 1)
  699. {
  700. //Set up accelerometer stuff
  701. //Build on FIFO_CTRL3
  702. //Set decimation
  703. tempFIFO_CTRL3 |= (settings.accelFifoDecimation & 0x07);
  704. }
  705. //CONFIGURE FIFO_CTRL4 (nothing for now-- sets data sets 3 and 4
  706. uint8_t tempFIFO_CTRL4 = 0;
  707. //CONFIGURE FIFO_CTRL5
  708. uint8_t tempFIFO_CTRL5 = 0;
  709. switch (settings.fifoSampleRate) {
  710. default: //set default case to 10Hz(slowest)
  711. case 10:
  712. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_10Hz;
  713. break;
  714. case 25:
  715. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_25Hz;
  716. break;
  717. case 50:
  718. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_50Hz;
  719. break;
  720. case 100:
  721. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_100Hz;
  722. break;
  723. case 200:
  724. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_200Hz;
  725. break;
  726. case 400:
  727. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_400Hz;
  728. break;
  729. case 800:
  730. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_800Hz;
  731. break;
  732. case 1600:
  733. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_1600Hz;
  734. break;
  735. case 3300:
  736. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_3300Hz;
  737. break;
  738. case 6600:
  739. tempFIFO_CTRL5 |= LSM6DS3_ACC_GYRO_ODR_FIFO_6600Hz;
  740. break;
  741. }
  742. //Hard code the fifo mode here:
  743. tempFIFO_CTRL5 |= settings.fifoModeWord = 6; //set mode:
  744. //Write the data
  745. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL1, thresholdLByte);
  746. //Serial.println(thresholdLByte, HEX);
  747. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL2, thresholdHByte);
  748. //Serial.println(thresholdHByte, HEX);
  749. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL3, tempFIFO_CTRL3);
  750. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL4, tempFIFO_CTRL4);
  751. writeRegister(LSM6DS3_ACC_GYRO_FIFO_CTRL5, tempFIFO_CTRL5);
  752. }
  753. void LSM6DS3::fifoClear( void ) {
  754. //Drain the fifo data and dump it
  755. while( (fifoGetStatus() & 0x1000 ) == 0 ) {
  756. fifoRead();
  757. }
  758. }
  759. int16_t LSM6DS3::fifoRead( void ) {
  760. //Pull the last data from the fifo
  761. uint8_t tempReadByte = 0;
  762. uint16_t tempAccumulator = 0;
  763. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_DATA_OUT_L);
  764. tempAccumulator = tempReadByte;
  765. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_DATA_OUT_H);
  766. tempAccumulator |= ((uint16_t)tempReadByte << 8);
  767. return tempAccumulator;
  768. }
  769. uint16_t LSM6DS3::fifoGetStatus( void ) {
  770. //Return some data on the state of the fifo
  771. uint8_t tempReadByte = 0;
  772. uint16_t tempAccumulator = 0;
  773. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_STATUS1);
  774. tempAccumulator = tempReadByte;
  775. readRegister(&tempReadByte, LSM6DS3_ACC_GYRO_FIFO_STATUS2);
  776. tempAccumulator |= (tempReadByte << 8);
  777. return tempAccumulator;
  778. }
  779. void LSM6DS3::fifoEnd( void ) {
  780. // turn off the fifo
  781. writeRegister(LSM6DS3_ACC_GYRO_FIFO_STATUS1, 0x00); //Disable
  782. }