Adafruit_LPS2X.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*!
  2. * @file Adafruit_LPS2X.cpp
  3. *
  4. * @mainpage Library for the LPS2X family of barometric pressure sensors
  5. *
  6. * @section intro_sec Introduction
  7. *
  8. * I2C Driver for the Library for the LPS2X family of barometric pressure
  9. * sensors
  10. *
  11. * This is a library for the Adafruit LPS2X breakout:
  12. * https://www.adafruit.com/product/45XX
  13. *
  14. * Adafruit invests time and resources providing this open source code,
  15. * please support Adafruit and open-source hardware by purchasing products from
  16. * Adafruit!
  17. *
  18. * @section dependencies Dependencies
  19. * This library depends on the Adafruit BusIO library
  20. *
  21. * This library depends on the Adafruit Unified Sensor library
  22. *
  23. * @section author Author
  24. *
  25. * Bryan Siepert for Adafruit Industries
  26. *
  27. * @section license License
  28. *
  29. * BSD (see license.txt)
  30. *
  31. * @section HISTORY
  32. *
  33. * v1.0 - First release
  34. */
  35. #include "Arduino.h"
  36. #include <Wire.h>
  37. #include "Adafruit_LPS2X.h"
  38. /**
  39. * @brief Construct a new Adafruit_LPS2X::Adafruit_LPS2X object
  40. *
  41. */
  42. Adafruit_LPS2X::Adafruit_LPS2X(void) {}
  43. /*!
  44. * @brief Sets up the hardware and initializes I2C
  45. * @param i2c_address
  46. * The I2C address to be used.
  47. * @param wire
  48. * The Wire object to be used for I2C connections.
  49. * @param sensor_id
  50. * The unique ID to differentiate the sensors from others
  51. * @return True if initialization was successful, otherwise false.
  52. */
  53. bool Adafruit_LPS2X::begin_I2C(uint8_t i2c_address, TwoWire *wire,
  54. int32_t sensor_id) {
  55. spi_dev = NULL;
  56. if (i2c_dev) {
  57. delete i2c_dev; // remove old interface
  58. }
  59. i2c_dev = new Adafruit_I2CDevice(i2c_address, wire);
  60. if (!i2c_dev->begin()) {
  61. return false;
  62. }
  63. return _init(sensor_id);
  64. }
  65. /*!
  66. * @brief Sets up the hardware and initializes hardware SPI
  67. * @param cs_pin The arduino pin # connected to chip select
  68. * @param theSPI The SPI object to be used for SPI connections.
  69. * @param sensor_id
  70. * The user-defined ID to differentiate different sensors
  71. * @return True if initialization was successful, otherwise false.
  72. */
  73. bool Adafruit_LPS2X::begin_SPI(uint8_t cs_pin, SPIClass *theSPI,
  74. int32_t sensor_id) {
  75. i2c_dev = NULL;
  76. if (spi_dev) {
  77. delete spi_dev; // remove old interface
  78. }
  79. spi_dev = new Adafruit_SPIDevice(cs_pin,
  80. 1000000, // frequency
  81. SPI_BITORDER_MSBFIRST, // bit order
  82. SPI_MODE0, // data mode
  83. theSPI);
  84. if (!spi_dev->begin()) {
  85. return false;
  86. }
  87. return _init(sensor_id);
  88. }
  89. /*!
  90. * @brief Sets up the hardware and initializes software SPI
  91. * @param cs_pin The arduino pin # connected to chip select
  92. * @param sck_pin The arduino pin # connected to SPI clock
  93. * @param miso_pin The arduino pin # connected to SPI MISO
  94. * @param mosi_pin The arduino pin # connected to SPI MOSI
  95. * @param sensor_id
  96. * The user-defined ID to differentiate different sensors
  97. * @return True if initialization was successful, otherwise false.
  98. */
  99. bool Adafruit_LPS2X::begin_SPI(int8_t cs_pin, int8_t sck_pin, int8_t miso_pin,
  100. int8_t mosi_pin, int32_t sensor_id) {
  101. i2c_dev = NULL;
  102. if (spi_dev) {
  103. delete spi_dev; // remove old interface
  104. }
  105. spi_dev = new Adafruit_SPIDevice(cs_pin, sck_pin, miso_pin, mosi_pin,
  106. 1000000, // frequency
  107. SPI_BITORDER_MSBFIRST, // bit order
  108. SPI_MODE0); // data mode
  109. if (!spi_dev->begin()) {
  110. return false;
  111. }
  112. return _init(sensor_id);
  113. }
  114. /**
  115. * @brief Performs a software reset initializing registers to their power on
  116. * state
  117. */
  118. void Adafruit_LPS2X::reset(void) {
  119. Adafruit_BusIO_RegisterBits sw_reset =
  120. Adafruit_BusIO_RegisterBits(ctrl2_reg, 1, 2);
  121. sw_reset.write(1);
  122. while (sw_reset.read()) {
  123. delay(1);
  124. }
  125. }
  126. /**
  127. * @brief Set the pressure threshold register for interrupt levels
  128. * @param hPa_delta The u16 that will be written to the register, check the
  129. * datasheet for more info on the format of this value!
  130. */
  131. void Adafruit_LPS2X::setPresThreshold(uint16_t hPa_delta) {
  132. threshp_reg->write(hPa_delta);
  133. }
  134. /******************* Adafruit_Sensor functions *****************/
  135. /*!
  136. * @brief Updates the measurement data for all sensors simultaneously
  137. */
  138. /**************************************************************************/
  139. void Adafruit_LPS2X::_read(void) {
  140. // get raw readings
  141. uint8_t pressure_addr = LPS2X_PRESS_OUT_XL;
  142. uint8_t temp_addr = LPS2X_TEMP_OUT_L;
  143. if (spi_dev) {
  144. // for LPS25 SPI, addr[7] is r/w, addr[6] is auto increment
  145. pressure_addr |= inc_spi_flag;
  146. temp_addr |= inc_spi_flag;
  147. }
  148. // for one-shot mode, must manually initiate a reading
  149. if (isOneShot) {
  150. Adafruit_BusIO_RegisterBits oneshot_bit =
  151. Adafruit_BusIO_RegisterBits(ctrl2_reg, 1, 0);
  152. oneshot_bit.write(1); // initiate reading
  153. while (oneshot_bit.read())
  154. delay(1); // wait for completion
  155. }
  156. Adafruit_BusIO_Register pressure_data = Adafruit_BusIO_Register(
  157. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, pressure_addr, 3);
  158. Adafruit_BusIO_Register temp_data = Adafruit_BusIO_Register(
  159. i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, temp_addr, 2);
  160. uint8_t buffer[3];
  161. temp_data.read(buffer, 2);
  162. int16_t raw_temp;
  163. raw_temp = (int16_t)(buffer[1]);
  164. raw_temp <<= 8;
  165. raw_temp |= (int16_t)(buffer[0]);
  166. pressure_data.read(buffer, 3);
  167. int32_t raw_pressure;
  168. raw_pressure = (int32_t)buffer[2];
  169. raw_pressure <<= 8;
  170. raw_pressure |= (int32_t)(buffer[1]);
  171. raw_pressure <<= 8;
  172. raw_pressure |= (int32_t)(buffer[0]);
  173. if (raw_temp & 0x8000) {
  174. raw_temp = raw_temp - 0xFFFF;
  175. }
  176. _temp = (raw_temp / temp_scaling) + temp_offset;
  177. if (raw_pressure & 0x800000) {
  178. raw_pressure = raw_pressure - 0xFFFFFF;
  179. }
  180. _pressure = raw_pressure / 4096.0;
  181. }
  182. /*!
  183. @brief Gets an Adafruit Unified Sensor object for the presure sensor
  184. component
  185. @return Adafruit_Sensor pointer to pressure sensor
  186. */
  187. Adafruit_Sensor *Adafruit_LPS2X::getPressureSensor(void) {
  188. return pressure_sensor;
  189. }
  190. /*!
  191. @brief Gets an Adafruit Unified Sensor object for the temp sensor component
  192. @return Adafruit_Sensor pointer to temperature sensor
  193. */
  194. Adafruit_Sensor *Adafruit_LPS2X::getTemperatureSensor(void) {
  195. return temp_sensor;
  196. }
  197. /**************************************************************************/
  198. /*!
  199. @brief Gets the pressure sensor and temperature values as sensor events
  200. @param pressure Sensor event object that will be populated with pressure
  201. data
  202. @param temp Sensor event object that will be populated with temp data
  203. @returns True
  204. */
  205. /**************************************************************************/
  206. bool Adafruit_LPS2X::getEvent(sensors_event_t *pressure,
  207. sensors_event_t *temp) {
  208. uint32_t t = millis();
  209. _read();
  210. // use helpers to fill in the events
  211. fillPressureEvent(pressure, t);
  212. fillTempEvent(temp, t);
  213. return true;
  214. }
  215. void Adafruit_LPS2X::fillPressureEvent(sensors_event_t *pressure,
  216. uint32_t timestamp) {
  217. memset(pressure, 0, sizeof(sensors_event_t));
  218. pressure->version = sizeof(sensors_event_t);
  219. pressure->sensor_id = _sensorid_pressure;
  220. pressure->type = SENSOR_TYPE_PRESSURE;
  221. pressure->timestamp = timestamp;
  222. pressure->pressure = _pressure;
  223. }
  224. void Adafruit_LPS2X::fillTempEvent(sensors_event_t *temp, uint32_t timestamp) {
  225. memset(temp, 0, sizeof(sensors_event_t));
  226. temp->version = sizeof(sensors_event_t);
  227. temp->sensor_id = _sensorid_temp;
  228. temp->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
  229. temp->timestamp = timestamp;
  230. temp->temperature = _temp;
  231. }
  232. /**************************************************************************/
  233. /*!
  234. @brief Gets the sensor_t data for the LPS2X's tenperature
  235. @param sensor The allocated sensor_t that we will fill!
  236. */
  237. /**************************************************************************/
  238. void Adafruit_LPS2X_Pressure::getSensor(sensor_t *sensor) {
  239. /* Clear the sensor_t object */
  240. memset(sensor, 0, sizeof(sensor_t));
  241. /* Insert the sensor name in the fixed length char array */
  242. strncpy(sensor->name, "LPS2X_P", sizeof(sensor->name) - 1);
  243. sensor->name[sizeof(sensor->name) - 1] = 0;
  244. sensor->version = 1;
  245. sensor->sensor_id = _sensorID;
  246. sensor->type = SENSOR_TYPE_PRESSURE;
  247. sensor->min_delay = 0;
  248. sensor->min_value = 260;
  249. sensor->max_value = 1260;
  250. // 4096 LSB = 1 hPa >> 1 LSB = 1/4096 hPa >> 1 LSB = 2.441e-4 hPa
  251. sensor->resolution = 2.441e-4;
  252. }
  253. /**************************************************************************/
  254. /*!
  255. @brief Gets the pressure as a standard sensor event
  256. @param event Sensor event object that will be populated
  257. @returns True
  258. */
  259. /**************************************************************************/
  260. bool Adafruit_LPS2X_Pressure::getEvent(sensors_event_t *event) {
  261. _theLPS2X->_read();
  262. _theLPS2X->fillPressureEvent(event, millis());
  263. return true;
  264. }
  265. /**************************************************************************/
  266. /*!
  267. @brief Gets the sensor_t data for the LPS2X's tenperature
  268. @param sensor The allocated sensor_t that we will fill!
  269. */
  270. /**************************************************************************/
  271. void Adafruit_LPS2X_Temp::getSensor(sensor_t *sensor) {
  272. /* Clear the sensor_t object */
  273. memset(sensor, 0, sizeof(sensor_t));
  274. /* Insert the sensor name in the fixed length char array */
  275. strncpy(sensor->name, "LPS2X_T", sizeof(sensor->name) - 1);
  276. sensor->name[sizeof(sensor->name) - 1] = 0;
  277. sensor->version = 1;
  278. sensor->sensor_id = _sensorID;
  279. sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
  280. sensor->min_delay = 0;
  281. sensor->min_value = -30;
  282. sensor->max_value = 105;
  283. sensor->resolution = 0.00208;
  284. }
  285. /**************************************************************************/
  286. /*!
  287. @brief Gets the temperature as a standard sensor event
  288. @param event Sensor event object that will be populated
  289. @returns True
  290. */
  291. /**************************************************************************/
  292. bool Adafruit_LPS2X_Temp::getEvent(sensors_event_t *event) {
  293. _theLPS2X->_read();
  294. _theLPS2X->fillTempEvent(event, millis());
  295. return true;
  296. }