Untitled
unknown
plain_text
4 months ago
3.9 kB
2
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