Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -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 $^
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
66 changes: 66 additions & 0 deletions examples/sparkfun_micro_vl53l5cx.py
Original file line number Diff line number Diff line change
@@ -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()
12 changes: 10 additions & 2 deletions tests/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
42 changes: 42 additions & 0 deletions tests/sensor_no_lpn.py
Original file line number Diff line number Diff line change
@@ -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
40 changes: 40 additions & 0 deletions tests/start_stop_no_lpn.py
Original file line number Diff line number Diff line change
@@ -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()
13 changes: 6 additions & 7 deletions vl53l5cx/cp.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ def _wr_multi(self, reg16, data):
self.dev.write(buf)

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)
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
13 changes: 6 additions & 7 deletions vl53l5cx/mp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +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:
raise ValueError("no LPN pin provided")

self._lpn.value(0)
sleep_ms(100)
self._lpn.value(1)
sleep_ms(100)
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