from machine import Pin
import utime
from neopixel import Neopixel
# Constants for Pins
TRIGGER_PIN = 0
ECHO_PIN = 1
# Constants for LED Gauge
MIN_DISTANCE = 50
MAX_DISTANCE = 200
MIN_LEDS = 0
MAX_LEDS = 16
# Constants for LED Colors
GREEN_COLOR = (0, 255, 0)
RED_COLOR = (255, 0, 0)
OFF_COLOR = (0, 0, 0) # Black, for turning off LEDs
# Brightness factor (between 0.0 and 1.0)
BRIGHTNESS = 0.5 # Adjust this value to set the desired brightness
# Constants for Flashing
FLASH_INTERVALS = {0: 0.2, 1: 0.3, 2: 0.4, 3: 0.5}
# Constants for timeout
DISTANCE_TIMEOUT = 5 * 1000 # Set the timeout period in milliseconds
HYSTERESIS_THRESHOLD = 10.0 # Set the hysteresis threshold in distance units
# Initialize Ultrasonic Sensor
trigger = Pin(TRIGGER_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)
def get_distance():
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep_us(5)
trigger.low()
signaloff = utime.ticks_us() # Initialize with default values
while echo.value() == 0:
signaloff = utime.ticks_us()
signalon = utime.ticks_us() # Initialize with default values
while echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0343) / 2
return distance
# Initialize Neopixel
pixels = Neopixel(16, 0, 6, "GRB")
# Initialize the time of the last distance change
last_distance_change_time = utime.ticks_ms()
# Initialize the last_distance variable
last_distance = None
# Initialize LED state (on or off)
leds_on = False
while True:
distance = get_distance()
# Ensure distance is within the specified range
if MIN_DISTANCE <= distance <= MAX_DISTANCE:
# Calculate the number of LEDs to turn green based on the distance range
leds_to_turn_green = int((distance - MIN_DISTANCE) / (MAX_DISTANCE - MIN_DISTANCE) * (MAX_LEDS - MIN_LEDS)) + MIN_LEDS
# Determine the flashing interval based on the number of green LEDs
flash_interval = FLASH_INTERVALS.get(leds_to_turn_green, 0.2)
# LED Gauge Display
if leds_on: # Check if LEDs should be on
if leds_to_turn_green <= 3:
for i in range(16):
if i < leds_to_turn_green:
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in GREEN_COLOR))
else:
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in RED_COLOR))
pixels.show()
utime.sleep(flash_interval)
for i in range(16):
if i < leds_to_turn_green:
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in GREEN_COLOR))
else:
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in OFF_COLOR))
pixels.show()
utime.sleep(flash_interval)
else:
# Delay for the normal display
for i in range(16):
if i < leds_to_turn_green:
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in GREEN_COLOR))
else:
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in RED_COLOR))
pixels.show()
utime.sleep(0.1) # Adjust this value to change the duration of the normal display
# Check if the distance has changed and update the last change time and last_distance
if last_distance is None or abs(distance - last_distance) > HYSTERESIS_THRESHOLD:
last_distance_change_time = utime.ticks_ms()
last_distance = distance
leds_on = True # Distance changed, turn LEDs on
else:
# Distance is outside the range
leds_on = False # Distance is outside the range, turn LEDs off
# Turn off all LEDs
for i in range(16):
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in OFF_COLOR))
pixels.show()
# Check if the distance has remained unchanged for the timeout period
if leds_on and utime.ticks_diff(utime.ticks_ms(), last_distance_change_time) > DISTANCE_TIMEOUT:
for i in range(16):
pixels.set_pixel(i, tuple(int(c * BRIGHTNESS) for c in OFF_COLOR))
pixels.show()
leds_on = False # LEDs turned off due to timeout