Skip to content

Commit ebdf774

Browse files
authored
Merge pull request #17 from pimoroni/set-timings
Methods to set timing budget for #16
2 parents 622c912 + 17b6ada commit ebdf774

7 files changed

Lines changed: 143 additions & 76 deletions

File tree

examples/distance.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/usr/bin/env python
22

3-
import os
43
import time
54
import sys
65
import signal
@@ -21,23 +20,23 @@
2120
Open and start the VL53L1X ranging sensor
2221
"""
2322
tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
24-
tof.open() # Initialise the i2c bus and configure the sensor
25-
tof.start_ranging(1) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
26-
23+
tof.open() # Initialise the i2c bus and configure the sensor
24+
tof.start_ranging(1) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
2725

2826
running = True
2927

28+
3029
def exit_handler(signal, frame):
3130
global running
3231
running = False
33-
tof.stop_ranging() # Stop ranging
32+
tof.stop_ranging()
3433
print()
3534
sys.exit(0)
3635

36+
3737
signal.signal(signal.SIGINT, exit_handler)
3838

3939
while running:
40-
distance_in_mm = tof.get_distance() # Grab the range in mm
40+
distance_in_mm = tof.get_distance()
4141
print("Distance: {}mm".format(distance_in_mm))
4242
time.sleep(0.1)
43-

examples/distance_multiplexer.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/usr/bin/env python
22

3-
import os
43
import time
54
import sys
65
import signal
@@ -22,28 +21,27 @@
2221
"""
2322
tof1 = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29, tca9548a_num=2, tca9548a_addr=0x70)
2423
tof2 = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29, tca9548a_num=4, tca9548a_addr=0x70)
25-
tof1.open() # Initialise the i2c bus and configure the sensor
26-
tof1.start_ranging(3) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
27-
tof2.open() # Initialise the i2c bus and configure the sensor
28-
tof2.start_ranging(3) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
24+
tof1.open()
25+
tof1.start_ranging(3) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
26+
tof2.open()
27+
tof2.start_ranging(3) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
2928

3029

31-
running = True
32-
3330
def exit_handler(signal, frame):
3431
global running
3532
running = False
36-
tof1.stop_ranging() # Stop ranging
37-
tof2.stop_ranging() # Stop ranging
33+
tof1.stop_ranging()
34+
tof2.stop_ranging()
3835
print()
3936
sys.exit(0)
4037

38+
39+
running = True
4140
signal.signal(signal.SIGINT, exit_handler)
4241

4342
while running:
44-
distance_in_mm = tof1.get_distance() # Grab the range in mm
43+
distance_in_mm = tof1.get_distance()
4544
print("Sensor 1 distance: {}mm".format(distance_in_mm))
46-
distance_in_mm = tof2.get_distance() # Grab the range in mm
45+
distance_in_mm = tof2.get_distance()
4746
print("Sensor 2 distance: {}mm".format(distance_in_mm))
4847
time.sleep(0.1)
49-

examples/graph.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77

88
import VL53L1X
99

10-
MAX_DISTANCE_MM = 800 # Distance at which our bar is full
11-
BAR_CHAR = u'\u2588' # Unicode FULL BLOCK
10+
MAX_DISTANCE_MM = 800 # Distance at which our bar is full
11+
BAR_CHAR = u'\u2588' # Unicode FULL BLOCK
1212

1313
ANSI_COLOR_RED = "\x1b[31m"
1414
ANSI_COLOR_YELLOW = "\x1b[33m"
1515
ANSI_COLOR_GREEN = "\x1b[32m"
1616
ANSI_COLOR_RESET = "\x1b[0m"
1717

18+
19+
UPDATE_TIME_MICROS = 1000
20+
INTER_MEASUREMENT_PERIOD_MILLIS = 100
21+
1822
print("""graph.py
1923
2024
Display a bar graph that ranges up to 80cm and turns yellow/red as the range decreases.
@@ -36,38 +40,44 @@
3640
Open and start the VL53L1X ranging sensor
3741
"""
3842
tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
39-
tof.open() # Initialise the i2c bus and configure the sensor
40-
tof.start_ranging(1) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
43+
tof.open() # Initialise the i2c bus and configure the sensor
44+
tof.set_distance_mode(3)
45+
46+
# Lower timing budgets allow for faster updates, but sacrifice accuracy
47+
tof.set_timing(UPDATE_TIME_MICROS, INTER_MEASUREMENT_PERIOD_MILLIS)
4148

49+
tof.start_ranging(0)
4250

4351
sys.stdout.write("\n")
4452

4553
running = True
4654

55+
4756
def exit_handler(signal, frame):
4857
global running
4958
running = False
50-
tof.stop_ranging() # Stop ranging
59+
tof.stop_ranging()
5160
sys.stdout.write("\n")
5261
sys.exit(0)
5362

63+
5464
signal.signal(signal.SIGINT, exit_handler)
5565

5666
while running:
57-
distance_in_mm = tof.get_distance() # Grab the range in mm
58-
distance_in_mm = min(MAX_DISTANCE_MM, distance_in_mm) # Cap at our MAX_DISTANCE
59-
bar_size = int((distance_in_mm / float(MAX_DISTANCE_MM)) * (cols-10)) # Scale bar_size to our terminal width
60-
bar = BAR_CHAR * bar_size # Create a bar out of `bar_size` unicode FULL BLOCK characters
61-
bar = bar.ljust(cols - 7, u' ') # Pad the bar to the full with of the terminal, minus the "00.00cm " prefix
62-
sys.stdout.write("\r") # Return the cursor to the beginning of the current line
67+
distance_in_mm = tof.get_distance() # Grab the range in mm
68+
distance_in_mm = min(MAX_DISTANCE_MM, distance_in_mm) # Cap at our MAX_DISTANCE
69+
bar_size = int((distance_in_mm / float(MAX_DISTANCE_MM)) * (cols - 10)) # Scale bar_size to our terminal width
70+
bar = BAR_CHAR * bar_size # Create a bar out of `bar_size` unicode FULL BLOCK characters
71+
bar = bar.ljust(cols - 7, u' ') # Pad the bar to the full with of the terminal, minus the "00.00cm " prefix
72+
sys.stdout.write("\r") # Return the cursor to the beginning of the current line
73+
sys.stdout.flush()
6374
color = ANSI_COLOR_GREEN
6475
if distance_in_mm < MAX_DISTANCE_MM * 0.6:
6576
color = ANSI_COLOR_YELLOW
6677
if distance_in_mm < MAX_DISTANCE_MM * 0.3:
6778
color = ANSI_COLOR_RED
6879
sys.stdout.write(color)
69-
sys.stdout.write(u"{:04.1f}cm {}".format(distance_in_mm/10.0, bar)) # Output our measurement and bar
80+
sys.stdout.write(u"{:04.1f}cm {}".format(distance_in_mm / 10.0, bar)) # Output our measurement and bar
7081
sys.stdout.write(ANSI_COLOR_RESET)
71-
sys.stdout.flush() # Flush the output buffer, since we're overdrawing the last line
72-
time.sleep(0.1)
73-
82+
sys.stdout.flush() # Flush the output buffer, since we're overdrawing the last line
83+
time.sleep(INTER_MEASUREMENT_PERIOD_MILLIS / 1000.0)

examples/trigger.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
import VL53L1X
99

10-
MAX_DISTANCE_MM = 800 # Distance at which our bar is full
10+
MAX_DISTANCE_MM = 800 # Distance at which our bar is full
1111
TRIGGER_DISTANCE_MM = 80
12-
BAR_CHAR = u'\u2588' # Unicode FULL BLOCK
12+
BAR_CHAR = u'\u2588' # Unicode FULL BLOCK
1313

1414
ANSI_COLOR_RED = "\x1b[31m"
1515
ANSI_COLOR_RESET = "\x1b[0m"
@@ -33,37 +33,39 @@
3333
Open and start the VL53L1X ranging sensor
3434
"""
3535
tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
36-
tof.open() # Initialise the i2c bus and configure the sensor
37-
tof.start_ranging(1) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
36+
tof.open() # Initialise the i2c bus and configure the sensor
37+
tof.start_ranging(1) # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
3838

3939

4040
sys.stdout.write("\n")
4141

4242
trigger_mark = int((cols / float(MAX_DISTANCE_MM)) * TRIGGER_DISTANCE_MM)
4343

44-
sys.stdout.write("|".rjust(trigger_mark + 7, " ") + " - {:04.1f}cm ".format(TRIGGER_DISTANCE_MM/10.0) + "\n")
44+
sys.stdout.write("|".rjust(trigger_mark + 7, " ") + " - {:04.1f}cm ".format(TRIGGER_DISTANCE_MM / 10.0) + "\n")
4545

4646
running = True
4747

48+
4849
def exit_handler(signal, frame):
4950
global running
5051
running = False
51-
tof.stop_ranging() # Stop ranging
52+
tof.stop_ranging()
5253
sys.stdout.write("\n")
5354
sys.exit(0)
5455

56+
5557
signal.signal(signal.SIGINT, exit_handler)
5658

5759
while running:
58-
distance_in_mm = tof.get_distance() # Grab the range in mm
59-
distance_in_mm = min(MAX_DISTANCE_MM, distance_in_mm) # Cap at our MAX_DISTANCE
60-
bar_size = int((distance_in_mm / float(MAX_DISTANCE_MM)) * (cols-10)) # Scale bar_size to our terminal width
61-
bar = BAR_CHAR * bar_size # Create a bar out of `bar_size` unicode FULL BLOCK characters
62-
bar = bar.ljust(cols - 7, u' ') # Pad the bar to the full with of the terminal, minus the "00.0cm " prefix
63-
sys.stdout.write("\r") # Return the cursor to the beginning of the current line
60+
distance_in_mm = tof.get_distance() # Grab the range in mm
61+
distance_in_mm = min(MAX_DISTANCE_MM, distance_in_mm) # Cap at our MAX_DISTANCE
62+
bar_size = int((distance_in_mm / float(MAX_DISTANCE_MM)) * (cols - 10)) # Scale bar_size to our terminal width
63+
bar = BAR_CHAR * bar_size # Create a bar out of `bar_size` unicode FULL BLOCK characters
64+
bar = bar.ljust(cols - 7, u' ') # Pad the bar to the full with of the terminal, minus the "00.0cm " prefix
65+
sys.stdout.write("\r") # Return the cursor to the beginning of the current line
6466
if distance_in_mm < TRIGGER_DISTANCE_MM:
6567
sys.stdout.write(ANSI_COLOR_RED)
66-
sys.stdout.write(u"{:04.1f}cm {}".format(distance_in_mm/10.0, bar)) # Output our measurement and bar
68+
sys.stdout.write(u"{:04.1f}cm {}".format(distance_in_mm / 10.0, bar)) # Output our measurement and bar
6769
sys.stdout.write(ANSI_COLOR_RESET)
68-
sys.stdout.flush() # Flush the output buffer, since we're overdrawing the last line
70+
sys.stdout.flush() # Flush the output buffer, since we're overdrawing the last line
6971
time.sleep(0.1)

python/VL53L1X.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@
2727
import site
2828
import glob
2929

30+
3031
class VL53L1xError(RuntimeError):
3132
pass
3233

34+
3335
class VL53L1xDistanceMode:
36+
NONE = 0
3437
SHORT = 1
3538
MEDIUM = 2
3639
LONG = 3
3740

41+
3842
# Read/write function pointer types.
3943
_I2C_MULTI_FUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte)
4044
_I2C_READ_FUNC = CFUNCTYPE(c_int, c_ubyte, c_ubyte, POINTER(c_ubyte), c_ubyte)
@@ -59,10 +63,10 @@ class VL53L1xDistanceMode:
5963
lib_file = files[0]
6064
try:
6165
_TOF_LIBRARY = CDLL(lib_file)
62-
#print("Using: " + lib_location + "/vl51l1x_python.so")
66+
# print("Using: " + lib_location + "/vl51l1x_python.so")
6367
break
6468
except OSError:
65-
#print(lib_location + "/vl51l1x_python.so not found")
69+
# print(lib_location + "/vl51l1x_python.so not found")
6670
pass
6771
else:
6872
raise OSError('Could not find vl53l1x_python.so')
@@ -85,11 +89,11 @@ def __init__(self, i2c_bus=1, i2c_address=0x29, tca9548a_num=255, tca9548a_addr=
8589

8690
self._dev = None
8791
# Register Address
88-
self.ADDR_UNIT_ID_HIGH = 0x16 # Serial number high byte
89-
self.ADDR_UNIT_ID_LOW = 0x17 # Serial number low byte
90-
self.ADDR_I2C_ID_HIGH = 0x18 # Write serial number high byte for I2C address unlock
91-
self.ADDR_I2C_ID_LOW = 0x19 # Write serial number low byte for I2C address unlock
92-
self.ADDR_I2C_SEC_ADDR = 0x8a # Write new I2C address after unlock
92+
self.ADDR_UNIT_ID_HIGH = 0x16 # Serial number high byte
93+
self.ADDR_UNIT_ID_LOW = 0x17 # Serial number low byte
94+
self.ADDR_I2C_ID_HIGH = 0x18 # Write serial number high byte for I2C address unlock
95+
self.ADDR_I2C_ID_LOW = 0x19 # Write serial number low byte for I2C address unlock
96+
self.ADDR_I2C_SEC_ADDR = 0x8a # Write new I2C address after unlock
9397

9498
def open(self, reset=False):
9599
self._i2c.open(bus=self._i2c_bus)
@@ -149,6 +153,14 @@ def start_ranging(self, mode=VL53L1xDistanceMode.LONG):
149153
"""Start VL53L1X ToF Sensor Ranging"""
150154
_TOF_LIBRARY.startRanging(self._dev, mode)
151155

156+
def set_distance_mode(self, mode):
157+
"""Set distance mode
158+
159+
:param mode: One of 1 = Short, 2 = Medium or 3 = Long
160+
161+
"""
162+
_TOF_LIBRARY.setDistanceMode(self._dev, mode)
163+
152164
def stop_ranging(self):
153165
"""Stop VL53L1X ToF Sensor Ranging"""
154166
_TOF_LIBRARY.stopRanging(self._dev)
@@ -157,6 +169,33 @@ def get_distance(self):
157169
"""Get distance from VL53L1X ToF Sensor"""
158170
return _TOF_LIBRARY.getDistance(self._dev)
159171

172+
def set_timing(self, timing_budget, inter_measurement_period):
173+
"""Set the timing budget and inter measurement period.
174+
175+
A higher timing budget results in greater measurement accuracy,
176+
but also a higher power consumption.
177+
178+
The inter measurement period must be >= the timing budget, otherwise
179+
it will be double the expected value.
180+
181+
:param timing_budget: Timing budget in microseconds
182+
:param inter_measurement_period: Inter Measurement Period in milliseconds
183+
184+
"""
185+
if (inter_measurement_period * 1000) < timing_budget:
186+
raise ValueError("The Inter Measurement Period must be >= Timing Budget")
187+
188+
self.set_timing_budget(timing_budget)
189+
self.set_inter_measurement_period(inter_measurement_period)
190+
191+
def set_timing_budget(self, timing_budget):
192+
"""Set the timing budget in microseocnds"""
193+
_TOF_LIBRARY.setMeasurementTimingBudgetMicroSeconds(self._dev, timing_budget)
194+
195+
def set_inter_measurement_period(self, period):
196+
"""Set the inter-measurement period in milliseconds"""
197+
_TOF_LIBRARY.setInterMeasurementPeriodMilliSeconds(self._dev, period)
198+
160199
# This function included to show how to access the ST library directly
161200
# from python instead of through the simplified interface
162201
def get_timing(self):

0 commit comments

Comments
 (0)