Display Type §
Distance Detection Display §
⚠️ Warning: Driver themselves should be accountable of their own awareness and this is only a guidance tool for them to evaluate the vehicle’s physical presence, this does not remove the need to be aware throughout the whole driving!
Preface §
In order to provide safer driving experience for both the driver, objects and people around the vehicle, the time of flight sensors are used for the vehicle. Namely, VL53L5CX sensor is used, which provides us 8x8 multizone ranging with wide field of view perspective.
Code §
MicroPython was used to output this feedback to the driver due to available libraries and ease of demoing. The components in use are not as safety critical, unlike the hydrogen valve control, due to the fact that in the case of this component missing, this component’s failure will not prevent further functions of the driving process.
Code block §
The following code is also available in GitHub and up to date.
https://github.com/Kodalem/VL53L5CX-LED-Display-Output
import pimoroni_i2c
import breakout_vl53l5cx
import time
from picographics import PicoGraphics, DISPLAY_LCD_240X240
from pimoroni import RGBLED
# The VL53L5CX requires a firmware blob to start up.
# Make sure you upload "vl53l5cx_firmware.bin" via Thonny to the root of your filesystem
# You can find it here: https://github.com/ST-mirror/VL53L5CX_ULD_driver/blob/no-fw/lite/en/vl53l5cx_firmware.bin
PINS_BREAKOUT_GARDEN = { "sda" : 4 , "scl" : 5 }
PINS_PICO_EXPLORER = { "sda" : 20 , "scl" : 21 }
# Sensor startup time is proportional to i2c baudrate
# HOWEVER many sensors may not run at > 400KHz (400000)
i2c = pimoroni_i2c.PimoroniI2C( ** PINS_BREAKOUT_GARDEN , baudrate = 2_000_000 )
# Display setup, check your own following display type, default is LCD 240x240
display = PicoGraphics( display = DISPLAY_LCD_240X240 )
display.set_backlight( 1.0 )
BG = display.create_pen( 40 , 40 , 40 )
display.set_pen( BG )
# Sensor setup
print ( "Starting up sensor..." )
t_sta = time.ticks_ms()
sensor = breakout_vl53l5cx.VL53L5CX(i2c)
t_end = time.ticks_ms()
print ( "Done in {} ms..." .format(t_end - t_sta))
# Make sure to set resolution and other settings *before* you start ranging
# 4x4 or 8x8
IS_8X8 = True
if IS_8X8 :
sensor.set_resolution(breakout_vl53l5cx. RESOLUTION_8X8 )
# 1-15 Hz for 8x8
sensor.set_ranging_frequency_hz( 15 )
else :
sensor.set_resolution(breakout_vl53l5cx. RESOLUTION_4X4 )
# 1-60 Hz for 4x4
sensor.set_ranging_frequency_hz( 60 )
# Start ranging
sensor.start_ranging()
def update_display_grid_distance (sensor_data):
# Save the distance RGB grid as 2D matrix
data_colour = []
# Set the max distance for the sensor
sensor_max_distance = 750
# Append the sensor data according to the sensor matrix size,
# multidimensional append each row of the matrix. # Loop through the sensor touple data and append it to the matrix according to rows and columns if IS_8X8:
for column in range ( 8 ):
data_colour.append([])
for row in range ( 8 ):
# Get the distance value from the sensor touple
distance = sensor_data.distance[column * 8 + row]
# Calculate the distance percentage
distance_colour = 255 - int ((distance / sensor_max_distance) * 255 )
# Append the distance colour to the matrix
data_colour[column].append(distance_colour)
else :
for column in range ( 4 ):
data_colour.append([])
for row in range ( 4 ):
# Get the distance value from the sensor touple
distance = sensor_data.distance[column * 4 + row]
# Calculate the distance percentage
distance_colour = 255 - int ((distance / sensor_max_distance) * 255 )
# Append the distance colour to the matrix
data_colour[column].append(distance_colour)
# Divide the screen into according grid into the sensor matrix size
# Get the screen size WIDTH, HEIGHT = display.get_bounds()
if IS_8X8 :
grid_step_x_init = int ( WIDTH / 8 )
grid_step_y_init = int ( HEIGHT / 8 )
else :
grid_step_x_init = int ( WIDTH / 4 )
grid_step_y_init = int ( HEIGHT / 4 )
grid_size = 4
grid_step_x = 0
grid_step_y = 0
display.clear()
print ( "Colour matrix: {} " .format(data_colour))
# Draw the grid from the 2-dimensional matrix array
for column in range ( len (data_colour)):
for row in range ( len (data_colour[column])):
# Set the grid colour pen
distance_pen = display.create_pen(data_colour[column][row], 0 , 0 )
# Set the grid colour
display.set_pen(distance_pen)
# Draw the grid
display.rectangle(grid_step_x, grid_step_y, grid_step_x_init, grid_step_y_init)
# Increase the grid step of x
grid_step_x += grid_step_x_init
# Increase the grid step of y
grid_step_y += grid_step_y_init
# Reset the grid step of x
grid_step_x = 0
display.update()
while True :
display.set_pen( BG )
display.clear()
if sensor.data_ready():
# "data" is a namedtuple (attrtuple technically)
# it includes average readings as "distance_avg" and "reflectance_avg" # plus a full 4x4 or 8x8 set of readings (as a 1d tuple) for both values. data = sensor.get_data()
update_display_grid_distance(data)
print ( " {} mm {} % (avg: {} mm {} %)" .format(
data.distance[ 0 ],
data.reflectance[ 0 ],
data.distance_avg,
data.reflectance_avg))
Visual Demo §