Adafruit_LSM6DS.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /*!
  2. * @file Adafruit_LSM6DS.cpp Adafruit LSM6DS 6-DoF Accelerometer
  3. * and Gyroscope library
  4. *
  5. * @section intro_sec Introduction
  6. *
  7. * I2C Driver base for Adafruit LSM6DS 6-DoF Accelerometer
  8. * and Gyroscope libraries
  9. *
  10. * Adafruit invests time and resources providing this open source code,
  11. * please support Adafruit and open-source hardware by purchasing products from
  12. * Adafruit!
  13. *
  14. * @section dependencies Dependencies
  15. * This library depends on the Adafruit BusIO library
  16. *
  17. * This library depends on the Adafruit Unified Sensor library
  18. * @section author Author
  19. *
  20. * Bryan Siepert for Adafruit Industries
  21. *
  22. * @section license License
  23. *
  24. * BSD (see license.txt)
  25. *
  26. * @section HISTORY
  27. *
  28. * v1.0 - First release
  29. */
  30. #include "Arduino.h"
  31. #include <Wire.h>
  32. #include "Adafruit_LSM6DS.h"
  33. static const float _data_rate_arr[] = {
  34. [LSM6DS_RATE_SHUTDOWN] = 0.0f, [LSM6DS_RATE_12_5_HZ] = 12.5f,
  35. [LSM6DS_RATE_26_HZ] = 26.0f, [LSM6DS_RATE_52_HZ] = 52.0f,
  36. [LSM6DS_RATE_104_HZ] = 104.0f, [LSM6DS_RATE_208_HZ] = 208.0f,
  37. [LSM6DS_RATE_416_HZ] = 416.0f, [LSM6DS_RATE_833_HZ] = 833.0f,
  38. [LSM6DS_RATE_1_66K_HZ] = 1660.0f, [LSM6DS_RATE_3_33K_HZ] = 3330.0f,
  39. [LSM6DS_RATE_6_66K_HZ] = 6660.0f,
  40. };
  41. /*!
  42. * @brief Instantiates a new LSM6DS class
  43. */
  44. Adafruit_LSM6DS::Adafruit_LSM6DS(void) {}
  45. /*!
  46. * @brief Cleans up the LSM6DS
  47. */
  48. Adafruit_LSM6DS::~Adafruit_LSM6DS(void) { delete temp_sensor; }
  49. /*! @brief Unique subclass initializer post i2c/spi init
  50. * @param sensor_id Optional unique ID for the sensor set
  51. * @returns True if chip identified and initialized
  52. */
  53. bool Adafruit_LSM6DS::_init(int32_t sensor_id) {
  54. (void)sensor_id;
  55. // Enable accelerometer with 104 Hz data rate, 4G
  56. setAccelDataRate(LSM6DS_RATE_104_HZ);
  57. setAccelRange(LSM6DS_ACCEL_RANGE_4_G);
  58. // Enable gyro with 104 Hz data rate, 2000 dps
  59. setGyroDataRate(LSM6DS_RATE_104_HZ);
  60. setGyroRange(LSM6DS_GYRO_RANGE_2000_DPS);
  61. delay(10);
  62. // delete objects if sensor is reinitialized
  63. delete temp_sensor;
  64. delete accel_sensor;
  65. delete gyro_sensor;
  66. temp_sensor = new Adafruit_LSM6DS_Temp(this);
  67. accel_sensor = new Adafruit_LSM6DS_Accelerometer(this);
  68. gyro_sensor = new Adafruit_LSM6DS_Gyro(this);
  69. return false;
  70. };
  71. /*!
  72. * @brief Read chip identification register
  73. * @returns 8 Bit value from WHOAMI register
  74. */
  75. uint8_t Adafruit_LSM6DS::chipID(void) {
  76. Adafruit_BusIO_Register chip_id = Adafruit_BusIO_Register(
  77. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_WHOAMI);
  78. // Serial.print("Read ID 0x"); Serial.println(chip_id.read(), HEX);
  79. // make sure we're talking to the right chip
  80. return chip_id.read();
  81. }
  82. /*!
  83. * @brief Read Status register
  84. * @returns 8 Bit value from Status register
  85. */
  86. uint8_t Adafruit_LSM6DS::status(void) {
  87. Adafruit_BusIO_Register status_reg = Adafruit_BusIO_Register(
  88. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_STATUS_REG);
  89. return status_reg.read();
  90. }
  91. /*!
  92. * @brief Sets up the hardware and initializes I2C
  93. * @param i2c_address
  94. * The I2C address to be used.
  95. * @param wire
  96. * The Wire object to be used for I2C connections.
  97. * @param sensor_id
  98. * The user-defined ID to differentiate different sensors
  99. * @return True if initialization was successful, otherwise false.
  100. */
  101. boolean Adafruit_LSM6DS::begin_I2C(uint8_t i2c_address, TwoWire *wire,
  102. int32_t sensor_id) {
  103. delete i2c_dev; // remove old interface
  104. i2c_dev = new Adafruit_I2CDevice(i2c_address, wire);
  105. if (!i2c_dev->begin()) {
  106. return false;
  107. }
  108. return _init(sensor_id);
  109. }
  110. /*!
  111. * @brief Sets up the hardware and initializes hardware SPI
  112. * @param cs_pin The arduino pin # connected to chip select
  113. * @param theSPI The SPI object to be used for SPI connections.
  114. * @param frequency The SPI bus frequency
  115. * @param sensor_id
  116. * The user-defined ID to differentiate different sensors
  117. * @return True if initialization was successful, otherwise false.
  118. */
  119. bool Adafruit_LSM6DS::begin_SPI(uint8_t cs_pin, SPIClass *theSPI,
  120. int32_t sensor_id, uint32_t frequency) {
  121. i2c_dev = NULL;
  122. delete spi_dev; // remove old interface
  123. spi_dev = new Adafruit_SPIDevice(cs_pin,
  124. frequency, // frequency
  125. SPI_BITORDER_MSBFIRST, // bit order
  126. SPI_MODE0, // data mode
  127. theSPI);
  128. if (!spi_dev->begin()) {
  129. return false;
  130. }
  131. return _init(sensor_id);
  132. }
  133. /*!
  134. * @brief Sets up the hardware and initializes software SPI
  135. * @param cs_pin The arduino pin # connected to chip select
  136. * @param sck_pin The arduino pin # connected to SPI clock
  137. * @param miso_pin The arduino pin # connected to SPI MISO
  138. * @param mosi_pin The arduino pin # connected to SPI MOSI
  139. * @param frequency The SPI bus frequency
  140. * @param sensor_id
  141. * The user-defined ID to differentiate different sensors
  142. * @return True if initialization was successful, otherwise false.
  143. */
  144. bool Adafruit_LSM6DS::begin_SPI(int8_t cs_pin, int8_t sck_pin, int8_t miso_pin,
  145. int8_t mosi_pin, int32_t sensor_id,
  146. uint32_t frequency) {
  147. i2c_dev = NULL;
  148. delete spi_dev; // remove old interface
  149. spi_dev = new Adafruit_SPIDevice(cs_pin, sck_pin, miso_pin, mosi_pin,
  150. frequency, // frequency
  151. SPI_BITORDER_MSBFIRST, // bit order
  152. SPI_MODE0); // data mode
  153. if (!spi_dev->begin()) {
  154. return false;
  155. }
  156. return _init(sensor_id);
  157. }
  158. /**************************************************************************/
  159. /*!
  160. @brief Resets the sensor to its power-on state, clearing all registers and
  161. memory
  162. */
  163. void Adafruit_LSM6DS::reset(void) {
  164. Adafruit_BusIO_Register ctrl3 = Adafruit_BusIO_Register(
  165. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL3_C);
  166. Adafruit_BusIO_RegisterBits sw_reset =
  167. Adafruit_BusIO_RegisterBits(&ctrl3, 1, 0);
  168. // Adafruit_BusIO_RegisterBits boot = Adafruit_BusIO_RegisterBits(&ctrl3, 1,
  169. // 7);
  170. sw_reset.write(true);
  171. while (sw_reset.read()) {
  172. delay(1);
  173. }
  174. }
  175. /*!
  176. @brief Gets an Adafruit Unified Sensor object for the temp sensor component
  177. @return Adafruit_Sensor pointer to temperature sensor
  178. */
  179. Adafruit_Sensor *Adafruit_LSM6DS::getTemperatureSensor(void) {
  180. return temp_sensor;
  181. }
  182. /*!
  183. @brief Gets an Adafruit Unified Sensor object for the accelerometer
  184. sensor component
  185. @return Adafruit_Sensor pointer to accelerometer sensor
  186. */
  187. Adafruit_Sensor *Adafruit_LSM6DS::getAccelerometerSensor(void) {
  188. return accel_sensor;
  189. }
  190. /*!
  191. @brief Gets an Adafruit Unified Sensor object for the gyro sensor component
  192. @return Adafruit_Sensor pointer to gyro sensor
  193. */
  194. Adafruit_Sensor *Adafruit_LSM6DS::getGyroSensor(void) { return gyro_sensor; }
  195. /**************************************************************************/
  196. /*!
  197. @brief Gets the most recent sensor event, Adafruit Unified Sensor format
  198. @param accel
  199. Pointer to an Adafruit Unified sensor_event_t object to be filled
  200. with acceleration event data.
  201. @param gyro
  202. Pointer to an Adafruit Unified sensor_event_t object to be filled
  203. with gyro event data.
  204. @param temp
  205. Pointer to an Adafruit Unified sensor_event_t object to be filled
  206. with temperature event data.
  207. @return True on successful read
  208. */
  209. /**************************************************************************/
  210. bool Adafruit_LSM6DS::getEvent(sensors_event_t *accel, sensors_event_t *gyro,
  211. sensors_event_t *temp) {
  212. uint32_t t = millis();
  213. _read();
  214. // use helpers to fill in the events
  215. fillAccelEvent(accel, t);
  216. fillGyroEvent(gyro, t);
  217. fillTempEvent(temp, t);
  218. return true;
  219. }
  220. void Adafruit_LSM6DS::fillTempEvent(sensors_event_t *temp, uint32_t timestamp) {
  221. memset(temp, 0, sizeof(sensors_event_t));
  222. temp->version = sizeof(sensors_event_t);
  223. temp->sensor_id = _sensorid_temp;
  224. temp->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
  225. temp->timestamp = timestamp;
  226. temp->temperature = temperature;
  227. }
  228. void Adafruit_LSM6DS::fillGyroEvent(sensors_event_t *gyro, uint32_t timestamp) {
  229. memset(gyro, 0, sizeof(sensors_event_t));
  230. gyro->version = 1;
  231. gyro->sensor_id = _sensorid_gyro;
  232. gyro->type = SENSOR_TYPE_GYROSCOPE;
  233. gyro->timestamp = timestamp;
  234. gyro->gyro.x = gyroX;
  235. gyro->gyro.y = gyroY;
  236. gyro->gyro.z = gyroZ;
  237. }
  238. void Adafruit_LSM6DS::fillAccelEvent(sensors_event_t *accel,
  239. uint32_t timestamp) {
  240. memset(accel, 0, sizeof(sensors_event_t));
  241. accel->version = 1;
  242. accel->sensor_id = _sensorid_accel;
  243. accel->type = SENSOR_TYPE_ACCELEROMETER;
  244. accel->timestamp = timestamp;
  245. accel->acceleration.x = accX;
  246. accel->acceleration.y = accY;
  247. accel->acceleration.z = accZ;
  248. }
  249. /**************************************************************************/
  250. /*!
  251. @brief Gets the accelerometer data rate.
  252. @returns The the accelerometer data rate.
  253. */
  254. lsm6ds_data_rate_t Adafruit_LSM6DS::getAccelDataRate(void) {
  255. Adafruit_BusIO_Register ctrl1 = Adafruit_BusIO_Register(
  256. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL1_XL);
  257. Adafruit_BusIO_RegisterBits accel_data_rate =
  258. Adafruit_BusIO_RegisterBits(&ctrl1, 4, 4);
  259. return (lsm6ds_data_rate_t)accel_data_rate.read();
  260. }
  261. /**************************************************************************/
  262. /*!
  263. @brief Sets the accelerometer data rate.
  264. @param data_rate
  265. The the accelerometer data rate. Must be a `lsm6ds_data_rate_t`.
  266. */
  267. void Adafruit_LSM6DS::setAccelDataRate(lsm6ds_data_rate_t data_rate) {
  268. Adafruit_BusIO_Register ctrl1 = Adafruit_BusIO_Register(
  269. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL1_XL);
  270. Adafruit_BusIO_RegisterBits accel_data_rate =
  271. Adafruit_BusIO_RegisterBits(&ctrl1, 4, 4);
  272. accel_data_rate.write(data_rate);
  273. }
  274. /**************************************************************************/
  275. /*!
  276. @brief Gets the accelerometer measurement range.
  277. @returns The the accelerometer measurement range.
  278. */
  279. lsm6ds_accel_range_t Adafruit_LSM6DS::getAccelRange(void) {
  280. Adafruit_BusIO_Register ctrl1 = Adafruit_BusIO_Register(
  281. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL1_XL);
  282. Adafruit_BusIO_RegisterBits accel_range =
  283. Adafruit_BusIO_RegisterBits(&ctrl1, 2, 2);
  284. accelRangeBuffered = (lsm6ds_accel_range_t)accel_range.read();
  285. return accelRangeBuffered;
  286. }
  287. /**************************************************************************/
  288. /*!
  289. @brief Sets the accelerometer measurement range.
  290. @param new_range The `lsm6ds_accel_range_t` range to set.
  291. */
  292. void Adafruit_LSM6DS::setAccelRange(lsm6ds_accel_range_t new_range) {
  293. Adafruit_BusIO_Register ctrl1 = Adafruit_BusIO_Register(
  294. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL1_XL);
  295. Adafruit_BusIO_RegisterBits accel_range =
  296. Adafruit_BusIO_RegisterBits(&ctrl1, 2, 2);
  297. accel_range.write(new_range);
  298. accelRangeBuffered = new_range;
  299. }
  300. /**************************************************************************/
  301. /*!
  302. @brief Gets the gyro data rate.
  303. @returns The the gyro data rate.
  304. */
  305. lsm6ds_data_rate_t Adafruit_LSM6DS::getGyroDataRate(void) {
  306. Adafruit_BusIO_Register ctrl2 = Adafruit_BusIO_Register(
  307. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL2_G);
  308. Adafruit_BusIO_RegisterBits gyro_data_rate =
  309. Adafruit_BusIO_RegisterBits(&ctrl2, 4, 4);
  310. return (lsm6ds_data_rate_t)gyro_data_rate.read();
  311. }
  312. /**************************************************************************/
  313. /*!
  314. @brief Sets the gyro data rate.
  315. @param data_rate
  316. The the gyro data rate. Must be a `lsm6ds_data_rate_t`.
  317. */
  318. void Adafruit_LSM6DS::setGyroDataRate(lsm6ds_data_rate_t data_rate) {
  319. Adafruit_BusIO_Register ctrl2 = Adafruit_BusIO_Register(
  320. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL2_G);
  321. Adafruit_BusIO_RegisterBits gyro_data_rate =
  322. Adafruit_BusIO_RegisterBits(&ctrl2, 4, 4);
  323. gyro_data_rate.write(data_rate);
  324. }
  325. /**************************************************************************/
  326. /*!
  327. @brief Gets the gyro range.
  328. @returns The the gyro range.
  329. */
  330. lsm6ds_gyro_range_t Adafruit_LSM6DS::getGyroRange(void) {
  331. Adafruit_BusIO_Register ctrl2 = Adafruit_BusIO_Register(
  332. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL2_G);
  333. Adafruit_BusIO_RegisterBits gyro_range =
  334. Adafruit_BusIO_RegisterBits(&ctrl2, 4, 0);
  335. gyroRangeBuffered = (lsm6ds_gyro_range_t)gyro_range.read();
  336. return gyroRangeBuffered;
  337. }
  338. /**************************************************************************/
  339. /*!
  340. @brief Sets the gyro range.
  341. @param new_range The `lsm6ds_gyro_range_t` to set.
  342. */
  343. void Adafruit_LSM6DS::setGyroRange(lsm6ds_gyro_range_t new_range) {
  344. Adafruit_BusIO_Register ctrl2 = Adafruit_BusIO_Register(
  345. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL2_G);
  346. Adafruit_BusIO_RegisterBits gyro_range =
  347. Adafruit_BusIO_RegisterBits(&ctrl2, 4, 0);
  348. gyro_range.write(new_range);
  349. gyroRangeBuffered = new_range;
  350. }
  351. /**************************************************************************/
  352. /*!
  353. @brief Enables the high pass filter and/or slope filter
  354. @param filter_enabled Whether to enable the slope filter (see datasheet)
  355. @param filter The lsm6ds_hp_filter_t that sets the data rate divisor
  356. */
  357. /**************************************************************************/
  358. void Adafruit_LSM6DS::highPassFilter(bool filter_enabled,
  359. lsm6ds_hp_filter_t filter) {
  360. Adafruit_BusIO_Register ctrl8 = Adafruit_BusIO_Register(
  361. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL8_XL);
  362. Adafruit_BusIO_RegisterBits HPF_en =
  363. Adafruit_BusIO_RegisterBits(&ctrl8, 1, 2);
  364. Adafruit_BusIO_RegisterBits HPF_filter =
  365. Adafruit_BusIO_RegisterBits(&ctrl8, 2, 5);
  366. HPF_en.write(filter_enabled);
  367. HPF_filter.write(filter);
  368. }
  369. /******************* Adafruit_Sensor functions *****************/
  370. /*!
  371. * @brief Updates the measurement data for all sensors simultaneously
  372. */
  373. /**************************************************************************/
  374. void Adafruit_LSM6DS::_read(void) {
  375. // get raw readings
  376. Adafruit_BusIO_Register data_reg = Adafruit_BusIO_Register(
  377. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_OUT_TEMP_L, 14);
  378. uint8_t buffer[14];
  379. data_reg.read(buffer, 14);
  380. rawTemp = buffer[1] << 8 | buffer[0];
  381. temperature = (rawTemp / temperature_sensitivity) + 25.0;
  382. rawGyroX = buffer[3] << 8 | buffer[2];
  383. rawGyroY = buffer[5] << 8 | buffer[4];
  384. rawGyroZ = buffer[7] << 8 | buffer[6];
  385. rawAccX = buffer[9] << 8 | buffer[8];
  386. rawAccY = buffer[11] << 8 | buffer[10];
  387. rawAccZ = buffer[13] << 8 | buffer[12];
  388. float gyro_scale = 1; // range is in milli-dps per bit!
  389. switch (gyroRangeBuffered) {
  390. case ISM330DHCX_GYRO_RANGE_4000_DPS:
  391. gyro_scale = 140.0;
  392. break;
  393. case LSM6DS_GYRO_RANGE_2000_DPS:
  394. gyro_scale = 70.0;
  395. break;
  396. case LSM6DS_GYRO_RANGE_1000_DPS:
  397. gyro_scale = 35.0;
  398. break;
  399. case LSM6DS_GYRO_RANGE_500_DPS:
  400. gyro_scale = 17.50;
  401. break;
  402. case LSM6DS_GYRO_RANGE_250_DPS:
  403. gyro_scale = 8.75;
  404. break;
  405. case LSM6DS_GYRO_RANGE_125_DPS:
  406. gyro_scale = 4.375;
  407. break;
  408. }
  409. gyroX = rawGyroX * gyro_scale * SENSORS_DPS_TO_RADS / 1000.0;
  410. gyroY = rawGyroY * gyro_scale * SENSORS_DPS_TO_RADS / 1000.0;
  411. gyroZ = rawGyroZ * gyro_scale * SENSORS_DPS_TO_RADS / 1000.0;
  412. float accel_scale = 1; // range is in milli-g per bit!
  413. switch (accelRangeBuffered) {
  414. case LSM6DS_ACCEL_RANGE_16_G:
  415. accel_scale = 0.488;
  416. break;
  417. case LSM6DS_ACCEL_RANGE_8_G:
  418. accel_scale = 0.244;
  419. break;
  420. case LSM6DS_ACCEL_RANGE_4_G:
  421. accel_scale = 0.122;
  422. break;
  423. case LSM6DS_ACCEL_RANGE_2_G:
  424. accel_scale = 0.061;
  425. break;
  426. }
  427. accX = rawAccX * accel_scale * SENSORS_GRAVITY_STANDARD / 1000;
  428. accY = rawAccY * accel_scale * SENSORS_GRAVITY_STANDARD / 1000;
  429. accZ = rawAccZ * accel_scale * SENSORS_GRAVITY_STANDARD / 1000;
  430. }
  431. /**************************************************************************/
  432. /*!
  433. @brief Sets the INT1 and INT2 pin activation mode
  434. @param active_low true to set the pins as active high, false to set the
  435. mode to active low
  436. @param open_drain true to set the pin mode as open-drain, false to set the
  437. mode to push-pull
  438. */
  439. void Adafruit_LSM6DS::configIntOutputs(bool active_low, bool open_drain) {
  440. Adafruit_BusIO_Register ctrl3 = Adafruit_BusIO_Register(
  441. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL3_C);
  442. Adafruit_BusIO_RegisterBits ppod_bits =
  443. Adafruit_BusIO_RegisterBits(&ctrl3, 2, 4);
  444. ppod_bits.write((active_low << 1) | open_drain);
  445. }
  446. /**************************************************************************/
  447. /*!
  448. @brief Enables and disables the data ready interrupt on INT 1.
  449. @param drdy_temp true to output the data ready temperature interrupt
  450. @param drdy_g true to output the data ready gyro interrupt
  451. @param drdy_xl true to output the data ready accelerometer interrupt
  452. @param step_detect true to output the step detection interrupt (default off)
  453. @param wakeup true to output the wake up interrupt (default off)
  454. */
  455. void Adafruit_LSM6DS::configInt1(bool drdy_temp, bool drdy_g, bool drdy_xl,
  456. bool step_detect, bool wakeup) {
  457. Adafruit_BusIO_Register int1_ctrl = Adafruit_BusIO_Register(
  458. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_INT1_CTRL);
  459. int1_ctrl.write((step_detect << 7) | (drdy_temp << 2) | (drdy_g << 1) |
  460. drdy_xl);
  461. Adafruit_BusIO_Register md1cfg = Adafruit_BusIO_Register(
  462. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_MD1_CFG);
  463. Adafruit_BusIO_RegisterBits wu = Adafruit_BusIO_RegisterBits(&md1cfg, 1, 5);
  464. wu.write(wakeup);
  465. }
  466. /**************************************************************************/
  467. /*!
  468. @brief Enables and disables the data ready interrupt on INT 2.
  469. @param drdy_temp true to output the data ready temperature interrupt
  470. @param drdy_g true to output the data ready gyro interrupt
  471. @param drdy_xl true to output the data ready accelerometer interrupt
  472. */
  473. void Adafruit_LSM6DS::configInt2(bool drdy_temp, bool drdy_g, bool drdy_xl) {
  474. Adafruit_BusIO_Register int2_ctrl = Adafruit_BusIO_Register(
  475. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_INT2_CTRL);
  476. Adafruit_BusIO_RegisterBits int2_drdy_bits =
  477. Adafruit_BusIO_RegisterBits(&int2_ctrl, 3, 0);
  478. int2_drdy_bits.write((drdy_temp << 2) | (drdy_g << 1) | drdy_xl);
  479. }
  480. /**************************************************************************/
  481. /*!
  482. @brief Gets the sensor_t data for the LSM6DS's gyroscope sensor
  483. */
  484. /**************************************************************************/
  485. void Adafruit_LSM6DS_Gyro::getSensor(sensor_t *sensor) {
  486. /* Clear the sensor_t object */
  487. memset(sensor, 0, sizeof(sensor_t));
  488. /* Insert the sensor name in the fixed length char array */
  489. strncpy(sensor->name, "LSM6DS_G", sizeof(sensor->name) - 1);
  490. sensor->name[sizeof(sensor->name) - 1] = 0;
  491. sensor->version = 1;
  492. sensor->sensor_id = _sensorID;
  493. sensor->type = SENSOR_TYPE_GYROSCOPE;
  494. sensor->min_delay = 0;
  495. sensor->min_value = -34.91; /* -2000 dps -> rad/s (radians per second) */
  496. sensor->max_value = +34.91;
  497. sensor->resolution = 7.6358e-5; /* 4.375 mdps -> rad/s */
  498. }
  499. /**************************************************************************/
  500. /*!
  501. @brief Gets the gyroscope as a standard sensor event
  502. @param event Sensor event object that will be populated
  503. @returns True
  504. */
  505. /**************************************************************************/
  506. bool Adafruit_LSM6DS_Gyro::getEvent(sensors_event_t *event) {
  507. _theLSM6DS->_read();
  508. _theLSM6DS->fillGyroEvent(event, millis());
  509. return true;
  510. }
  511. /**************************************************************************/
  512. /*!
  513. @brief Gets the sensor_t data for the LSM6DS's accelerometer
  514. */
  515. /**************************************************************************/
  516. void Adafruit_LSM6DS_Accelerometer::getSensor(sensor_t *sensor) {
  517. /* Clear the sensor_t object */
  518. memset(sensor, 0, sizeof(sensor_t));
  519. /* Insert the sensor name in the fixed length char array */
  520. strncpy(sensor->name, "LSM6DS_A", sizeof(sensor->name) - 1);
  521. sensor->name[sizeof(sensor->name) - 1] = 0;
  522. sensor->version = 1;
  523. sensor->sensor_id = _sensorID;
  524. sensor->type = SENSOR_TYPE_ACCELEROMETER;
  525. sensor->min_delay = 0;
  526. sensor->min_value = -156.9064F; /* -16g = 156.9064 m/s^2 */
  527. sensor->max_value = 156.9064F; /* 16g = 156.9064 m/s^2 */
  528. sensor->resolution = 0.061; /* 0.061 mg/LSB at +-2g */
  529. }
  530. /**************************************************************************/
  531. /*!
  532. @brief Gets the accelerometer as a standard sensor event
  533. @param event Sensor event object that will be populated
  534. @returns True
  535. */
  536. /**************************************************************************/
  537. bool Adafruit_LSM6DS_Accelerometer::getEvent(sensors_event_t *event) {
  538. _theLSM6DS->_read();
  539. _theLSM6DS->fillAccelEvent(event, millis());
  540. return true;
  541. }
  542. /**************************************************************************/
  543. /*!
  544. @brief Gets the sensor_t data for the LSM6DS's tenperature
  545. */
  546. /**************************************************************************/
  547. void Adafruit_LSM6DS_Temp::getSensor(sensor_t *sensor) {
  548. /* Clear the sensor_t object */
  549. memset(sensor, 0, sizeof(sensor_t));
  550. /* Insert the sensor name in the fixed length char array */
  551. strncpy(sensor->name, "LSM6DS_T", sizeof(sensor->name) - 1);
  552. sensor->name[sizeof(sensor->name) - 1] = 0;
  553. sensor->version = 1;
  554. sensor->sensor_id = _sensorID;
  555. sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
  556. sensor->min_delay = 0;
  557. sensor->min_value = -40;
  558. sensor->max_value = 85;
  559. sensor->resolution = 1; /* not a great sensor */
  560. }
  561. /**************************************************************************/
  562. /*!
  563. @brief Gets the temperature as a standard sensor event
  564. @param event Sensor event object that will be populated
  565. @returns True
  566. */
  567. /**************************************************************************/
  568. bool Adafruit_LSM6DS_Temp::getEvent(sensors_event_t *event) {
  569. _theLSM6DS->_read();
  570. _theLSM6DS->fillTempEvent(event, millis());
  571. return true;
  572. }
  573. /**************************************************************************/
  574. /*!
  575. @brief Enables and disables the pedometer function
  576. @param enable True to turn on the pedometer function, false to turn off
  577. */
  578. /**************************************************************************/
  579. void Adafruit_LSM6DS::enablePedometer(bool enable) {
  580. // enable or disable step counter
  581. Adafruit_BusIO_Register tapcfg = Adafruit_BusIO_Register(
  582. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_TAP_CFG);
  583. Adafruit_BusIO_RegisterBits pedo_en =
  584. Adafruit_BusIO_RegisterBits(&tapcfg, 1, 6);
  585. pedo_en.write(enable);
  586. // enable or disable functionality
  587. Adafruit_BusIO_Register ctrl10 = Adafruit_BusIO_Register(
  588. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL10_C);
  589. Adafruit_BusIO_RegisterBits func_en =
  590. Adafruit_BusIO_RegisterBits(&ctrl10, 1, 2);
  591. func_en.write(enable);
  592. resetPedometer();
  593. }
  594. /**************************************************************************/
  595. /*!
  596. @brief Enables and disables the wakeup function
  597. @param enable True to turn on the wakeup function, false to turn off
  598. @param duration How many > threshold readings to generate a wakeup
  599. @param thresh The threshold (sensitivity)
  600. */
  601. /**************************************************************************/
  602. void Adafruit_LSM6DS::enableWakeup(bool enable, uint8_t duration,
  603. uint8_t thresh) {
  604. // enable or disable functionality
  605. Adafruit_BusIO_Register tapcfg = Adafruit_BusIO_Register(
  606. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_TAP_CFG);
  607. Adafruit_BusIO_RegisterBits slope_en =
  608. Adafruit_BusIO_RegisterBits(&tapcfg, 1, 4);
  609. Adafruit_BusIO_RegisterBits timer_en =
  610. Adafruit_BusIO_RegisterBits(&tapcfg, 1, 7);
  611. slope_en.write(enable);
  612. timer_en.write(enable);
  613. if (enable) {
  614. Adafruit_BusIO_Register wake_dur = Adafruit_BusIO_Register(
  615. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_WAKEUP_DUR);
  616. Adafruit_BusIO_RegisterBits durbits =
  617. Adafruit_BusIO_RegisterBits(&wake_dur, 2, 5);
  618. durbits.write(duration);
  619. Adafruit_BusIO_Register wake_ths = Adafruit_BusIO_Register(
  620. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_WAKEUP_THS);
  621. Adafruit_BusIO_RegisterBits thsbits =
  622. Adafruit_BusIO_RegisterBits(&wake_ths, 6, 0);
  623. thsbits.write(thresh);
  624. }
  625. }
  626. /**************************************************************************/
  627. /*!
  628. @brief Checks interrupt register to see if we have a wake signal
  629. @returns True if wake event bit is set in WAKEUP_SRC (cleared on read)
  630. */
  631. /**************************************************************************/
  632. bool Adafruit_LSM6DS::awake(void) {
  633. Adafruit_BusIO_Register wakesrc = Adafruit_BusIO_Register(
  634. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_WAKEUP_SRC);
  635. Adafruit_BusIO_RegisterBits wake_evt =
  636. Adafruit_BusIO_RegisterBits(&wakesrc, 1, 3);
  637. return wake_evt.read();
  638. }
  639. /**************************************************************************/
  640. /*!
  641. @brief Simple shake detection. Must call enableWakeup() first.
  642. @returns True if shake (wake) detected, otherwise false.
  643. */
  644. /**************************************************************************/
  645. bool Adafruit_LSM6DS::shake(void) {
  646. Adafruit_BusIO_Register tapcfg = Adafruit_BusIO_Register(
  647. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_TAP_CFG);
  648. Adafruit_BusIO_RegisterBits slope_en =
  649. Adafruit_BusIO_RegisterBits(&tapcfg, 1, 4);
  650. Adafruit_BusIO_RegisterBits timer_en =
  651. Adafruit_BusIO_RegisterBits(&tapcfg, 1, 7);
  652. // only check if enabled
  653. if (slope_en.read() && timer_en.read()) {
  654. return awake();
  655. }
  656. return false;
  657. }
  658. /**************************************************************************/
  659. /*!
  660. @brief Reset the pedometer count
  661. */
  662. /**************************************************************************/
  663. void Adafruit_LSM6DS::resetPedometer(void) {
  664. // reset bit to clear counter
  665. Adafruit_BusIO_Register ctrl10 = Adafruit_BusIO_Register(
  666. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_CTRL10_C);
  667. Adafruit_BusIO_RegisterBits ped_rst =
  668. Adafruit_BusIO_RegisterBits(&ctrl10, 1, 1);
  669. ped_rst.write(true);
  670. }
  671. /**************************************************************************/
  672. /*!
  673. @brief Read the 16-bit pedometer count
  674. @returns The value from the step counter
  675. */
  676. /**************************************************************************/
  677. uint16_t Adafruit_LSM6DS::readPedometer(void) {
  678. Adafruit_BusIO_Register steps_reg = Adafruit_BusIO_Register(
  679. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_STEPCOUNTER, 2);
  680. return steps_reg.read();
  681. }
  682. /**************************************************************************/
  683. /*!
  684. @brief Gets the accelerometer data rate.
  685. @returns The data rate in float
  686. */
  687. float Adafruit_LSM6DS::accelerationSampleRate(void) {
  688. return _data_rate_arr[this->getAccelDataRate()];
  689. }
  690. /**************************************************************************/
  691. /*!
  692. @brief Check for available data from accelerometer
  693. @returns 1 if available, 0 if not
  694. */
  695. int Adafruit_LSM6DS::accelerationAvailable(void) {
  696. return (this->status() & 0x01) ? 1 : 0;
  697. }
  698. /**************************************************************************/
  699. /*!
  700. @brief Read accelerometer data
  701. @param x reference to x axis
  702. @param y reference to y axis
  703. @param z reference to z axis
  704. @returns 1 if success, 0 if not
  705. */
  706. int Adafruit_LSM6DS::readAcceleration(float &x, float &y, float &z) {
  707. int16_t data[3];
  708. Adafruit_BusIO_Register accel_data = Adafruit_BusIO_Register(
  709. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_OUTX_L_A, 6);
  710. if (!accel_data.read((uint8_t *)data, sizeof(data))) {
  711. x = y = z = NAN;
  712. return 0;
  713. }
  714. // scale to range of -4 – 4
  715. x = data[0] * 4.0 / 32768.0;
  716. y = data[1] * 4.0 / 32768.0;
  717. z = data[2] * 4.0 / 32768.0;
  718. return 1;
  719. }
  720. /**************************************************************************/
  721. /*!
  722. @brief Get the gyroscope data rate.
  723. @returns The data rate in float
  724. */
  725. float Adafruit_LSM6DS::gyroscopeSampleRate(void) {
  726. return _data_rate_arr[this->getGyroDataRate()];
  727. }
  728. /**************************************************************************/
  729. /*!
  730. @brief Check for available data from gyroscope
  731. @returns 1 if available, 0 if not
  732. */
  733. int Adafruit_LSM6DS::gyroscopeAvailable(void) {
  734. return (this->status() & 0x02) ? 1 : 0;
  735. }
  736. /**************************************************************************/
  737. /*!
  738. @brief Read gyroscope data
  739. @param x reference to x axis
  740. @param y reference to y axis
  741. @param z reference to z axis
  742. @returns 1 if success, 0 if not
  743. */
  744. int Adafruit_LSM6DS::readGyroscope(float &x, float &y, float &z) {
  745. int16_t data[3];
  746. Adafruit_BusIO_Register gyro_data = Adafruit_BusIO_Register(
  747. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_OUTX_L_G, 6);
  748. if (!gyro_data.read((uint8_t *)data, sizeof(data))) {
  749. x = y = z = NAN;
  750. return 0;
  751. }
  752. // scale to range of -2000 – 2000
  753. x = data[0] * 2000.0 / 32768.0;
  754. y = data[1] * 2000.0 / 32768.0;
  755. z = data[2] * 2000.0 / 32768.0;
  756. return 1;
  757. }