From ec6bdcc7c02adfe3a1ce4a18275b085a9cdb9780 Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Sun, 30 Jan 2022 23:08:29 +0100 Subject: [PATCH 1/7] Added support for continuous mode and history buffering --- adafruit_vl6180x.py | 138 +++++++++++++++++++++++----- docs/examples.rst | 42 ++++++++- examples/vl6180x_calibrationtest.py | 2 +- examples/vl6180x_continuoustest.py | 36 ++++++++ examples/vl6180x_historytest.py | 38 ++++++++ examples/vl6180x_performancetest.py | 57 ++++++++++++ 6 files changed, 289 insertions(+), 24 deletions(-) create mode 100644 examples/vl6180x_continuoustest.py create mode 100644 examples/vl6180x_historytest.py create mode 100644 examples/vl6180x_performancetest.py diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 93482dc..47db96d 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -9,7 +9,7 @@ CircuitPython module for the VL6180X distance sensor. See examples/simpletest.py for a demo of the usage. -* Author(s): Tony DiCola +* Author(s): Tony DiCola, Jonas Schatz Implementation Notes -------------------- @@ -26,12 +26,16 @@ * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ import struct +import time + from micropython import const from adafruit_bus_device import i2c_device try: - import typing # pylint: disable=unused-import + import logging + import time + from typing import Optional, List from busio import I2C except ImportError: pass @@ -40,23 +44,31 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VL6180X.git" - -# Internal constants: -_VL6180X_DEFAULT_I2C_ADDR = const(0x29) +# Registers _VL6180X_REG_IDENTIFICATION_MODEL_ID = const(0x000) + +_VL6180X_REG_SYSTEM_HISTORY_CTRL = const(0x012) _VL6180X_REG_SYSTEM_INTERRUPT_CONFIG = const(0x014) _VL6180X_REG_SYSTEM_INTERRUPT_CLEAR = const(0x015) _VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET = const(0x016) + _VL6180X_REG_SYSRANGE_START = const(0x018) +_VL6180X_REG_SYSRANGE_INTERMEASUREMENT_PERIOD = const(0x01B) +_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET = const(0x024) + _VL6180X_REG_SYSALS_START = const(0x038) _VL6180X_REG_SYSALS_ANALOGUE_GAIN = const(0x03F) _VL6180X_REG_SYSALS_INTEGRATION_PERIOD_HI = const(0x040) _VL6180X_REG_SYSALS_INTEGRATION_PERIOD_LO = const(0x041) -_VL6180X_REG_RESULT_ALS_VAL = const(0x050) -_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) +_VL6180X_REG_RESULT_ALS_VAL = const(0x050) +_VL6180X_REG_RESULT_HISTORY_BUFFER_0 = const(0x052) +_VL6180X_REG_RESULT_RANGE_VAL = const(0x062) + +# Internal constants: +_VL6180X_DEFAULT_I2C_ADDR = const(0x29) # User-facing constants: ALS_GAIN_1 = const(0x06) @@ -82,7 +94,7 @@ class VL6180X: - """Create an instance of the VL6180X distance sensor. You must pass in + """Create an instance of the VL6180X distance sensor. You must pass in the following parameters: :param i2c: An instance of the I2C bus connected to the sensor. @@ -103,22 +115,82 @@ def __init__( self._write_8(_VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00) self.offset = offset + # Reset a sensor that crashed while in continuous mode + if self.continuous_mode_enabled: + self.stop_range_continuous() + time.sleep(0.1) + + # Activate history buffer for range measurement + self._write_8(_VL6180X_REG_SYSTEM_HISTORY_CTRL, 0x01) + @property 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: - pass - # Start a range measurement - self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) - # Poll until bit 2 is set - while not self._read_8(_VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO) & 0x04: - pass - # read range in mm - range_ = self._read_8(_VL6180X_REG_RESULT_RANGE_VAL) - # clear interrupt - self._write_8(_VL6180X_REG_SYSTEM_INTERRUPT_CLEAR, 0x07) - return range_ + if self.continuous_mode_enabled: + return self._read_range_continuous() + return self._read_range_single() + + @property + def range_from_history(self) -> Optional[int]: + """ Read the latest range data from history + To do so, you don't have to wait for a complete measurement. """ + + if not self.range_history_enabled: + return None + + return self._read_8(_VL6180X_REG_RESULT_HISTORY_BUFFER_0) + + @property + def ranges_from_history(self) -> Optional[List[int]]: + """ Read the last 16 range measurements from history """ + + if not self.range_history_enabled: + return None + + return [self._read_8(_VL6180X_REG_RESULT_HISTORY_BUFFER_0 + age) for age in range(16)] + + @property + def range_history_enabled(self) -> bool: + """ Checks if history buffer stores range data """ + + history_ctrl: int = self._read_8(_VL6180X_REG_SYSTEM_HISTORY_CTRL) + + if history_ctrl & 0x0: + logging.info('History buffering not enabled') + return False + + if (history_ctrl > 1) & 0x1: + logging.info('History buffer stores ALS data, not range') + return False + + return True + + def start_range_continuous(self, period: int = 100) -> None: + """ Start continuous range mode + :param period: Time delay between measurements in ms + """ + # Set range between measurements + period_reg: int = 0 + if period > 10: + if period < 2250: + period_reg = (period // 10) - 1 + else: + period_reg = 254 + self._write_8(_VL6180X_REG_SYSRANGE_INTERMEASUREMENT_PERIOD, period_reg) + + # Start continuous range measurement + self._write_8(_VL6180X_REG_SYSRANGE_START, 0x03) + + def stop_range_continuous(self) -> None: + """ Stop continuous range mode. It is advised to wait for about 0.3s + afterwards to avoid issues with the interrupt flags """ + if self.continuous_mode_enabled: + self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) + + @property + def continuous_mode_enabled(self) -> bool: + """ Checks if continuous mode is enabled """ + return self._read_8(_VL6180X_REG_SYSRANGE_START) > 1 & 0x1 @property def offset(self) -> int: @@ -132,6 +204,28 @@ def offset(self, offset: int) -> None: ) self._offset = offset + def _read_range_single(self) -> int: + """ Read the range when in single-shot mode""" + while not self._read_8(_VL6180X_REG_RESULT_RANGE_STATUS) & 0x01: + pass + self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) + return self._read_range_continuous() + + def _read_range_continuous(self) -> int: + """ Read the range when in continuous mode""" + + # Poll until bit 2 is set + while not self._read_8(_VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO) & 0x04: + pass + + # read range in mm + range_ = self._read_8(_VL6180X_REG_RESULT_RANGE_VAL) + + # clear interrupt + self._write_8(_VL6180X_REG_SYSTEM_INTERRUPT_CLEAR, 0x07) + + return range_ + 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: diff --git a/docs/examples.rst b/docs/examples.rst index 5856981..a13fe94 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,4 +1,4 @@ -Simple test +Simple Test ------------ Ensure your device works with this simple test. @@ -6,3 +6,43 @@ Ensure your device works with this simple test. .. literalinclude:: ../examples/vl6180x_simpletest.py :caption: examples/vl6180x_simpletest.py :linenos: + + +Calibration Test +------------ + +Demo of calibrating the part to part range offset per Application Note 4545 for the VL6180X sensor. + +.. literalinclude:: ../examples/vl6180x_calibrationtest.py + :caption: examples/vl6180x_calibrationtest.py + :linenos: + + +Continuous Test +------------ + +Demo of reading the range from the VL6180x distance sensor in continuous mode. + +.. literalinclude:: ../examples/vl6180x_continuoustest.py + :caption: examples/vl6180x_continuoustest.py + :linenos: + + +History Test +------------ + +Demo of reading the range from the history buffer of the VL6180x distance sensor. + +.. literalinclude:: ../examples/vl6180x_historytest.py + :caption: examples/vl6180x_historytest.py + :linenos: + + +Performance Test +------------ + +Demo of reading the range from the VL6180x distance sensor in different access modes (single shot, continuous, history). + +.. literalinclude:: ../examples/vl6180x_performancetest.py + :caption: examples/vl6180x_performancetest.py + :linenos: diff --git a/examples/vl6180x_calibrationtest.py b/examples/vl6180x_calibrationtest.py index 8289b71..c3e5630 100644 --- a/examples/vl6180x_calibrationtest.py +++ b/examples/vl6180x_calibrationtest.py @@ -19,7 +19,7 @@ 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 +# with the target in place and calculate mean of the range results. For a # reliable measurement, take at least 10 measurements. measurements = [] for msmt in range(10): diff --git a/examples/vl6180x_continuoustest.py b/examples/vl6180x_continuoustest.py new file mode 100644 index 0000000..2d2d3fb --- /dev/null +++ b/examples/vl6180x_continuoustest.py @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2018 Jonas Schatz +# SPDX-License-Identifier: MIT + +# Demo of reading the range from the VL6180x distance sensor in +# continuous mode + +import time + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance. +sensor = adafruit_vl6180x.VL6180X(i2c) + +# Starting continuous mode +print('Starting continuous mode') +sensor.start_range_continuous(20) + +# Main loop prints the range and lux every 0.01 seconds +for _ in range(100): + # Read the range in millimeters and print it. + range_mm = sensor.range + print("Range: {0}mm".format(range_mm)) + + # Delay for 10 ms + time.sleep(0.01) + +# Stop continuous mode. This is advised as the sensor +# wouldn't stop measuring after the program has ended +sensor.stop_range_continuous() diff --git a/examples/vl6180x_historytest.py b/examples/vl6180x_historytest.py new file mode 100644 index 0000000..6a237b3 --- /dev/null +++ b/examples/vl6180x_historytest.py @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2022 Jonas Schatz +# SPDX-License-Identifier: MIT + +# Demo of reading the range from the history buffer of the VL6180x +# distance sensor + +import time +from typing import List + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance. +sensor = adafruit_vl6180x.VL6180X(i2c) + +# Starting continuous mode +print('Starting continuous mode') +sensor.start_range_continuous() + +# Main loop prints the ranges every 0.01 seconds for about 5 seconds +# You should see changes 'ripple through' the history array +for _ in range(500): + # Read the range in millimeters and print it. + ranges_mm: List[int] = sensor.ranges_from_history + print(ranges_mm) + + # Delay for 10 ms so that the loop is not too fast + time.sleep(0.01) + +# Stop continuous mode. This is advised as the sensor +# wouldn't stop measuring after the program has ended +sensor.stop_range_continuous() diff --git a/examples/vl6180x_performancetest.py b/examples/vl6180x_performancetest.py new file mode 100644 index 0000000..314d8a9 --- /dev/null +++ b/examples/vl6180x_performancetest.py @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2022 Jonas Schatz +# SPDX-License-Identifier: MIT + +# Demo of reading the range from the VL6180x distance sensor in +# different access modes (single shot, continuous, history) + +import time + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance. +sensor = adafruit_vl6180x.VL6180X(i2c) + +# Define the number of measurements +# n_measurements = 1000 will run for about 2 minutes +n_measurements: int = 100 + +# Single shot +print('Starting single-shot measurement...') +start = time.time() +for i in range(n_measurements): + range_mm = sensor.range +print('Performed {} measurements in single-shot mode in {}s\n' + .format(n_measurements, time.time() - start)) + +# Sleep is required, otherwise the sensor might freeze when switching to +# continuous mode too quickly after the last single shot +time.sleep(2) + +# Continuous with no delay between measurements +print('Starting continuous measurement...') +sensor.start_range_continuous(0) +start = time.time() +for i in range(n_measurements): + range_mm = sensor.range +print('Performed {} measurements in continuous mode in {}s\n' + .format(n_measurements, time.time() - start)) + +# Continuous, reading data from history. +# Note: This is fast, since you don't have to wait for the measurement to be +# finished. On the downside, you will read the same value multiple times +print('Starting continuous measurement with history enabled...') +start = time.time() +for i in range(n_measurements): + range_mm = sensor.range_from_history +print('Performed {} measurements in continuous mode, reading form history, in {}s\n' + .format(n_measurements, time.time() - start)) + +sensor.stop_range_continuous() +print('Finished') From c9851cb96d8a9a2eb7a67867cb4e921277e7b7e2 Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Sun, 30 Jan 2022 23:08:29 +0100 Subject: [PATCH 2/7] Added support for continuous mode and history buffering --- adafruit_vl6180x.py | 137 +++++++++++++++++++++++----- docs/examples.rst | 42 ++++++++- examples/vl6180x_calibrationtest.py | 2 +- examples/vl6180x_continuoustest.py | 36 ++++++++ examples/vl6180x_historytest.py | 38 ++++++++ examples/vl6180x_performancetest.py | 57 ++++++++++++ 6 files changed, 288 insertions(+), 24 deletions(-) create mode 100644 examples/vl6180x_continuoustest.py create mode 100644 examples/vl6180x_historytest.py create mode 100644 examples/vl6180x_performancetest.py diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 93482dc..a9f6fb0 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -9,7 +9,7 @@ CircuitPython module for the VL6180X distance sensor. See examples/simpletest.py for a demo of the usage. -* Author(s): Tony DiCola +* Author(s): Tony DiCola, Jonas Schatz Implementation Notes -------------------- @@ -26,12 +26,15 @@ * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ import struct +import time + from micropython import const from adafruit_bus_device import i2c_device try: - import typing # pylint: disable=unused-import + import logging + from typing import Optional, List from busio import I2C except ImportError: pass @@ -40,23 +43,31 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VL6180X.git" - -# Internal constants: -_VL6180X_DEFAULT_I2C_ADDR = const(0x29) +# Registers _VL6180X_REG_IDENTIFICATION_MODEL_ID = const(0x000) + +_VL6180X_REG_SYSTEM_HISTORY_CTRL = const(0x012) _VL6180X_REG_SYSTEM_INTERRUPT_CONFIG = const(0x014) _VL6180X_REG_SYSTEM_INTERRUPT_CLEAR = const(0x015) _VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET = const(0x016) + _VL6180X_REG_SYSRANGE_START = const(0x018) +_VL6180X_REG_SYSRANGE_INTERMEASUREMENT_PERIOD = const(0x01B) +_VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET = const(0x024) + _VL6180X_REG_SYSALS_START = const(0x038) _VL6180X_REG_SYSALS_ANALOGUE_GAIN = const(0x03F) _VL6180X_REG_SYSALS_INTEGRATION_PERIOD_HI = const(0x040) _VL6180X_REG_SYSALS_INTEGRATION_PERIOD_LO = const(0x041) -_VL6180X_REG_RESULT_ALS_VAL = const(0x050) -_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) +_VL6180X_REG_RESULT_ALS_VAL = const(0x050) +_VL6180X_REG_RESULT_HISTORY_BUFFER_0 = const(0x052) +_VL6180X_REG_RESULT_RANGE_VAL = const(0x062) + +# Internal constants: +_VL6180X_DEFAULT_I2C_ADDR = const(0x29) # User-facing constants: ALS_GAIN_1 = const(0x06) @@ -82,7 +93,7 @@ class VL6180X: - """Create an instance of the VL6180X distance sensor. You must pass in + """Create an instance of the VL6180X distance sensor. You must pass in the following parameters: :param i2c: An instance of the I2C bus connected to the sensor. @@ -103,22 +114,82 @@ def __init__( self._write_8(_VL6180X_REG_SYSTEM_FRESH_OUT_OF_RESET, 0x00) self.offset = offset + # Reset a sensor that crashed while in continuous mode + if self.continuous_mode_enabled: + self.stop_range_continuous() + time.sleep(0.1) + + # Activate history buffer for range measurement + self._write_8(_VL6180X_REG_SYSTEM_HISTORY_CTRL, 0x01) + @property 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: - pass - # Start a range measurement - self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) - # Poll until bit 2 is set - while not self._read_8(_VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO) & 0x04: - pass - # read range in mm - range_ = self._read_8(_VL6180X_REG_RESULT_RANGE_VAL) - # clear interrupt - self._write_8(_VL6180X_REG_SYSTEM_INTERRUPT_CLEAR, 0x07) - return range_ + if self.continuous_mode_enabled: + return self._read_range_continuous() + return self._read_range_single() + + @property + def range_from_history(self) -> Optional[int]: + """ Read the latest range data from history + To do so, you don't have to wait for a complete measurement. """ + + if not self.range_history_enabled: + return None + + return self._read_8(_VL6180X_REG_RESULT_HISTORY_BUFFER_0) + + @property + def ranges_from_history(self) -> Optional[List[int]]: + """ Read the last 16 range measurements from history """ + + if not self.range_history_enabled: + return None + + return [self._read_8(_VL6180X_REG_RESULT_HISTORY_BUFFER_0 + age) for age in range(16)] + + @property + def range_history_enabled(self) -> bool: + """ Checks if history buffer stores range data """ + + history_ctrl: int = self._read_8(_VL6180X_REG_SYSTEM_HISTORY_CTRL) + + if history_ctrl & 0x0: + logging.info('History buffering not enabled') + return False + + if (history_ctrl > 1) & 0x1: + logging.info('History buffer stores ALS data, not range') + return False + + return True + + def start_range_continuous(self, period: int = 100) -> None: + """ Start continuous range mode + :param period: Time delay between measurements in ms + """ + # Set range between measurements + period_reg: int = 0 + if period > 10: + if period < 2250: + period_reg = (period // 10) - 1 + else: + period_reg = 254 + self._write_8(_VL6180X_REG_SYSRANGE_INTERMEASUREMENT_PERIOD, period_reg) + + # Start continuous range measurement + self._write_8(_VL6180X_REG_SYSRANGE_START, 0x03) + + def stop_range_continuous(self) -> None: + """ Stop continuous range mode. It is advised to wait for about 0.3s + afterwards to avoid issues with the interrupt flags """ + if self.continuous_mode_enabled: + self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) + + @property + def continuous_mode_enabled(self) -> bool: + """ Checks if continuous mode is enabled """ + return self._read_8(_VL6180X_REG_SYSRANGE_START) > 1 & 0x1 @property def offset(self) -> int: @@ -132,6 +203,28 @@ def offset(self, offset: int) -> None: ) self._offset = offset + def _read_range_single(self) -> int: + """ Read the range when in single-shot mode""" + while not self._read_8(_VL6180X_REG_RESULT_RANGE_STATUS) & 0x01: + pass + self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) + return self._read_range_continuous() + + def _read_range_continuous(self) -> int: + """ Read the range when in continuous mode""" + + # Poll until bit 2 is set + while not self._read_8(_VL6180X_REG_RESULT_INTERRUPT_STATUS_GPIO) & 0x04: + pass + + # read range in mm + range_ = self._read_8(_VL6180X_REG_RESULT_RANGE_VAL) + + # clear interrupt + self._write_8(_VL6180X_REG_SYSTEM_INTERRUPT_CLEAR, 0x07) + + return range_ + 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: diff --git a/docs/examples.rst b/docs/examples.rst index 5856981..a13fe94 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,4 +1,4 @@ -Simple test +Simple Test ------------ Ensure your device works with this simple test. @@ -6,3 +6,43 @@ Ensure your device works with this simple test. .. literalinclude:: ../examples/vl6180x_simpletest.py :caption: examples/vl6180x_simpletest.py :linenos: + + +Calibration Test +------------ + +Demo of calibrating the part to part range offset per Application Note 4545 for the VL6180X sensor. + +.. literalinclude:: ../examples/vl6180x_calibrationtest.py + :caption: examples/vl6180x_calibrationtest.py + :linenos: + + +Continuous Test +------------ + +Demo of reading the range from the VL6180x distance sensor in continuous mode. + +.. literalinclude:: ../examples/vl6180x_continuoustest.py + :caption: examples/vl6180x_continuoustest.py + :linenos: + + +History Test +------------ + +Demo of reading the range from the history buffer of the VL6180x distance sensor. + +.. literalinclude:: ../examples/vl6180x_historytest.py + :caption: examples/vl6180x_historytest.py + :linenos: + + +Performance Test +------------ + +Demo of reading the range from the VL6180x distance sensor in different access modes (single shot, continuous, history). + +.. literalinclude:: ../examples/vl6180x_performancetest.py + :caption: examples/vl6180x_performancetest.py + :linenos: diff --git a/examples/vl6180x_calibrationtest.py b/examples/vl6180x_calibrationtest.py index 8289b71..c3e5630 100644 --- a/examples/vl6180x_calibrationtest.py +++ b/examples/vl6180x_calibrationtest.py @@ -19,7 +19,7 @@ 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 +# with the target in place and calculate mean of the range results. For a # reliable measurement, take at least 10 measurements. measurements = [] for msmt in range(10): diff --git a/examples/vl6180x_continuoustest.py b/examples/vl6180x_continuoustest.py new file mode 100644 index 0000000..2d2d3fb --- /dev/null +++ b/examples/vl6180x_continuoustest.py @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2018 Jonas Schatz +# SPDX-License-Identifier: MIT + +# Demo of reading the range from the VL6180x distance sensor in +# continuous mode + +import time + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance. +sensor = adafruit_vl6180x.VL6180X(i2c) + +# Starting continuous mode +print('Starting continuous mode') +sensor.start_range_continuous(20) + +# Main loop prints the range and lux every 0.01 seconds +for _ in range(100): + # Read the range in millimeters and print it. + range_mm = sensor.range + print("Range: {0}mm".format(range_mm)) + + # Delay for 10 ms + time.sleep(0.01) + +# Stop continuous mode. This is advised as the sensor +# wouldn't stop measuring after the program has ended +sensor.stop_range_continuous() diff --git a/examples/vl6180x_historytest.py b/examples/vl6180x_historytest.py new file mode 100644 index 0000000..6a237b3 --- /dev/null +++ b/examples/vl6180x_historytest.py @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2022 Jonas Schatz +# SPDX-License-Identifier: MIT + +# Demo of reading the range from the history buffer of the VL6180x +# distance sensor + +import time +from typing import List + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance. +sensor = adafruit_vl6180x.VL6180X(i2c) + +# Starting continuous mode +print('Starting continuous mode') +sensor.start_range_continuous() + +# Main loop prints the ranges every 0.01 seconds for about 5 seconds +# You should see changes 'ripple through' the history array +for _ in range(500): + # Read the range in millimeters and print it. + ranges_mm: List[int] = sensor.ranges_from_history + print(ranges_mm) + + # Delay for 10 ms so that the loop is not too fast + time.sleep(0.01) + +# Stop continuous mode. This is advised as the sensor +# wouldn't stop measuring after the program has ended +sensor.stop_range_continuous() diff --git a/examples/vl6180x_performancetest.py b/examples/vl6180x_performancetest.py new file mode 100644 index 0000000..314d8a9 --- /dev/null +++ b/examples/vl6180x_performancetest.py @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2022 Jonas Schatz +# SPDX-License-Identifier: MIT + +# Demo of reading the range from the VL6180x distance sensor in +# different access modes (single shot, continuous, history) + +import time + +import board +import busio + +import adafruit_vl6180x + + +# Create I2C bus. +i2c = busio.I2C(board.SCL, board.SDA) + +# Create sensor instance. +sensor = adafruit_vl6180x.VL6180X(i2c) + +# Define the number of measurements +# n_measurements = 1000 will run for about 2 minutes +n_measurements: int = 100 + +# Single shot +print('Starting single-shot measurement...') +start = time.time() +for i in range(n_measurements): + range_mm = sensor.range +print('Performed {} measurements in single-shot mode in {}s\n' + .format(n_measurements, time.time() - start)) + +# Sleep is required, otherwise the sensor might freeze when switching to +# continuous mode too quickly after the last single shot +time.sleep(2) + +# Continuous with no delay between measurements +print('Starting continuous measurement...') +sensor.start_range_continuous(0) +start = time.time() +for i in range(n_measurements): + range_mm = sensor.range +print('Performed {} measurements in continuous mode in {}s\n' + .format(n_measurements, time.time() - start)) + +# Continuous, reading data from history. +# Note: This is fast, since you don't have to wait for the measurement to be +# finished. On the downside, you will read the same value multiple times +print('Starting continuous measurement with history enabled...') +start = time.time() +for i in range(n_measurements): + range_mm = sensor.range_from_history +print('Performed {} measurements in continuous mode, reading form history, in {}s\n' + .format(n_measurements, time.time() - start)) + +sensor.stop_range_continuous() +print('Finished') From cacf12b5d89bc7378cf38dc69deef0f55590eb6c Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Sun, 30 Jan 2022 23:53:37 +0100 Subject: [PATCH 3/7] Removed unused import --- adafruit_vl6180x.py | 1 - 1 file changed, 1 deletion(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 47db96d..a9f6fb0 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -34,7 +34,6 @@ try: import logging - import time from typing import Optional, List from busio import I2C except ImportError: From f3da49ea04e0288f7bb5fc669c79c80f6ddb664a Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Sat, 5 Feb 2022 00:28:38 +0100 Subject: [PATCH 4/7] Reformatted files for black --- adafruit_vl6180x.py | 20 ++++++++++++-------- examples/vl6180x_continuoustest.py | 2 +- examples/vl6180x_historytest.py | 2 +- examples/vl6180x_performancetest.py | 29 +++++++++++++++++++---------- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index cc12f76..7bb42a8 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -26,6 +26,7 @@ * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ import struct +import time from micropython import const @@ -130,8 +131,8 @@ def range(self) -> int: @property def range_from_history(self) -> Optional[int]: - """ Read the latest range data from history - To do so, you don't have to wait for a complete measurement. """ + """Read the latest range data from history + To do so, you don't have to wait for a complete measurement.""" if not self.range_history_enabled: return None @@ -145,7 +146,10 @@ def ranges_from_history(self) -> Optional[List[int]]: if not self.range_history_enabled: return None - return [self._read_8(_VL6180X_REG_RESULT_HISTORY_BUFFER_0 + age) for age in range(16)] + return [ + self._read_8(_VL6180X_REG_RESULT_HISTORY_BUFFER_0 + age) + for age in range(16) + ] @property def range_history_enabled(self) -> bool: @@ -154,17 +158,17 @@ def range_history_enabled(self) -> bool: history_ctrl: int = self._read_8(_VL6180X_REG_SYSTEM_HISTORY_CTRL) if history_ctrl & 0x0: - logging.info('History buffering not enabled') + logging.info("History buffering not enabled") return False if (history_ctrl > 1) & 0x1: - logging.info('History buffer stores ALS data, not range') + logging.info("History buffer stores ALS data, not range") return False return True def start_range_continuous(self, period: int = 100) -> None: - """ Start continuous range mode + """Start continuous range mode :param period: Time delay between measurements in ms """ # Set range between measurements @@ -180,8 +184,8 @@ def start_range_continuous(self, period: int = 100) -> None: self._write_8(_VL6180X_REG_SYSRANGE_START, 0x03) def stop_range_continuous(self) -> None: - """ Stop continuous range mode. It is advised to wait for about 0.3s - afterwards to avoid issues with the interrupt flags """ + """Stop continuous range mode. It is advised to wait for about 0.3s + afterwards to avoid issues with the interrupt flags""" if self.continuous_mode_enabled: self._write_8(_VL6180X_REG_SYSRANGE_START, 0x01) diff --git a/examples/vl6180x_continuoustest.py b/examples/vl6180x_continuoustest.py index 2d2d3fb..d638915 100644 --- a/examples/vl6180x_continuoustest.py +++ b/examples/vl6180x_continuoustest.py @@ -19,7 +19,7 @@ sensor = adafruit_vl6180x.VL6180X(i2c) # Starting continuous mode -print('Starting continuous mode') +print("Starting continuous mode") sensor.start_range_continuous(20) # Main loop prints the range and lux every 0.01 seconds diff --git a/examples/vl6180x_historytest.py b/examples/vl6180x_historytest.py index 6a237b3..c82d65c 100644 --- a/examples/vl6180x_historytest.py +++ b/examples/vl6180x_historytest.py @@ -20,7 +20,7 @@ sensor = adafruit_vl6180x.VL6180X(i2c) # Starting continuous mode -print('Starting continuous mode') +print("Starting continuous mode") sensor.start_range_continuous() # Main loop prints the ranges every 0.01 seconds for about 5 seconds diff --git a/examples/vl6180x_performancetest.py b/examples/vl6180x_performancetest.py index 314d8a9..933a256 100644 --- a/examples/vl6180x_performancetest.py +++ b/examples/vl6180x_performancetest.py @@ -23,35 +23,44 @@ n_measurements: int = 100 # Single shot -print('Starting single-shot measurement...') +print("Starting single-shot measurement...") start = time.time() for i in range(n_measurements): range_mm = sensor.range -print('Performed {} measurements in single-shot mode in {}s\n' - .format(n_measurements, time.time() - start)) +print( + "Performed {} measurements in single-shot mode in {}s\n".format( + n_measurements, time.time() - start + ) +) # Sleep is required, otherwise the sensor might freeze when switching to # continuous mode too quickly after the last single shot time.sleep(2) # Continuous with no delay between measurements -print('Starting continuous measurement...') +print("Starting continuous measurement...") sensor.start_range_continuous(0) start = time.time() for i in range(n_measurements): range_mm = sensor.range -print('Performed {} measurements in continuous mode in {}s\n' - .format(n_measurements, time.time() - start)) +print( + "Performed {} measurements in continuous mode in {}s\n".format( + n_measurements, time.time() - start + ) +) # Continuous, reading data from history. # Note: This is fast, since you don't have to wait for the measurement to be # finished. On the downside, you will read the same value multiple times -print('Starting continuous measurement with history enabled...') +print("Starting continuous measurement with history enabled...") start = time.time() for i in range(n_measurements): range_mm = sensor.range_from_history -print('Performed {} measurements in continuous mode, reading form history, in {}s\n' - .format(n_measurements, time.time() - start)) +print( + "Performed {} measurements in continuous mode, reading form history, in {}s\n".format( + n_measurements, time.time() - start + ) +) sensor.stop_range_continuous() -print('Finished') +print("Finished") From 044f8f714f0f883069ac861054c48890caa56aae Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Sat, 5 Feb 2022 00:34:42 +0100 Subject: [PATCH 5/7] Fixed too short title underlines --- docs/examples.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index a13fe94..c348e59 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -9,7 +9,7 @@ Ensure your device works with this simple test. Calibration Test ------------- +----------------- Demo of calibrating the part to part range offset per Application Note 4545 for the VL6180X sensor. @@ -19,7 +19,7 @@ Demo of calibrating the part to part range offset per Application Note 4545 for Continuous Test ------------- +---------------- Demo of reading the range from the VL6180x distance sensor in continuous mode. @@ -29,7 +29,7 @@ Demo of reading the range from the VL6180x distance sensor in continuous mode. History Test ------------- +------------- Demo of reading the range from the history buffer of the VL6180x distance sensor. @@ -39,7 +39,7 @@ Demo of reading the range from the history buffer of the VL6180x distance sensor Performance Test ------------- +----------------- Demo of reading the range from the VL6180x distance sensor in different access modes (single shot, continuous, history). From a016dc4030539b953874c783f39e37517939edfc Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Fri, 11 Feb 2022 20:01:46 +0100 Subject: [PATCH 6/7] Replaced logging with print statements --- adafruit_vl6180x.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/adafruit_vl6180x.py b/adafruit_vl6180x.py index 7bb42a8..ea14a44 100644 --- a/adafruit_vl6180x.py +++ b/adafruit_vl6180x.py @@ -33,7 +33,6 @@ from adafruit_bus_device import i2c_device try: - import logging from typing import Optional, List from busio import I2C except ImportError: @@ -158,11 +157,11 @@ def range_history_enabled(self) -> bool: history_ctrl: int = self._read_8(_VL6180X_REG_SYSTEM_HISTORY_CTRL) if history_ctrl & 0x0: - logging.info("History buffering not enabled") + print("History buffering not enabled") return False if (history_ctrl > 1) & 0x1: - logging.info("History buffer stores ALS data, not range") + print("History buffer stores ALS data, not range") return False return True From 43b0735afbf651fa5ba20924cbf49cf8ee85ede5 Mon Sep 17 00:00:00 2001 From: Jonas Schatz Date: Sat, 12 Feb 2022 00:37:39 +0100 Subject: [PATCH 7/7] Removed typing in history example --- examples/vl6180x_historytest.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/vl6180x_historytest.py b/examples/vl6180x_historytest.py index c82d65c..e2e1a46 100644 --- a/examples/vl6180x_historytest.py +++ b/examples/vl6180x_historytest.py @@ -5,7 +5,6 @@ # distance sensor import time -from typing import List import board import busio @@ -26,8 +25,8 @@ # Main loop prints the ranges every 0.01 seconds for about 5 seconds # You should see changes 'ripple through' the history array for _ in range(500): - # Read the range in millimeters and print it. - ranges_mm: List[int] = sensor.ranges_from_history + # Read the last 16 ranges from the history buffer as a List[int] + ranges_mm = sensor.ranges_from_history print(ranges_mm) # Delay for 10 ms so that the loop is not too fast