/ adafruit_mpl115a2.py
adafruit_mpl115a2.py
  1  # The MIT License (MIT)
  2  #
  3  # Copyright (c) 2017 Carter Nelson for Adafruit Industries
  4  #
  5  # Permission is hereby granted, free of charge, to any person obtaining a copy
  6  # of this software and associated documentation files (the "Software"), to deal
  7  # in the Software without restriction, including without limitation the rights
  8  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9  # copies of the Software, and to permit persons to whom the Software is
 10  # furnished to do so, subject to the following conditions:
 11  #
 12  # The above copyright notice and this permission notice shall be included in
 13  # all copies or substantial portions of the Software.
 14  #
 15  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 21  # THE SOFTWARE.
 22  """
 23  `adafruit_mpl115a2`
 24  ====================================================
 25  
 26  CircuitPython driver for MPL115A2 I2C Barometric Pressure/Temperature Sensor.
 27  
 28  * Author(s): Carter Nelson
 29  
 30  Implementation Notes
 31  --------------------
 32  
 33  **Hardware:**
 34  
 35  * `MPL115A2 I2C Barometric Pressure/Temperature Sensor <https://www.adafruit.com/product/992>`_
 36  
 37  **Software and Dependencies:**
 38  
 39  * Adafruit CircuitPython firmware for the supported boards:
 40    https://github.com/adafruit/circuitpython/releases
 41  * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
 42  """
 43  
 44  import time
 45  import struct
 46  import adafruit_bus_device.i2c_device as i2c_device
 47  from micropython import const
 48  
 49  __version__ = "0.0.0-auto.0"
 50  __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MPL115A2.git"
 51  
 52  # pylint: disable=bad-whitespace
 53  _MPL115A2_ADDRESS = const(0x60)
 54  _MPL115A2_REGISTER_PRESSURE_MSB = const(0x00)
 55  _MPL115A2_REGISTER_A0_COEFF_MSB = const(0x04)
 56  _MPL115A2_REGISTER_STARTCONVERSION = const(0x12)
 57  # pylint: enable=bad-whitespace
 58  
 59  
 60  class MPL115A2:
 61      """Driver for MPL115A2 I2C barometric pressure / temperature sensor."""
 62  
 63      def __init__(self, i2c, address=_MPL115A2_ADDRESS):
 64          self._i2c = i2c_device.I2CDevice(i2c, address)
 65          self._buf = bytearray(4)
 66          self._read_coefficients()
 67  
 68      @property
 69      def pressure(self):
 70          """The pressure in hPa."""
 71          return self._read()[0] * 10
 72  
 73      @property
 74      def temperature(self):
 75          """The temperature in deg C."""
 76          return self._read()[1]
 77  
 78      def _read_coefficients(self):
 79          # pylint: disable=invalid-name
 80          buf = bytearray(8)
 81          buf[0] = _MPL115A2_REGISTER_A0_COEFF_MSB
 82          with self._i2c as i2c:
 83              i2c.write(buf, end=1)
 84              i2c.readinto(buf)
 85          a0, b1, b2, c12 = struct.unpack(">hhhh", buf)
 86          c12 >>= 2
 87          # see datasheet pg. 9, do math
 88          self._a0 = a0 / 8
 89          self._b1 = b1 / 8192
 90          self._b2 = b2 / 16384
 91          self._c12 = c12 / 4194304
 92  
 93      def _read(self):
 94          # pylint: disable=invalid-name
 95          self._buf[0] = _MPL115A2_REGISTER_STARTCONVERSION
 96          self._buf[1] = 0x00  # why? see datasheet, pg. 9, fig. 4
 97          with self._i2c as i2c:
 98              i2c.write(self._buf, end=2)
 99              time.sleep(0.005)  # see datasheet, Conversion Time = 3ms MAX
100              self._buf[0] = _MPL115A2_REGISTER_PRESSURE_MSB
101              i2c.write(self._buf, end=1)
102              i2c.readinto(self._buf)
103          pressure, temp = struct.unpack(">HH", self._buf)
104          pressure >>= 6
105          temp >>= 6
106          # see datasheet pg. 6, eqn. 1, result in counts
107          pressure = self._a0 + (self._b1 + self._c12 * temp) * pressure + self._b2 * temp
108          # see datasheet pg. 6, eqn. 2, result in kPa
109          pressure = (65 / 1023) * pressure + 50
110          # stolen from arduino driver, result in deg C
111          temp = (temp - 498) / -5.35 + 25
112          return pressure, temp