Adafruit_LSM9DS0.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. /*!
  2. * @file Adafruit_LSM9DS0.cpp
  3. *
  4. * @mainpage Adafruit LSM9DS0 Accelerometer
  5. *
  6. * @section intro_sec Introduction
  7. *
  8. * This is a library for the LSM9DS0 Accelerometer and magnentometer/compass
  9. *
  10. * Designed specifically to work with the Adafruit LSM9DS0 Breakouts
  11. *
  12. * These sensors use I2C to communicate, 2 pins are required to interface.
  13. *
  14. * Adafruit invests time and resources providing this open source code,
  15. * please support Adafruit andopen-source hardware by purchasing products
  16. * from Adafruit!
  17. *
  18. * @section author Author
  19. *
  20. * Written by Kevin Townsend for Adafruit Industries.
  21. *
  22. * @section license License
  23. *
  24. * BSD license, all text above must be included in any redistribution
  25. *
  26. */
  27. #include <Adafruit_LSM9DS0.h>
  28. /***************************************************************************
  29. CONSTRUCTOR
  30. ***************************************************************************/
  31. void Adafruit_LSM9DS0::initI2C(TwoWire *wireBus, int32_t sensorID) {
  32. _i2c = true;
  33. _wire = wireBus;
  34. _lsm9dso_sensorid_accel = sensorID + 1;
  35. _lsm9dso_sensorid_mag = sensorID + 2;
  36. _lsm9dso_sensorid_gyro = sensorID + 3;
  37. _lsm9dso_sensorid_temp = sensorID + 4;
  38. _accelSensor = Sensor(this, &Adafruit_LSM9DS0::readAccel,
  39. &Adafruit_LSM9DS0::getAccelEvent,
  40. &Adafruit_LSM9DS0::getAccelSensor);
  41. _magSensor =
  42. Sensor(this, &Adafruit_LSM9DS0::readMag, &Adafruit_LSM9DS0::getMagEvent,
  43. &Adafruit_LSM9DS0::getMagSensor);
  44. _gyroSensor =
  45. Sensor(this, &Adafruit_LSM9DS0::readGyro, &Adafruit_LSM9DS0::getGyroEvent,
  46. &Adafruit_LSM9DS0::getGyroSensor);
  47. _tempSensor =
  48. Sensor(this, &Adafruit_LSM9DS0::readTemp, &Adafruit_LSM9DS0::getTempEvent,
  49. &Adafruit_LSM9DS0::getTempSensor);
  50. }
  51. /**************************************************************************/
  52. /*!
  53. @brief Instantiate with default hardware I2C interface
  54. @param sensorID Unique identifier you'd like for the sensors
  55. */
  56. /**************************************************************************/
  57. Adafruit_LSM9DS0::Adafruit_LSM9DS0(int32_t sensorID) {
  58. initI2C(&Wire, sensorID);
  59. }
  60. /**************************************************************************/
  61. /*!
  62. @brief Instantiate with hardware I2C interface
  63. @param wireBus The I2C wire interface you'd like to use
  64. @param sensorID Unique identifier you'd like for the sensors
  65. */
  66. /**************************************************************************/
  67. Adafruit_LSM9DS0::Adafruit_LSM9DS0(TwoWire *wireBus, int32_t sensorID) {
  68. initI2C(wireBus, sensorID);
  69. }
  70. /**************************************************************************/
  71. /*!
  72. @brief Instantiate with hardware SPI interface
  73. @param xmcs SPI CS pin for accelerometer/mag subchip
  74. @param gcs SPI CS pin for gyro subchip
  75. @param sensorID Unique identifier you'd like for the sensors
  76. */
  77. /**************************************************************************/
  78. Adafruit_LSM9DS0::Adafruit_LSM9DS0(int8_t xmcs, int8_t gcs, int32_t sensorID) {
  79. _i2c = false;
  80. // hardware SPI!
  81. _csg = gcs;
  82. _csxm = xmcs;
  83. _mosi = _miso = _clk = -1;
  84. _lsm9dso_sensorid_accel = sensorID + 1;
  85. _lsm9dso_sensorid_mag = sensorID + 2;
  86. _lsm9dso_sensorid_gyro = sensorID + 3;
  87. _lsm9dso_sensorid_temp = sensorID + 4;
  88. _accelSensor = Sensor(this, &Adafruit_LSM9DS0::readAccel,
  89. &Adafruit_LSM9DS0::getAccelEvent,
  90. &Adafruit_LSM9DS0::getAccelSensor);
  91. _magSensor =
  92. Sensor(this, &Adafruit_LSM9DS0::readMag, &Adafruit_LSM9DS0::getMagEvent,
  93. &Adafruit_LSM9DS0::getMagSensor);
  94. _gyroSensor =
  95. Sensor(this, &Adafruit_LSM9DS0::readGyro, &Adafruit_LSM9DS0::getGyroEvent,
  96. &Adafruit_LSM9DS0::getGyroSensor);
  97. _tempSensor =
  98. Sensor(this, &Adafruit_LSM9DS0::readTemp, &Adafruit_LSM9DS0::getTempEvent,
  99. &Adafruit_LSM9DS0::getTempSensor);
  100. }
  101. /**************************************************************************/
  102. /*!
  103. @brief Instantiate with software SPI interface
  104. @param clk SPI clock pin
  105. @param miso SPI MISO pin
  106. @param mosi SPI MOSI pin
  107. @param xmcs SPI CS pin for accelerometer/mag subchip
  108. @param gcs SPI CS pin for gyro subchip
  109. @param sensorID Unique identifier you'd like for the sensors
  110. */
  111. /**************************************************************************/
  112. Adafruit_LSM9DS0::Adafruit_LSM9DS0(int8_t clk, int8_t miso, int8_t mosi,
  113. int8_t xmcs, int8_t gcs, int32_t sensorID) {
  114. _i2c = false;
  115. // software SPI!
  116. _csg = gcs;
  117. _csxm = xmcs;
  118. _mosi = mosi;
  119. _miso = miso;
  120. _clk = clk;
  121. _lsm9dso_sensorid_accel = sensorID + 1;
  122. _lsm9dso_sensorid_mag = sensorID + 2;
  123. _lsm9dso_sensorid_gyro = sensorID + 3;
  124. _lsm9dso_sensorid_temp = sensorID + 4;
  125. _accelSensor = Sensor(this, &Adafruit_LSM9DS0::readAccel,
  126. &Adafruit_LSM9DS0::getAccelEvent,
  127. &Adafruit_LSM9DS0::getAccelSensor);
  128. _magSensor =
  129. Sensor(this, &Adafruit_LSM9DS0::readMag, &Adafruit_LSM9DS0::getMagEvent,
  130. &Adafruit_LSM9DS0::getMagSensor);
  131. _gyroSensor =
  132. Sensor(this, &Adafruit_LSM9DS0::readGyro, &Adafruit_LSM9DS0::getGyroEvent,
  133. &Adafruit_LSM9DS0::getGyroSensor);
  134. _tempSensor =
  135. Sensor(this, &Adafruit_LSM9DS0::readTemp, &Adafruit_LSM9DS0::getTempEvent,
  136. &Adafruit_LSM9DS0::getTempSensor);
  137. }
  138. /**************************************************************************/
  139. /*!
  140. @brief Initialize I2C or SPI and detect/initialize subsensors
  141. @returns True if both subsensors were detected on the desired interface
  142. */
  143. /**************************************************************************/
  144. bool Adafruit_LSM9DS0::begin() {
  145. if (_i2c) {
  146. _wire->begin();
  147. } else if (_clk == -1) {
  148. // Hardware SPI
  149. pinMode(_csxm, OUTPUT);
  150. pinMode(_csg, OUTPUT);
  151. digitalWrite(_csxm, HIGH);
  152. digitalWrite(_csg, HIGH);
  153. SPI.begin();
  154. } else {
  155. // Sofware SPI
  156. pinMode(_clk, OUTPUT);
  157. pinMode(_mosi, OUTPUT);
  158. pinMode(_csxm, OUTPUT);
  159. pinMode(_csg, OUTPUT);
  160. digitalWrite(_csxm, HIGH);
  161. digitalWrite(_csg, HIGH);
  162. digitalWrite(_clk, HIGH);
  163. }
  164. uint8_t id = read8(XMTYPE, LSM9DS0_REGISTER_WHO_AM_I_XM);
  165. // Serial.print ("XM whoami: 0x");
  166. // Serial.println(id, HEX);
  167. if (id != LSM9DS0_XM_ID)
  168. return false;
  169. id = read8(GYROTYPE, LSM9DS0_REGISTER_WHO_AM_I_G);
  170. // Serial.print ("G whoami: 0x");
  171. // Serial.println(id, HEX);
  172. if (id != LSM9DS0_G_ID)
  173. return false;
  174. // Enable the accelerometer continous
  175. write8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG1_XM, 0x67); // 100hz XYZ
  176. write8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG5_XM, 0b11110000);
  177. // enable mag continuous
  178. write8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG7_XM, 0b00000000);
  179. // enable gyro continuous
  180. write8(GYROTYPE, LSM9DS0_REGISTER_CTRL_REG1_G, 0x0F); // on XYZ
  181. // enable the temperature sensor (output rate same as the mag sensor)
  182. uint8_t tempReg = read8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG5_XM);
  183. write8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG5_XM, tempReg | (1 << 7));
  184. /*
  185. for (uint8_t i=0; i<0x30; i++) {
  186. Serial.print("$"); Serial.print(i, HEX);
  187. Serial.print(" = 0x");
  188. Serial.println(read8(XMTYPE, i), HEX);
  189. }
  190. */
  191. // Set default ranges for the various sensors
  192. setupAccel(LSM9DS0_ACCELRANGE_2G);
  193. setupMag(LSM9DS0_MAGGAIN_2GAUSS);
  194. setupGyro(LSM9DS0_GYROSCALE_245DPS);
  195. return true;
  196. }
  197. /***************************************************************************
  198. PUBLIC FUNCTIONS
  199. ***************************************************************************/
  200. /**************************************************************************/
  201. /*!
  202. @brief Read all four sensor subcomponents
  203. */
  204. /**************************************************************************/
  205. void Adafruit_LSM9DS0::read() {
  206. /* Read all the sensors. */
  207. readAccel();
  208. readMag();
  209. readGyro();
  210. readTemp();
  211. }
  212. /**************************************************************************/
  213. /*!
  214. @brief Read the sensor accelerometer sensor component
  215. */
  216. /**************************************************************************/
  217. void Adafruit_LSM9DS0::readAccel() {
  218. // Read the accelerometer
  219. byte buffer[6];
  220. readBuffer(XMTYPE, 0x80 | LSM9DS0_REGISTER_OUT_X_L_A, 6, buffer);
  221. uint8_t xlo = buffer[0];
  222. int16_t xhi = buffer[1];
  223. uint8_t ylo = buffer[2];
  224. int16_t yhi = buffer[3];
  225. uint8_t zlo = buffer[4];
  226. int16_t zhi = buffer[5];
  227. // Shift values to create properly formed integer (low byte first)
  228. xhi <<= 8;
  229. xhi |= xlo;
  230. yhi <<= 8;
  231. yhi |= ylo;
  232. zhi <<= 8;
  233. zhi |= zlo;
  234. accelData.x = xhi;
  235. accelData.y = yhi;
  236. accelData.z = zhi;
  237. }
  238. /**************************************************************************/
  239. /*!
  240. @brief Read the sensor magnetometer sensor component
  241. */
  242. /**************************************************************************/
  243. void Adafruit_LSM9DS0::readMag() {
  244. // Read the magnetometer
  245. byte buffer[6];
  246. readBuffer(XMTYPE, 0x80 | LSM9DS0_REGISTER_OUT_X_L_M, 6, buffer);
  247. uint8_t xlo = buffer[0];
  248. int16_t xhi = buffer[1];
  249. uint8_t ylo = buffer[2];
  250. int16_t yhi = buffer[3];
  251. uint8_t zlo = buffer[4];
  252. int16_t zhi = buffer[5];
  253. // Shift values to create properly formed integer (low byte first)
  254. xhi <<= 8;
  255. xhi |= xlo;
  256. yhi <<= 8;
  257. yhi |= ylo;
  258. zhi <<= 8;
  259. zhi |= zlo;
  260. magData.x = xhi;
  261. magData.y = yhi;
  262. magData.z = zhi;
  263. }
  264. /**************************************************************************/
  265. /*!
  266. @brief Read the sensor gyroscope sensor component
  267. */
  268. /**************************************************************************/
  269. void Adafruit_LSM9DS0::readGyro() {
  270. // Read gyro
  271. byte buffer[6];
  272. readBuffer(GYROTYPE, 0x80 | LSM9DS0_REGISTER_OUT_X_L_G, 6, buffer);
  273. uint8_t xlo = buffer[0];
  274. int16_t xhi = buffer[1];
  275. uint8_t ylo = buffer[2];
  276. int16_t yhi = buffer[3];
  277. uint8_t zlo = buffer[4];
  278. int16_t zhi = buffer[5];
  279. // Shift values to create properly formed integer (low byte first)
  280. xhi <<= 8;
  281. xhi |= xlo;
  282. yhi <<= 8;
  283. yhi |= ylo;
  284. zhi <<= 8;
  285. zhi |= zlo;
  286. gyroData.x = xhi;
  287. gyroData.y = yhi;
  288. gyroData.z = zhi;
  289. }
  290. /**************************************************************************/
  291. /*!
  292. @brief Read the sensor temperature sensor component
  293. */
  294. /**************************************************************************/
  295. void Adafruit_LSM9DS0::readTemp() {
  296. // Read temp sensor
  297. byte buffer[2];
  298. readBuffer(XMTYPE, 0x80 | LSM9DS0_REGISTER_TEMP_OUT_L_XM, 2, buffer);
  299. uint8_t xlo = buffer[0];
  300. int16_t xhi = buffer[1];
  301. xhi <<= 8;
  302. xhi |= xlo;
  303. // Shift values to create properly formed integer (low byte first)
  304. temperature = xhi;
  305. }
  306. /**************************************************************************/
  307. /*!
  308. @brief Configure the accelerometer ranging
  309. @param range Can be LSM9DS0_ACCELRANGE_2G, LSM9DS0_ACCELRANGE_4G,
  310. LSM9DS0_ACCELRANGE_6G, LSM9DS0_ACCELRANGE_8G, LSM9DS0_ACCELRANGE_16G
  311. */
  312. /**************************************************************************/
  313. void Adafruit_LSM9DS0::setupAccel(lsm9ds0AccelRange_t range) {
  314. uint8_t reg = read8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG2_XM);
  315. reg &= ~(0b00111000);
  316. reg |= range;
  317. write8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG2_XM, reg);
  318. switch (range) {
  319. case LSM9DS0_ACCELRANGE_2G:
  320. _accel_mg_lsb = LSM9DS0_ACCEL_MG_LSB_2G;
  321. break;
  322. case LSM9DS0_ACCELRANGE_4G:
  323. _accel_mg_lsb = LSM9DS0_ACCEL_MG_LSB_4G;
  324. break;
  325. case LSM9DS0_ACCELRANGE_6G:
  326. _accel_mg_lsb = LSM9DS0_ACCEL_MG_LSB_6G;
  327. break;
  328. case LSM9DS0_ACCELRANGE_8G:
  329. _accel_mg_lsb = LSM9DS0_ACCEL_MG_LSB_8G;
  330. break;
  331. case LSM9DS0_ACCELRANGE_16G:
  332. _accel_mg_lsb = LSM9DS0_ACCEL_MG_LSB_16G;
  333. break;
  334. }
  335. }
  336. /**************************************************************************/
  337. /*!
  338. @brief Configure the magnetometer gain
  339. @param gain Can be LSM9DS0_MAGGAIN_2GAUSS, LSM9DS0_MAGGAIN_4GAUSS,
  340. LSM9DS0_MAGGAIN_8GAUSS, LSM9DS0_MAGGAIN_12GAUSS
  341. */
  342. /**************************************************************************/
  343. void Adafruit_LSM9DS0::setupMag(lsm9ds0MagGain_t gain) {
  344. uint8_t reg = read8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG6_XM);
  345. reg &= ~(0b01100000);
  346. reg |= gain;
  347. write8(XMTYPE, LSM9DS0_REGISTER_CTRL_REG6_XM, reg);
  348. switch (gain) {
  349. case LSM9DS0_MAGGAIN_2GAUSS:
  350. _mag_mgauss_lsb = LSM9DS0_MAG_MGAUSS_2GAUSS;
  351. break;
  352. case LSM9DS0_MAGGAIN_4GAUSS:
  353. _mag_mgauss_lsb = LSM9DS0_MAG_MGAUSS_4GAUSS;
  354. break;
  355. case LSM9DS0_MAGGAIN_8GAUSS:
  356. _mag_mgauss_lsb = LSM9DS0_MAG_MGAUSS_8GAUSS;
  357. break;
  358. case LSM9DS0_MAGGAIN_12GAUSS:
  359. _mag_mgauss_lsb = LSM9DS0_MAG_MGAUSS_12GAUSS;
  360. break;
  361. }
  362. }
  363. /**************************************************************************/
  364. /*!
  365. @brief Configure the gyroscope scaling
  366. @param scale Can be LSM9DS0_GYROSCALE_245DPS, LSM9DS0_GYROSCALE_500DPS
  367. or LSM9DS0_GYROSCALE_2000DPS
  368. */
  369. /**************************************************************************/
  370. void Adafruit_LSM9DS0::setupGyro(lsm9ds0GyroScale_t scale) {
  371. uint8_t reg = read8(GYROTYPE, LSM9DS0_REGISTER_CTRL_REG4_G);
  372. reg &= ~(0b00110000);
  373. reg |= scale;
  374. write8(GYROTYPE, LSM9DS0_REGISTER_CTRL_REG4_G, reg);
  375. switch (scale) {
  376. case LSM9DS0_GYROSCALE_245DPS:
  377. _gyro_dps_digit = LSM9DS0_GYRO_DPS_DIGIT_245DPS;
  378. break;
  379. case LSM9DS0_GYROSCALE_500DPS:
  380. _gyro_dps_digit = LSM9DS0_GYRO_DPS_DIGIT_500DPS;
  381. break;
  382. case LSM9DS0_GYROSCALE_2000DPS:
  383. _gyro_dps_digit = LSM9DS0_GYRO_DPS_DIGIT_2000DPS;
  384. break;
  385. }
  386. }
  387. /***************************************************************************
  388. UNIFIED SENSOR FUNCTIONS
  389. ***************************************************************************/
  390. /**************************************************************************/
  391. /*!
  392. @brief Gets the most recent accel sensor events for all 4 sensors
  393. @param accelEvent The accelerometer event object we will fill, pass NULL to
  394. skip
  395. @param magEvent The magnetometer event object we will fill, pass NULL to
  396. skip
  397. @param gyroEvent The gyroscope event object we will fill, pass NULL to skip
  398. @param tempEvent The temperature event object we will fill, pass NULL to
  399. skip
  400. @returns True on successful reads
  401. */
  402. /**************************************************************************/
  403. bool Adafruit_LSM9DS0::getEvent(sensors_event_t *accelEvent,
  404. sensors_event_t *magEvent,
  405. sensors_event_t *gyroEvent,
  406. sensors_event_t *tempEvent) {
  407. /* Grab new sensor reading and timestamp. */
  408. read();
  409. uint32_t timestamp = millis();
  410. /* Update appropriate sensor events. */
  411. if (accelEvent)
  412. getAccelEvent(accelEvent, timestamp);
  413. if (magEvent)
  414. getMagEvent(magEvent, timestamp);
  415. if (gyroEvent)
  416. getGyroEvent(gyroEvent, timestamp);
  417. if (tempEvent)
  418. getTempEvent(tempEvent, timestamp);
  419. return true;
  420. }
  421. /**************************************************************************/
  422. /*!
  423. @brief Gets the sensor_t data for all 4 sub-sensors at once call
  424. @param accel The accelerometer sensor_t object we will fill, pass NULL to
  425. skip
  426. @param mag The magnetometer sensor_t object we will fill, pass NULL to skip
  427. @param gyro The gyroscope sensor_t object we will fill, pass NULL to skip
  428. @param temp The temperature sensor_t object we will fill, pass NULL to skip
  429. */
  430. /**************************************************************************/
  431. void Adafruit_LSM9DS0::getSensor(sensor_t *accel, sensor_t *mag, sensor_t *gyro,
  432. sensor_t *temp) {
  433. /* Update appropriate sensor metadata. */
  434. if (accel)
  435. getAccelSensor(accel);
  436. if (mag)
  437. getMagSensor(mag);
  438. if (gyro)
  439. getGyroSensor(gyro);
  440. if (temp)
  441. getTempSensor(temp);
  442. }
  443. /***************************************************************************
  444. PRIVATE FUNCTIONS
  445. ***************************************************************************/
  446. void Adafruit_LSM9DS0::write8(boolean type, byte reg, byte value) {
  447. byte address, _cs;
  448. if (type == GYROTYPE) {
  449. address = LSM9DS0_ADDRESS_GYRO;
  450. _cs = _csg;
  451. } else {
  452. address = LSM9DS0_ADDRESS_ACCELMAG;
  453. _cs = _csxm;
  454. }
  455. if (_i2c) {
  456. _wire->beginTransmission(address);
  457. _wire->write(reg);
  458. _wire->write(value);
  459. _wire->endTransmission();
  460. } else {
  461. SPI.beginTransaction(SPISettings(200000, MSBFIRST, SPI_MODE0));
  462. digitalWrite(_cs, LOW);
  463. // set address
  464. spixfer(reg | 0x40); // write multiple
  465. spixfer(value);
  466. digitalWrite(_cs, HIGH);
  467. SPI.endTransaction();
  468. }
  469. }
  470. byte Adafruit_LSM9DS0::read8(boolean type, byte reg) {
  471. uint8_t value;
  472. readBuffer(type, reg, 1, &value);
  473. return value;
  474. }
  475. byte Adafruit_LSM9DS0::readBuffer(boolean type, byte reg, byte len,
  476. uint8_t *buffer) {
  477. byte address, _cs;
  478. if (type == GYROTYPE) {
  479. address = LSM9DS0_ADDRESS_GYRO;
  480. _cs = _csg;
  481. } else {
  482. address = LSM9DS0_ADDRESS_ACCELMAG;
  483. _cs = _csxm;
  484. }
  485. if (_i2c) {
  486. #ifdef __SAM3X8E__
  487. _wire->requestFrom(
  488. address, len, reg, 1,
  489. true); // see
  490. // http://forum.arduino.cc/index.php?topic=385377.msg2947227#msg2947227
  491. #else
  492. _wire->beginTransmission(address);
  493. _wire->write(reg);
  494. _wire->endTransmission();
  495. _wire->requestFrom(address, (byte)len);
  496. #endif
  497. for (uint8_t i = 0; i < len; i++) {
  498. buffer[i] = _wire->read();
  499. }
  500. } else {
  501. SPI.beginTransaction(SPISettings(200000, MSBFIRST, SPI_MODE0));
  502. digitalWrite(_cs, LOW);
  503. // set address
  504. spixfer(reg | 0x80 | 0x40); // read multiple
  505. for (uint8_t i = 0; i < len; i++) {
  506. buffer[i] = spixfer(0);
  507. }
  508. digitalWrite(_cs, HIGH);
  509. SPI.endTransaction();
  510. }
  511. return len;
  512. }
  513. uint8_t Adafruit_LSM9DS0::spixfer(uint8_t data) {
  514. if (_clk == -1) {
  515. // Serial.println("Hardware SPI");
  516. return SPI.transfer(data);
  517. } else {
  518. // Serial.println("Software SPI");
  519. uint8_t reply = 0;
  520. for (int i = 7; i >= 0; i--) {
  521. reply <<= 1;
  522. digitalWrite(_clk, LOW);
  523. digitalWrite(_mosi, data & (1 << i));
  524. digitalWrite(_clk, HIGH);
  525. if (digitalRead(_miso))
  526. reply |= 1;
  527. }
  528. return reply;
  529. }
  530. }
  531. /**************************************************************************/
  532. /*!
  533. @brief Fill in the details about the most recent accelerometer data read
  534. @param event The sensor_event_t object we will fill!
  535. @param timestamp Unused
  536. */
  537. /**************************************************************************/
  538. void Adafruit_LSM9DS0::getAccelEvent(sensors_event_t *event,
  539. uint32_t timestamp) {
  540. memset(event, 0, sizeof(sensors_event_t));
  541. event->version = sizeof(sensors_event_t);
  542. event->sensor_id = _lsm9dso_sensorid_accel;
  543. event->type = SENSOR_TYPE_ACCELEROMETER;
  544. event->timestamp = timestamp;
  545. event->acceleration.x = accelData.x * _accel_mg_lsb;
  546. event->acceleration.x /= 1000;
  547. event->acceleration.x *= SENSORS_GRAVITY_STANDARD;
  548. event->acceleration.y = accelData.y * _accel_mg_lsb;
  549. event->acceleration.y /= 1000;
  550. event->acceleration.y *= SENSORS_GRAVITY_STANDARD;
  551. event->acceleration.z = accelData.z * _accel_mg_lsb;
  552. event->acceleration.z /= 1000;
  553. event->acceleration.z *= SENSORS_GRAVITY_STANDARD;
  554. }
  555. /**************************************************************************/
  556. /*!
  557. @brief Fill in the details about the most recent magnetometer data read
  558. @param event The sensor_event_t object we will fill!
  559. @param timestamp Unused
  560. */
  561. /**************************************************************************/
  562. void Adafruit_LSM9DS0::getMagEvent(sensors_event_t *event, uint32_t timestamp) {
  563. memset(event, 0, sizeof(sensors_event_t));
  564. event->version = sizeof(sensors_event_t);
  565. event->sensor_id = _lsm9dso_sensorid_mag;
  566. event->type = SENSOR_TYPE_MAGNETIC_FIELD;
  567. event->timestamp = timestamp;
  568. event->magnetic.x = magData.x * _mag_mgauss_lsb / 10;
  569. event->magnetic.y = magData.y * _mag_mgauss_lsb / 10;
  570. event->magnetic.z = magData.z * _mag_mgauss_lsb / 10;
  571. }
  572. /**************************************************************************/
  573. /*!
  574. @brief Fill in the details about the most recent gyroscope data read
  575. @param event The sensor_event_t object we will fill!
  576. @param timestamp The millis timestamp when the read occured
  577. */
  578. /**************************************************************************/
  579. void Adafruit_LSM9DS0::getGyroEvent(sensors_event_t *event,
  580. uint32_t timestamp) {
  581. memset(event, 0, sizeof(sensors_event_t));
  582. event->version = sizeof(sensors_event_t);
  583. event->sensor_id = _lsm9dso_sensorid_accel;
  584. event->type = SENSOR_TYPE_GYROSCOPE;
  585. event->timestamp = timestamp;
  586. event->gyro.x = gyroData.x * _gyro_dps_digit * SENSORS_DPS_TO_RADS;
  587. event->gyro.y = gyroData.y * _gyro_dps_digit * SENSORS_DPS_TO_RADS;
  588. event->gyro.z = gyroData.z * _gyro_dps_digit * SENSORS_DPS_TO_RADS;
  589. }
  590. /**************************************************************************/
  591. /*!
  592. @brief Fill in the details about the most recent temperature data read
  593. @param event The sensor_event_t object we will fill!
  594. @param timestamp The millis timestamp when the read occured
  595. */
  596. /**************************************************************************/
  597. void Adafruit_LSM9DS0::getTempEvent(sensors_event_t *event,
  598. uint32_t timestamp) {
  599. memset(event, 0, sizeof(sensors_event_t));
  600. event->version = sizeof(sensors_event_t);
  601. event->sensor_id = _lsm9dso_sensorid_temp;
  602. event->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
  603. event->timestamp = timestamp;
  604. // This is just a guess since the staring point (21C here) isn't documented :(
  605. event->temperature = 21.0 + (float)temperature / 8;
  606. // event->temperature /= LSM9DS0_TEMP_LSB_DEGREE_CELSIUS;
  607. }
  608. /**************************************************************************/
  609. /*!
  610. @brief Fill in the details about the accelerometer sensor component
  611. @param sensor The sensor_t object we will fill!
  612. */
  613. /**************************************************************************/
  614. void Adafruit_LSM9DS0::getAccelSensor(sensor_t *sensor) {
  615. memset(sensor, 0, sizeof(sensor_t));
  616. strncpy(sensor->name, "LSM9DS0_A", sizeof(sensor->name) - 1);
  617. sensor->name[sizeof(sensor->name) - 1] = 0;
  618. sensor->version = 1;
  619. sensor->sensor_id = _lsm9dso_sensorid_accel;
  620. sensor->type = SENSOR_TYPE_ACCELEROMETER;
  621. sensor->min_delay = 0;
  622. sensor->max_value = 0.0; // ToDo
  623. sensor->min_value = 0.0; // ToDo
  624. sensor->resolution = 0.0; // ToDo
  625. }
  626. /**************************************************************************/
  627. /*!
  628. @brief Fill in the details about the magnetometer sensor component
  629. @param sensor The sensor_t object we will fill!
  630. */
  631. /**************************************************************************/
  632. void Adafruit_LSM9DS0::getMagSensor(sensor_t *sensor) {
  633. memset(sensor, 0, sizeof(sensor_t));
  634. strncpy(sensor->name, "LSM9DS0_M", sizeof(sensor->name) - 1);
  635. sensor->name[sizeof(sensor->name) - 1] = 0;
  636. sensor->version = 1;
  637. sensor->sensor_id = _lsm9dso_sensorid_mag;
  638. sensor->type = SENSOR_TYPE_MAGNETIC_FIELD;
  639. sensor->min_delay = 0;
  640. sensor->max_value = 0.0; // ToDo
  641. sensor->min_value = 0.0; // ToDo
  642. sensor->resolution = 0.0; // ToDo
  643. }
  644. /**************************************************************************/
  645. /*!
  646. @brief Fill in the details about the gyroscope sensor component
  647. @param sensor The sensor_t object we will fill!
  648. */
  649. /**************************************************************************/
  650. void Adafruit_LSM9DS0::getGyroSensor(sensor_t *sensor) {
  651. memset(sensor, 0, sizeof(sensor_t));
  652. strncpy(sensor->name, "LSM9DS0_G", sizeof(sensor->name) - 1);
  653. sensor->name[sizeof(sensor->name) - 1] = 0;
  654. sensor->version = 1;
  655. sensor->sensor_id = _lsm9dso_sensorid_gyro;
  656. sensor->type = SENSOR_TYPE_GYROSCOPE;
  657. sensor->min_delay = 0;
  658. sensor->max_value = 0.0; // ToDo
  659. sensor->min_value = 0.0; // ToDo
  660. sensor->resolution = 0.0; // ToDo
  661. }
  662. /**************************************************************************/
  663. /*!
  664. @brief Fill in the details about the temperature sensor component
  665. @param sensor The sensor_t object we will fill!
  666. */
  667. /**************************************************************************/
  668. void Adafruit_LSM9DS0::getTempSensor(sensor_t *sensor) {
  669. memset(sensor, 0, sizeof(sensor_t));
  670. strncpy(sensor->name, "LSM9DS0_T", sizeof(sensor->name) - 1);
  671. sensor->name[sizeof(sensor->name) - 1] = 0;
  672. sensor->version = 1;
  673. sensor->sensor_id = _lsm9dso_sensorid_temp;
  674. sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
  675. sensor->min_delay = 0;
  676. sensor->max_value = 0.0; // ToDo
  677. sensor->min_value = 0.0; // ToDo
  678. sensor->resolution = 0.0; // ToDo
  679. }