/ adafruit_mprls.py
adafruit_mprls.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2018 ladyada 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_mprls` 24 ==================================================== 25 26 CircuitPython library to support Honeywell MPRLS digital pressure sensors 27 28 * Author(s): ladyada 29 30 Implementation Notes 31 -------------------- 32 33 **Hardware:** 34 35 **Software and Dependencies:** 36 37 * Adafruit CircuitPython firmware for the supported boards: 38 https://github.com/adafruit/circuitpython/releases 39 40 * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice 41 42 """ 43 44 # imports 45 46 __version__ = "0.0.0-auto.0" 47 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MPRLS.git" 48 49 50 import time 51 from adafruit_bus_device.i2c_device import I2CDevice 52 from digitalio import Direction 53 from micropython import const 54 55 # pylint: disable=bad-whitespace 56 _MPRLS_DEFAULT_ADDR = const(0x18) 57 # pylint: enable=bad-whitespace 58 59 60 class MPRLS: 61 """ 62 Driver base for the MPRLS pressure sensor 63 :param i2c_bus: The `busio.I2C` object to use. This is the only required parameter. 64 :param int addr: The optional I2C address, defaults to 0x18 65 :param microcontroller.Pin reset_pin: Optional digitalio pin for hardware resetting 66 :param microcontroller.Pin eoc_pin: Optional digitalio pin for getting End Of Conversion signal 67 :param float psi_min: The minimum pressure in PSI, defaults to 0 68 :param float psi_max: The maximum pressure in PSI, defaults to 25 69 """ 70 71 def __init__( 72 self, 73 i2c_bus, 74 *, 75 addr=_MPRLS_DEFAULT_ADDR, 76 reset_pin=None, 77 eoc_pin=None, 78 psi_min=0, 79 psi_max=25 80 ): 81 # Init I2C 82 self._i2c = I2CDevice(i2c_bus, addr) 83 self._buffer = bytearray(4) 84 85 # Optional hardware reset pin 86 if reset_pin is not None: 87 reset_pin.direction = Direction.OUTPUT 88 reset_pin.value = True 89 reset_pin.value = False 90 time.sleep(0.01) 91 reset_pin.value = True 92 time.sleep(0.005) # Start up timing 93 94 # Optional end-of-conversion pin 95 self._eoc = eoc_pin 96 if eoc_pin is not None: 97 self._eoc.direction = Direction.INPUT 98 99 if psi_min >= psi_max: 100 raise ValueError("Min PSI must be < max!") 101 self._psimax = psi_max 102 self._psimin = psi_min 103 # That's pretty much it, there's no ID register :( 104 105 @property 106 def pressure(self): 107 """The measured pressure, in hPa""" 108 return self._read_data() 109 110 def _read_data(self): 111 """Read the status & 24-bit data reading""" 112 self._buffer[0] = 0xAA 113 self._buffer[1] = 0 114 self._buffer[2] = 0 115 with self._i2c as i2c: 116 # send command 117 i2c.write(self._buffer, end=3) 118 # ready busy flag/status 119 while True: 120 # check End of Convert pin first, if we can 121 if self._eoc is not None: 122 if self._eoc.value: 123 break 124 # or you can read the status byte 125 i2c.readinto(self._buffer, end=1) 126 if not self._buffer[0] & 0x20: 127 break 128 # no longer busy! 129 i2c.readinto(self._buffer, end=4) 130 131 # check other status bits 132 if self._buffer[0] & 0x01: 133 raise RuntimeError("Internal math saturation") 134 if self._buffer[0] & 0x04: 135 raise RuntimeError("Integrity failure") 136 137 # All is good, calculate the PSI and convert to hPA 138 raw_psi = (self._buffer[1] << 16) | (self._buffer[2] << 8) | self._buffer[3] 139 # use the 10-90 calibration curve 140 psi = (raw_psi - 0x19999A) * (self._psimax - self._psimin) 141 psi /= 0xE66666 - 0x19999A 142 psi += self._psimin 143 # convert PSI to hPA 144 return psi * 68.947572932