diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/README.md b/README.md index 8cb51d6..56a876f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,73 @@ -# MLX90614 +# MicroPython MLX90614 -A MicroPython library for interfacing with a MLX90614 IR temperature sensor. +A MicroPython library for interfacing with a Melexis MLX90614 IR temperature sensor. + +For example, the [GY-906 module](https://www.aliexpress.com/item/GY-906-MLX90614ESF-New-MLX90614-Contactless-Temperature-Sensor-Module-For-Arduino-Compatible/32474869821.html). + +![demo](docs/GY-906-MLX90614.jpg) + +## Examples + +Copy the file to your device, using ampy, webrepl or compiling and deploying. eg. + +```bash +$ ampy put mlx90614.py +``` + +**Basic measurement** + +```python +import mlx90614 +from machine import I2C, Pin + +i2c = I2C(scl=Pin(5), sda=Pin(4)) +sensor = mlx90614.MLX90614(i2c) + +print(sensor.read_ambient_temp()) +print(sensor.read_object_temp()) +if sensor.dual_zone: + print(sensor.object2_temp) +``` + +**Continuous measurement** + +```python +import time +import mlx90614 +from machine import I2C, Pin + +i2c = I2C(scl=Pin(5), sda=Pin(4)) +sensor = mlx90614.MLX90614(i2c) + +while True: + print(sensor.read_ambient_temp(), sensor.read_object_temp()) + time.sleep_ms(500) +``` For full documentation see http://micropython-mlx90614.rtfd.io/. -![demo](docs/GY-906-MLX90614.jpg) \ No newline at end of file +## Parts + +* [WeMos D1 Mini](https://www.aliexpress.com/store/product/D1-mini-Mini-NodeMcu-4M-bytes-Lua-WIFI-Internet-of-Things-development-board-based-ESP8266/1331105_32529101036.html) $3.50 USD +* [GY-906 module](https://www.aliexpress.com/item/GY-906-MLX90614ESF-New-MLX90614-Contactless-Temperature-Sensor-Module-For-Arduino-Compatible/32474869821.html) $4.05 USD + +## Connections + +WeMos D1 Mini | GY-906 module +------------- | ---------- +D1 (GPIO5) | SCL +D2 (GPIO4) | SDA +3V3 | VCC +G | GND + +## Links + +* [MLX90614 product page](https://www.melexis.com/en/product/MLX90614/Digital-Plug-Play-Infrared-Thermometer-TO-Can) +* [MLX90614 datasheet](https://www.melexis.com/-/media/files/documents/datasheets/mlx90614-datasheet-melexis.pdf) +* [WeMos D1 Mini](https://wiki.wemos.cc/products:d1:d1_mini) +* [micropython.org](http://micropython.org) +* [Adafruit Ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy) + +## License + +Licensed under the [MIT License](http://opensource.org/licenses/MIT). diff --git a/docs/examples.rst b/docs/examples.rst index 67b7bb9..6b98bb0 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -16,6 +16,8 @@ Now, to make basic measurement:: sensor = mlx90614.MLX90614(i2c) print(sensor.read_ambient_temp()) print(sensor.read_object_temp()) + if sensor.dual_zone: + print(sensor.object2_temp) To perform continuous measurement:: @@ -23,3 +25,7 @@ To perform continuous measurement:: while True: print(sensor.read_ambient_temp(), sensor.read_object_temp()) time.sleep_ms(500) + +There are some useful properties: + * ``.dual_zone`` - set to ``True`` if the sensor has two thermopiles + * ``.ambient_temp`` - equivalent to read_ambient_temp(), also works for object and object2 diff --git a/docs/mlx90614.rst b/docs/mlx90614.rst index 40ee530..97e5b9a 100644 --- a/docs/mlx90614.rst +++ b/docs/mlx90614.rst @@ -14,10 +14,32 @@ MLX90614 specifies which sensor to connect to, if you have more than one and have changed their addresses with the ``Addr`` pin. + All temperatures are returned in Celsius. + .. method:: read_ambient_temp() - Get the ambient temperature in Celcius + Get the ambient sensor temperature .. method:: read_object_temp() - Get the object temperature in Celcius + Get the object temperature from the first or only thermopile + + .. method:: read_object2_temp() + + Get the object temperature the second thermopile, if it exists + + .. property:: dual_zone + + set to ``True`` if this sensor has two thermopiles + + .. property:: ambient_temp + + Equivalent to ``read_ambient_temp()`` + + .. property:: object_temp + + Equivalent to ``read_object_temp()`` + + .. property:: object2_temp + + Equivalent to ``read_object2_temp()`` diff --git a/mlx90614.py b/mlx90614.py index 525758a..9036712 100644 --- a/mlx90614.py +++ b/mlx90614.py @@ -1,16 +1,32 @@ """ -MicroPython driver for MLX90614 IR temperature sensor +MicroPython MLX90614 IR temperature sensor driver +https://github.com/mcauser/micropython-mlx90614 + +MIT License +Copyright (c) 2016 Mike Causer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. """ import ustruct -_REGISTER_TA = const(0x06) # ambient -_REGISTER_TOBJ1 = const(0x07) # object - -class MLX90614: - def __init__(self, i2c, address=0x5a): - self.i2c = i2c - self.address = address +class SensorBase: def read16(self, register): data = self.i2c.readfrom_mem(self.address, register, 2) @@ -25,7 +41,48 @@ def read_temp(self, register): return temp; def read_ambient_temp(self): - return self.read_temp(_REGISTER_TA) + return self.read_temp(self._REGISTER_TA) def read_object_temp(self): - return self.read_temp(_REGISTER_TOBJ1) + return self.read_temp(self._REGISTER_TOBJ1) + + def read_object2_temp(self): + if self.dual_zone: + return self.read_temp(self._REGISTER_TOBJ2) + else: + raise RuntimeError("Device only has one thermopile") + + @property + def ambient_temp(self): + return self.read_ambient_temp() + + @property + def object_temp(self): + return self.read_object_temp() + + @property + def object2_temp(self): + return self.read_object2_temp() + +class MLX90614(SensorBase): + + _REGISTER_TA = 0x06 + _REGISTER_TOBJ1 = 0x07 + _REGISTER_TOBJ2 = 0x08 + + def __init__(self, i2c, address=0x5a): + self.i2c = i2c + self.address = address + _config1 = i2c.readfrom_mem(address, 0x25, 2) + _dz = ustruct.unpack('