From 97202bbfb449a932c51fdaed8cee1ce3a7e141fa Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Thu, 2 Jun 2022 20:31:55 +0100 Subject: [PATCH 1/3] fix: no low power pin (lpn), added tests + stop reset raise --- tests/sensor.py | 12 +++++++++-- tests/sensor_no_lpn.py | 42 ++++++++++++++++++++++++++++++++++++++ tests/start_stop_no_lpn.py | 40 ++++++++++++++++++++++++++++++++++++ vl53l5cx/cp.py | 13 ++++++------ vl53l5cx/mp.py | 13 ++++++------ 5 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 tests/sensor_no_lpn.py create mode 100644 tests/start_stop_no_lpn.py diff --git a/tests/sensor.py b/tests/sensor.py index 3d3ea9f..a5116e1 100644 --- a/tests/sensor.py +++ b/tests/sensor.py @@ -25,9 +25,17 @@ def make_sensor(): from digitalio import DigitalInOut, Direction from vl53l5cx.cp import VL53L5CXCP + + ## import adafruit boards library for named pins + import boards + + ## Sparkfun RP2040 Thing Plus or other boards with one set of SCL/SDA pins, plus lpn from tiny2040 *untested* + scl_pin, sda_pin = (boards.SCL, boards.SDA, pin.GPIO28, pin.GPIO5) + + # Pimoroni TINY2040 coupled with VL53L5CX breakout with low-power-pin (lpn) + #scl_pin, sda_pin = (pin.GPIO1, pin.GPIO0, pin.GPIO28, pin.GPIO5) + - # Pimoroni TINY2040 - scl_pin, sda_pin, lpn_pin, _ = (pin.GPIO1, pin.GPIO0, pin.GPIO28, pin.GPIO5) i2c = busio.I2C(scl_pin, sda_pin, frequency=1_000_000) lpn = DigitalInOut(lpn_pin) diff --git a/tests/sensor_no_lpn.py b/tests/sensor_no_lpn.py new file mode 100644 index 0000000..f98d9ac --- /dev/null +++ b/tests/sensor_no_lpn.py @@ -0,0 +1,42 @@ +def make_sensor(): + mp = False + try: + import microcontroller + except: + mp = True + + if mp: + from machine import I2C, Pin + + from vl53l5cx.mp import VL53L5CXMP + + # LILYGO TTGO + scl_pin, sda_pin, lpn_pin, _ = (22, 21, 12, 13) + + # Pimoroni TINY2040 + # scl_pin, sda_pin, lpn_pin, irq_pin = (1, 0, 28, 5) + + i2c = I2C(0, scl=Pin(scl_pin, Pin.OUT), sda=Pin(sda_pin), freq=1_000_000) + + tof = VL53L5CXMP(i2c) + else: + import busio + #from microcontroller import pin + from digitalio import DigitalInOut, Direction + + from vl53l5cx.cp import VL53L5CXCP + + ## import adafruit boards library for named pins + import boards + + # Sparkfun RP2040 Thing Plus or other boards with one set of SCL/SDA pins + scl_pin, sda_pin = (boards.SCL, boards.SDA) + + # Pimoroni TINY2040 coupled with VL53L5CX breakout with low-power-pin (lpn) + #scl_pin, sda_pin = (pin.GPIO1, pin.GPIO0, pin.GPIO28, pin.GPIO5) + + i2c = busio.I2C(scl_pin, sda_pin, frequency=1_000_000) + + tof = VL53L5CXCP(i2c) + + return tof diff --git a/tests/start_stop_no_lpn.py b/tests/start_stop_no_lpn.py new file mode 100644 index 0000000..a1909e8 --- /dev/null +++ b/tests/start_stop_no_lpn.py @@ -0,0 +1,40 @@ +from time import sleep + +from sensor_no_lpn import make_sensor + +from vl53l5cx import DATA_TARGET_STATUS, DATA_DISTANCE_MM +from vl53l5cx import RESOLUTION_4X4, RESOLUTION_8X8 + + +def main(): + tof = make_sensor() + tof.reset() + tof.init() + + tof.ranging_freq = 15 + + for i in range(10): + if i & 0x1: + tof.resolution = RESOLUTION_4X4 + length = 16 + else: + tof.resolution = RESOLUTION_8X8 + length = 64 + + tof.start_ranging({DATA_DISTANCE_MM, DATA_TARGET_STATUS}) + + while not tof.check_data_ready(): + sleep(0.010) + + results = tof.get_ranging_data() + + assert(len(results.distance_mm) == length) + assert(len(results.target_status) == length) + assert(not results.motion_indicator) + + tof.stop_ranging() + + print("pass") + + +main() diff --git a/vl53l5cx/cp.py b/vl53l5cx/cp.py index e078e56..25617f7 100644 --- a/vl53l5cx/cp.py +++ b/vl53l5cx/cp.py @@ -51,9 +51,10 @@ def _wr_multi(self, reg16, data): def reset(self): if not self._lpn: - raise ValueError("no LPN pin provided") - - self._lpn.value = False - sleep(0.1) - self._lpn.value = True - sleep(0.1) + self.i2c.unlock() + #raise ValueError("no LPN pin provided") + else: + self._lpn.value = False + sleep(0.1) + self._lpn.value = True + sleep(0.1) diff --git a/vl53l5cx/mp.py b/vl53l5cx/mp.py index 0620c06..482df09 100644 --- a/vl53l5cx/mp.py +++ b/vl53l5cx/mp.py @@ -24,9 +24,10 @@ def _wr_multi(self, reg16, buf): def reset(self): if not self._lpn: - raise ValueError("no LPN pin provided") - - self._lpn.value(0) - sleep_ms(100) - self._lpn.value(1) - sleep_ms(100) + self.i2c.unlock() + #raise ValueError("no LPN pin provided") + else: + self._lpn.value = False + sleep_ms(100) + self._lpn.value = True + sleep_ms(100) From 5b01b88f253f2e8a685ccd57701cae9d84e6d52b Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Thu, 2 Jun 2022 22:14:16 +0100 Subject: [PATCH 2/3] example: add sparkfun mini breakout csv example (no lpn) --- examples/sparkfun_micro_vl53l5cx.py | 66 +++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 examples/sparkfun_micro_vl53l5cx.py diff --git a/examples/sparkfun_micro_vl53l5cx.py b/examples/sparkfun_micro_vl53l5cx.py new file mode 100644 index 0000000..e2bcdeb --- /dev/null +++ b/examples/sparkfun_micro_vl53l5cx.py @@ -0,0 +1,66 @@ +### This is written for an RP2040 (Sparkfun Thing Plus), to provide a tab separated grid of data, +### but should work with any single I2C board, otherwise change pins (check names under board in REPL). +### +### The low power enable/disable pin is not available on the mini / low-profile Sparkfun VL53L5CX +### breakout https://www.sparkfun.com/products/19013 (if using low-power add LPN pins like examples) +### +### Designed to be visualised using processing (processing.org) as mentioned in the hookup guide +### https://learn.sparkfun.com/tutorials/qwiic-tof-imager---vl53l5cx-hookup-guide +### https://cdn.sparkfun.com/assets/learn_tutorials/2/0/0/2/SparkFun_VL53L5CX_3D_Depth_Map.zip + + +# depends on +import board +import busio + +from vl53l5cx.cp import VL53L5CXCP + +def make_sensor(): + + # lpn = low power pin, removed as using the micro VL53L5CX breakout without lpn + scl_pin, sda_pin = (board.SCL, board.SDA) + + #i2c = busio.I2C(board.SCL1, board.SDA1,frequency=1_000_000) + i2c = busio.I2C(scl_pin, sda_pin, frequency=1_000_000) + + return VL53L5CXCP(i2c) + + +from vl53l5cx import DATA_TARGET_STATUS, DATA_DISTANCE_MM +from vl53l5cx import STATUS_VALID, RESOLUTION_4X4, RESOLUTION_8X8 + + +def main(): + tof = make_sensor() + tof.reset() + + if not tof.is_alive(): + raise ValueError("VL53L5CX not detected") + + tof.init() + + tof.resolution = RESOLUTION_8X8 + grid = 7 # change to 3 if 4x4 grid + + tof.ranging_freq = 4 # was 2, 4 felt intense! + + tof.start_ranging({DATA_DISTANCE_MM, DATA_TARGET_STATUS}) + + while True: + if tof.check_data_ready(): + results = tof.get_ranging_data() + distance = results.distance_mm + status = results.target_status + + for i, d in enumerate(distance): + if status[i] == STATUS_VALID: + print(d, end="") + else: + print("0", end="") + + print(",", end="") + + print("") + + +main() \ No newline at end of file From 0b0b5139da4867956a9938f9495dd8d3a7216305 Mon Sep 17 00:00:00 2001 From: tyeth Date: Mon, 14 Aug 2023 20:53:47 +0100 Subject: [PATCH 3/3] No i2c unlock in reset, skip if no LowPowerPin. Updates makefile to allow overloading of VL53L5CX_ULD_DIR Adds testing notes for CPY 8 --- Makefile | 7 ++++++- README.md | 1 + vl53l5cx/cp.py | 6 ++---- vl53l5cx/mp.py | 6 ++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index fa415ca..4fb2f2e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,10 @@ +# If you want to build the firmware blob, you need to download the STSW-IMG023 firmware package, +# and agree to the terms. See https://www.st.com/en/embedded-software/stsw-img023.html#st-get-software +# Download from https://www.st.com/content/ccc/resource/technical/software/application_sw/group0/43/1c/58/e9/46/a0/48/95/STSW-IMG023/files/STSW-IMG023.zip/jcr:content/translations/en.STSW-IMG023.zip +# and start command with VL53L5CX_ULD_DIR=/path/to/unzipped/folder make vl_fw.bin + # used to build a binary blob firmware file for the sensor's MCU -VL53L5CX_ULD_DIR := /home/mark/Projects/vl53l5cx/VL53L5CX_ULD_driver_1.1.0 +VL53L5CX_ULD_DIR ?= /home/mark/Projects/vl53l5cx/VL53L5CX_ULD_driver_1.1.0 vl53l5cx/%.mpy: vl53l5cx/%.py mpy-cross -O2 $^ diff --git a/README.md b/README.md index 0650510..3e77018 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This package provides a class that is (mostly) a straight port of the ST [Ultra ![Range as colors demo](ttgo_vl53l5cx.png) The code has been tested with the VL53L5CX breakout board from [Pesky Products on Tindie](https://www.tindie.com/products/onehorse/vl53l5cx-ranging-camera/) using a [Pimoroni Tiny 2040](https://shop.pimoroni.com/products/tiny-2040) with both MicroPython (v1.16) and CircuitPython (v7.0) and a [LILYGO TTGO T-Display](http://www.lilygo.cn/prod_view.aspx?TypeId=50062&Id=1126&FId=t3:50062:3) using MicroPython (v1.17). +Also with the [SparkFun Qwiic Mini ToF Imager](https://www.sparkfun.com/products/19013) on the [Adafruit QT Py ESP32-S2](https://www.adafruit.com/product/5325) using Circuitpython 8.2.3 and no Low Power Pin. ## Installation diff --git a/vl53l5cx/cp.py b/vl53l5cx/cp.py index 25617f7..f4b9ae5 100644 --- a/vl53l5cx/cp.py +++ b/vl53l5cx/cp.py @@ -50,11 +50,9 @@ def _wr_multi(self, reg16, data): self.dev.write(buf) def reset(self): - if not self._lpn: - self.i2c.unlock() - #raise ValueError("no LPN pin provided") - else: + if self._lpn: self._lpn.value = False sleep(0.1) self._lpn.value = True sleep(0.1) + # ELSE: Rely on init function to do software reset diff --git a/vl53l5cx/mp.py b/vl53l5cx/mp.py index 482df09..35e6261 100644 --- a/vl53l5cx/mp.py +++ b/vl53l5cx/mp.py @@ -23,11 +23,9 @@ def _wr_multi(self, reg16, buf): self.i2c.writeto_mem(self.addr, reg16, buf, addrsize=16) def reset(self): - if not self._lpn: - self.i2c.unlock() - #raise ValueError("no LPN pin provided") - else: + if self._lpn: self._lpn.value = False sleep_ms(100) self._lpn.value = True sleep_ms(100) + # ELSE: Rely on init function to do software reset