SparkFunLSM6DS3.cpp 26 KB

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