Untitled
unknown
plain_text
a year ago
3.9 kB
4
Indexable
import time
import board
import busio
import adafruit_vl53l0x
from adafruit_tca9548a import TCA9548A
import statistics
import sys
import tty
import termios
# Initialize I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
mux = TCA9548A(i2c)
# Create sensor objects on channels 1, 2, and 4-7
sensors = {
1: adafruit_vl53l0x.VL53L0X(mux[1]),
2: adafruit_vl53l0x.VL53L0X(mux[2]),
4: adafruit_vl53l0x.VL53L0X(mux[4]),
5: adafruit_vl53l0x.VL53L0X(mux[5]),
6: adafruit_vl53l0x.VL53L0X(mux[6]),
7: adafruit_vl53l0x.VL53L0X(mux[7])
}
# Constants
MAX_DISTANCE = 400
MIN_DISTANCE = 0
FULL_THRESHOLD = 50
SAMPLES_PER_SENSOR = 20 # Number of readings per sensor
SAMPLE_DELAY = 0.05 # 50ms between readings
def getch():
"""Get a single character from standard input"""
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def get_filtered_reading(sensor):
"""Get multiple readings from a sensor and filter out outliers"""
readings = []
for _ in range(SAMPLES_PER_SENSOR):
try:
reading = sensor.range
readings.append(reading)
time.sleep(SAMPLE_DELAY)
except Exception:
continue
if not readings:
return None
# Remove outliers: readings outside 2 standard deviations
if len(readings) >= 4: # Need enough samples for statistical validity
mean = statistics.mean(readings)
stdev = statistics.stdev(readings)
filtered_readings = [r for r in readings if (mean - 2 * stdev) <= r <= (mean + 2 * stdev)]
if filtered_readings:
return statistics.median(filtered_readings)
return statistics.median(readings)
def get_fill_level():
"""Get readings from all sensors with statistical filtering"""
all_readings = []
closest_reading = float('inf')
print("Taking precise measurements...")
for sensor_id, sensor in sensors.items():
reading = get_filtered_reading(sensor)
if reading is not None:
all_readings.append(reading)
closest_reading = min(closest_reading, reading)
print(f"Sensor {sensor_id}: {reading:.1f}mm")
if not all_readings:
return None, None
median_distance = statistics.median(all_readings)
percentage = ((MAX_DISTANCE - median_distance) / (MAX_DISTANCE - MIN_DISTANCE)) * 100
percentage = max(0, min(100, percentage)) # Clamp between 0-100%
return closest_reading, percentage
def main():
# Give sensors time to initialize
time.sleep(1)
print("High-Precision Fill Level Measurement")
print("Press any key to measure, 'q' to quit")
while True:
char = getch()
if char.lower() == 'q':
print("\nExiting...")
break
print("\nStarting new measurement cycle...")
closest_reading, percentage = get_fill_level()
if closest_reading is None:
print("Error: Could not get valid readings from sensors")
continue
print("\nResults:")
print(f"Closest distance: {closest_reading:.1f}mm")
if closest_reading <= FULL_THRESHOLD:
print("STATUS: BIN FULL")
else:
print(f"Fill level: {percentage:.1f}%")
print(f"Available space: {(MAX_DISTANCE - closest_reading):.1f}mm")
print("\nPress any key for new measurement, 'q' to quit")
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"\nAn error occurred: {str(e)}")Editor is loading...
Leave a Comment