From 9100ea96eb08bc2d03b0c13f5d7f1832ccce3d43 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 16 Nov 2021 22:34:04 -0500 Subject: [PATCH 01/15] Add type hints --- adafruit_vl6180x.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 49aab78..c6ba4c4 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -29,6 +29,12 @@ from adafruit_bus_device import i2c_device +try: + import typing # pylint: disable=unused-import + from busio import I2C +except ImportError: + pass + __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VL6180X.git" @@ -85,7 +91,7 @@ class VL6180X: default value will be assumed. """ - def __init__(self, i2c, address=_VL6180X_DEFAULT_I2C_ADDR): + def __init__(self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR) -> None: self._device = i2c_device.I2CDevice(i2c, address) if self._read_8(_VL6180X_REG_IDENTIFICATION_MODEL_ID) != 0xB4: raise RuntimeError("Could not find VL6180X, is it connected and powered?") @@ -93,7 +99,7 @@ def __init__(self, i2c, address=_VL6180X_DEFAULT_I2C_ADDR): self._write_8(_VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00) @property - def range(self): + def range(self) -> int: """Read the range of an object in front of sensor and return it in mm.""" # wait for device to be ready for range measurement while not self._read_8(_VL6180X_REG_RESULT_RANGE_STATUS) & 0x01: @@ -109,7 +115,7 @@ def range(self): self._write_8(_VL6180X_REG_SYSTEM_INTERRUPT_CLEAR, 0x07) return range_ - def read_lux(self, gain): + def read_lux(self, gain: int) -> float: """Read the lux (light value) from the sensor and return it. Must specify the gain value to use for the lux reading: - ALS_GAIN_1 = 1x @@ -164,7 +170,7 @@ def read_lux(self, gain): return lux @property - def range_status(self): + def range_status(self) -> int: """Retrieve the status/error from a previous range read. This will return a constant value such as: @@ -182,7 +188,7 @@ def range_status(self): """ return self._read_8(_VL6180X_REG_RESULT_RANGE_STATUS) >> 4 - def _load_settings(self): + def _load_settings(self) -> None: # private settings from page 24 of app note self._write_8(0x0207, 0x01) self._write_8(0x0208, 0x01) @@ -238,12 +244,12 @@ def _load_settings(self): self._write_8(0x0014, 0x24) # Configures interrupt on 'New Sample # Ready threshold event' - def _write_8(self, address, data): + def _write_8(self, address: int, data: int) -> None: # Write 1 byte of data from the specified 16-bit register address. with self._device: self._device.write(bytes([(address >> 8) & 0xFF, address & 0xFF, data])) - def _write_16(self, address, data): + def _write_16(self, address: int, data: int) -> None: # Write a 16-bit big endian value to the specified 16-bit register # address. with self._device as i2c: @@ -258,7 +264,7 @@ def _write_16(self, address, data): ) ) - def _read_8(self, address): + def _read_8(self, address: int) -> int: # Read and return a byte from the specified 16-bit register address. with self._device as i2c: result = bytearray(1) @@ -266,7 +272,7 @@ def _read_8(self, address): i2c.readinto(result) return result[0] - def _read_16(self, address): + def _read_16(self, address: int) -> int: # Read and return a 16-bit unsigned big endian value read from the # specified 16-bit register address. with self._device as i2c: From de087a77562c72b98bffb258c1cf450284e45d77 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 16 Nov 2021 23:22:06 -0500 Subject: [PATCH 02/15] Add manual offset getting/setting --- adafruit_vl6180x.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index c6ba4c4..f1d7349 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -55,6 +55,7 @@ _VL6180X_REG_RESULT_RANGE_VAL = const(0x062) _VL6180X_REG_RESULT_RANGE_STATUS = const(0x04D) _VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO = const(0x04F) +_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET = const(0x024) # User-facing constants: ALS_GAIN_1 = const(0x06) @@ -97,6 +98,7 @@ def __init__(self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR) -> None: raise RuntimeError("Could not find VL6180X, is it connected and powered?") self._load_settings() self._write_8(_VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00) + self._offset = self._read_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET) @property def range(self) -> int: @@ -115,6 +117,20 @@ def range(self) -> int: self._write_8(_VL6180X_REG_SYSTEM_INTERRUPT_CLEAR, 0x07) return range_ + @property + def manual_offset(self) -> int: + """Read and sets the manual offset for the sensor, in millimeters""" + return self._offset + + @manual_offset.setter + def manual_offset(self, offset: int) -> None: + if not -128 <= offset <= 127: + raise ValueError("Offset out of range (-128 ... 127)") + if offset < 0: + offset = ~ (abs(offset) - 1) + self._write_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, offset) + self._offset = offset + def read_lux(self, gain: int) -> float: """Read the lux (light value) from the sensor and return it. Must specify the gain value to use for the lux reading: From 977a013fe353c99b37a6ead513c44005ba61f6cf Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Wed, 17 Nov 2021 09:24:21 -0500 Subject: [PATCH 03/15] Changed property to "offset" --- adafruit_vl6180x.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index f1d7349..1ac04b1 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -118,12 +118,12 @@ def range(self) -> int: return range_ @property - def manual_offset(self) -> int: + def offset(self) -> int: """Read and sets the manual offset for the sensor, in millimeters""" return self._offset - @manual_offset.setter - def manual_offset(self, offset: int) -> None: + @offset.setter + def offset(self, offset: int) -> None: if not -128 <= offset <= 127: raise ValueError("Offset out of range (-128 ... 127)") if offset < 0: From 74c318fa9352ef8e184cf3c16fdd9cfd59c92810 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Wed, 17 Nov 2021 09:25:12 -0500 Subject: [PATCH 04/15] Remove read of offset in __init__ Datasheet says it doesn't keep between resets --- adafruit_vl6180x.py | 1 - 1 file changed, 1 deletion(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 1ac04b1..cbe0255 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -98,7 +98,6 @@ def __init__(self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR) -> None: raise RuntimeError("Could not find VL6180X, is it connected and powered?") self._load_settings() self._write_8(_VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00) - self._offset = self._read_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET) @property def range(self) -> int: From ba462ae8285dc20da1335d673dd19e98b1c1e487 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Wed, 17 Nov 2021 09:25:25 -0500 Subject: [PATCH 05/15] Allow setting of offset during __init__ --- adafruit_vl6180x.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index cbe0255..e51886d 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -92,12 +92,13 @@ class VL6180X: default value will be assumed. """ - def __init__(self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR) -> None: + def __init__(self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR, offset: int = 0) -> None: self._device = i2c_device.I2CDevice(i2c, address) if self._read_8(_VL6180X_REG_IDENTIFICATION_MODEL_ID) != 0xB4: raise RuntimeError("Could not find VL6180X, is it connected and powered?") self._load_settings() self._write_8(_VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00) + self.offset = offset @property def range(self) -> int: From 4e569402f699add49f405475663efcf1c40cda31 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Wed, 17 Nov 2021 09:27:32 -0500 Subject: [PATCH 06/15] Reformatted per pre-commit --- adafruit_vl6180x.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index e51886d..74ba264 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -92,7 +92,9 @@ class VL6180X: default value will be assumed. """ - def __init__(self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR, offset: int = 0) -> None: + def __init__( + self, i2c: I2C, address: int = _VL6180X_DEFAULT_I2C_ADDR, offset: int = 0 + ) -> None: self._device = i2c_device.I2CDevice(i2c, address) if self._read_8(_VL6180X_REG_IDENTIFICATION_MODEL_ID) != 0xB4: raise RuntimeError("Could not find VL6180X, is it connected and powered?") @@ -121,13 +123,13 @@ def range(self) -> int: def offset(self) -> int: """Read and sets the manual offset for the sensor, in millimeters""" return self._offset - + @offset.setter def offset(self, offset: int) -> None: if not -128 <= offset <= 127: raise ValueError("Offset out of range (-128 ... 127)") if offset < 0: - offset = ~ (abs(offset) - 1) + offset = ~(abs(offset) - 1) self._write_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, offset) self._offset = offset From ce7e81daf9975da24b8f2e2e6e566c5dcb83e99a Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 23 Nov 2021 00:35:30 -0500 Subject: [PATCH 07/15] Create example for adding manual offset --- examples/vl6180x_offsettest.py | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/vl6180x_offsettest.py diff --git a/examples/vl6180x_offsettest.py b/examples/vl6180x_offsettest.py new file mode 100644 index 0000000..ab04132 --- /dev/null +++ b/examples/vl6180x_offsettest.py @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2018 Tony DiCola for Adafruit Industries +# SPDX-License-Identifier: MIT + +# Demo of reading the range and lux from the VL6180x distance sensor and +# printing it every second. + +import time + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance, with an offset value determined by manual calibration. +sensor = adafruit_vl6180x.VL6180X(i2c, offset=10) + +# Main loop prints the range and lux every second: +while True: + # Read the range in millimeters and print it. + range_mm = sensor.range + print("Range: {0}mm".format(range_mm)) + # Read the light, note this requires specifying a gain value: + # - adafruit_vl6180x.ALS_GAIN_1 = 1x + # - adafruit_vl6180x.ALS_GAIN_1_25 = 1.25x + # - adafruit_vl6180x.ALS_GAIN_1_67 = 1.67x + # - adafruit_vl6180x.ALS_GAIN_2_5 = 2.5x + # - adafruit_vl6180x.ALS_GAIN_5 = 5x + # - adafruit_vl6180x.ALS_GAIN_10 = 10x + # - adafruit_vl6180x.ALS_GAIN_20 = 20x + # - adafruit_vl6180x.ALS_GAIN_40 = 40x + light_lux = sensor.read_lux(adafruit_vl6180x.ALS_GAIN_1) + print("Light (1x gain): {0}lux".format(light_lux)) + # Delay for a second. + time.sleep(1.0) From 3d5b2b8109bb3abc91bfa66224fa7529eae9f52b Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 23 Nov 2021 13:33:26 -0500 Subject: [PATCH 08/15] Simplify packing offset into byte using struct.pack() --- adafruit_vl6180x.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 74ba264..6b5d18a 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -28,6 +28,7 @@ from micropython import const from adafruit_bus_device import i2c_device +import struct try: import typing # pylint: disable=unused-import @@ -126,11 +127,7 @@ def offset(self) -> int: @offset.setter def offset(self, offset: int) -> None: - if not -128 <= offset <= 127: - raise ValueError("Offset out of range (-128 ... 127)") - if offset < 0: - offset = ~(abs(offset) - 1) - self._write_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, offset) + self._write_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, struct.pack("b", offset)[0]) self._offset = offset def read_lux(self, gain: int) -> float: From edbd33bd37948684e6c75fedfa932b35977bd138 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 23 Nov 2021 13:35:14 -0500 Subject: [PATCH 09/15] Reformatted per pre-commit, --- adafruit_vl6180x.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 6b5d18a..4a0d93d 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -127,7 +127,9 @@ def offset(self) -> int: @offset.setter def offset(self, offset: int) -> None: - self._write_8(_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, struct.pack("b", offset)[0]) + self._write_8( + _VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, struct.pack("b", offset)[0] + ) self._offset = offset def read_lux(self, gain: int) -> float: From 12d539408a92c95b6cb0ae4ba4ebc52e75a369b3 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 23 Nov 2021 13:35:24 -0500 Subject: [PATCH 10/15] Move import of struct --- adafruit_vl6180x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 4a0d93d..93482dc 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -25,10 +25,10 @@ https://github.com/adafruit/circuitpython/releases * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ +import struct from micropython import const from adafruit_bus_device import i2c_device -import struct try: import typing # pylint: disable=unused-import From 008ac3a91760b4309b1a1261ba2346f5e09aca53 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 23 Nov 2021 20:16:50 -0500 Subject: [PATCH 11/15] Convert offset example to calibration example --- examples/vl6180x_calibrationtest.py | 35 ++++++++++++++++++++++++++ examples/vl6180x_offsettest.py | 38 ----------------------------- 2 files changed, 35 insertions(+), 38 deletions(-) create mode 100644 examples/vl6180x_calibrationtest.py delete mode 100644 examples/vl6180x_offsettest.py diff --git a/examples/vl6180x_calibrationtest.py b/examples/vl6180x_calibrationtest.py new file mode 100644 index 0000000..0a61d50 --- /dev/null +++ b/examples/vl6180x_calibrationtest.py @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: 2018 Tony DiCola for Adafruit Industries +# SPDX-License-Identifier: MIT + +# Demo of calibrating the part to part range offset per Application Note 4545 +# for the VL6180X sensor + +import time + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance, with explicit offset of 0 to clear the system offset +sensor = adafruit_vl6180x.VL6180X(i2c, offset=0) + +# Place a target at 50mm away from VL6180X Collect a number of range measurements +# with the target in place and calculate mean of the range reseults. For a +# reliable measurement, take at least 10 measurements. +measurements = [] +for msmt in range(10): + range_mm = sensor.range + measurements.append(range_mm) + time.sleep(1.0) +average_msmt = sum(measurements)/10 + +# Calculate the offset required: +calibration_offset = 50 - average_msmt + +# Apply offset +sensor.offset = calibration_offset diff --git a/examples/vl6180x_offsettest.py b/examples/vl6180x_offsettest.py deleted file mode 100644 index ab04132..0000000 --- a/examples/vl6180x_offsettest.py +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-FileCopyrightText: 2018 Tony DiCola for Adafruit Industries -# SPDX-License-Identifier: MIT - -# Demo of reading the range and lux from the VL6180x distance sensor and -# printing it every second. - -import time - -import board -import busio - -import adafruit_vl6180x - - -# Create I2C bus. -i2c = busio.I2C(board.SCL, board.SDA) - -# Create sensor instance, with an offset value determined by manual calibration. -sensor = adafruit_vl6180x.VL6180X(i2c, offset=10) - -# Main loop prints the range and lux every second: -while True: - # Read the range in millimeters and print it. - range_mm = sensor.range - print("Range: {0}mm".format(range_mm)) - # Read the light, note this requires specifying a gain value: - # - adafruit_vl6180x.ALS_GAIN_1 = 1x - # - adafruit_vl6180x.ALS_GAIN_1_25 = 1.25x - # - adafruit_vl6180x.ALS_GAIN_1_67 = 1.67x - # - adafruit_vl6180x.ALS_GAIN_2_5 = 2.5x - # - adafruit_vl6180x.ALS_GAIN_5 = 5x - # - adafruit_vl6180x.ALS_GAIN_10 = 10x - # - adafruit_vl6180x.ALS_GAIN_20 = 20x - # - adafruit_vl6180x.ALS_GAIN_40 = 40x - light_lux = sensor.read_lux(adafruit_vl6180x.ALS_GAIN_1) - print("Light (1x gain): {0}lux".format(light_lux)) - # Delay for a second. - time.sleep(1.0) From 3ccf54dd7ef7b41e9c7f27ac09b042e0e5b36b25 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 23 Nov 2021 20:17:16 -0500 Subject: [PATCH 12/15] Add commented out line in simple test for initializing sensor with offset --- examples/vl6180x_simpletest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/vl6180x_simpletest.py b/examples/vl6180x_simpletest.py index cb02bea..6c3961a 100644 --- a/examples/vl6180x_simpletest.py +++ b/examples/vl6180x_simpletest.py @@ -17,6 +17,7 @@ # Create sensor instance. sensor = adafruit_vl6180x.VL6180X(i2c) +# sensor = adafruit_vl6180x.VL6180X(i2c) # This would add a +10 millimeter offset to all measurements: # Main loop prints the range and lux every second: while True: From 82a0669934c680cbd9d46770b6dd67c8ca24fb39 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 23 Nov 2021 20:19:26 -0500 Subject: [PATCH 13/15] Reformatted per black --- examples/vl6180x_calibrationtest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vl6180x_calibrationtest.py b/examples/vl6180x_calibrationtest.py index 0a61d50..8289b71 100644 --- a/examples/vl6180x_calibrationtest.py +++ b/examples/vl6180x_calibrationtest.py @@ -26,7 +26,7 @@ range_mm = sensor.range measurements.append(range_mm) time.sleep(1.0) -average_msmt = sum(measurements)/10 +average_msmt = sum(measurements) / 10 # Calculate the offset required: calibration_offset = 50 - average_msmt From 74360e762dc5f618e3c9b8c9b6d2ce56ac9b0941 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Tue, 23 Nov 2021 20:19:43 -0500 Subject: [PATCH 14/15] Shorten line per pylint --- examples/vl6180x_simpletest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vl6180x_simpletest.py b/examples/vl6180x_simpletest.py index 6c3961a..9bc0649 100644 --- a/examples/vl6180x_simpletest.py +++ b/examples/vl6180x_simpletest.py @@ -17,7 +17,7 @@ # Create sensor instance. sensor = adafruit_vl6180x.VL6180X(i2c) -# sensor = adafruit_vl6180x.VL6180X(i2c) # This would add a +10 millimeter offset to all measurements: +# sensor = adafruit_vl6180x.VL6180X(i2c) # This would add a +10 millimeter offset to measurements: # Main loop prints the range and lux every second: while True: From 4fa94aec378a8f6fc6121b2aaad3cb213dadc706 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Wed, 24 Nov 2021 10:38:39 -0500 Subject: [PATCH 15/15] Add offset to commented out code, expand explanation --- examples/vl6180x_simpletest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/vl6180x_simpletest.py b/examples/vl6180x_simpletest.py index 9bc0649..2b06f4a 100644 --- a/examples/vl6180x_simpletest.py +++ b/examples/vl6180x_simpletest.py @@ -17,7 +17,9 @@ # Create sensor instance. sensor = adafruit_vl6180x.VL6180X(i2c) -# sensor = adafruit_vl6180x.VL6180X(i2c) # This would add a +10 millimeter offset to measurements: +# You can add an offset to distance measurements here (e.g. calibration) +# Swapping for the following would add a +10 millimeter offset to measurements: +# sensor = adafruit_vl6180x.VL6180X(i2c, offset=10) # Main loop prints the range and lux every second: while True: