Untitled

 avatar
unknown
plain_text
4 months ago
4.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
import threading
import os

# Initialize I2C bus
i2c = busio.I2C(board.SCL, board.SDA)

# Initialize the TCA9548A multiplexer
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  # 0%
MIN_DISTANCE = 0    # 100%
FULL_THRESHOLD = 50  # Threshold for "bin full" message
SAMPLING_TIME = 1.5  # Time in seconds to collect readings
SAMPLING_RATE = 0.05  # Time between individual readings

def clear_screen():
    """Clear the terminal screen"""
    os.system('cls' if os.name == 'nt' else 'clear')

def print_header():
    """Print a nice header"""
    print("╔════════════════════════════════════════╗")
    print("║         Fill Level Measurement         ║")
    print("╚════════════════════════════════════════╝")
    print("\nPress any key to take a measurement")
    print("Press 'q' to quit\n")

def print_measuring():
    """Print measuring message"""
    print("\n⏳ Measuring...\n")

def print_result(percentage=None, is_full=False):
    """Print the result in a nice format"""
    print("\n╔════════════════════════════════════════╗")
    if is_full:
        print("║             ⚠️  BIN FULL ⚠️            ║")
    else:
        fill_bar = create_fill_bar(percentage)
        print(f"║ Fill Level: {percentage:>5.1f}%              ║")
        print("║                                    ║")
        print(f"║ {fill_bar} ║")
    print("╚════════════════════════════════════════╝\n")

def create_fill_bar(percentage):
    """Create a visual fill bar"""
    bar_length = 20
    filled_length = int(percentage / 100 * bar_length)
    bar = '█' * filled_length + '░' * (bar_length - filled_length)
    return bar

def distance_to_percentage(distance):
    """Convert distance to percentage where 400mm = 0% and 0mm = 100%"""
    distance = min(max(distance, MIN_DISTANCE), MAX_DISTANCE)
    percentage = ((MAX_DISTANCE - distance) / (MAX_DISTANCE - MIN_DISTANCE)) * 100
    return round(percentage, 1)

def get_measurements():
    """Take multiple measurements over SAMPLING_TIME seconds"""
    end_time = time.time() + SAMPLING_TIME
    all_readings = []
    
    while time.time() < end_time:
        readings = []
        for sensor in sensors.values():
            try:
                readings.append(sensor.range)
            except Exception:
                continue
        if readings:
            all_readings.extend(readings)
        time.sleep(SAMPLING_RATE)
    
    return all_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 main():
    clear_screen()
    print_header()
    
    while True:
        # Wait for keypress
        char = getch()
        
        if char.lower() == 'q':
            clear_screen()
            print("\nThank you for using the Fill Level Measurement system!")
            break
            
        clear_screen()
        print_header()
        print_measuring()
        
        # Take multiple measurements
        readings = get_measurements()
        
        if not readings:
            print("Error: No valid readings from sensors")
            continue
            
        # Check if any reading indicates bin is full
        if any(reading <= FULL_THRESHOLD for reading in readings):
            print_result(is_full=True)
        else:
            # Calculate median of all readings
            median_distance = statistics.median(readings)
            percentage = distance_to_percentage(median_distance)
            print_result(percentage=percentage)

if __name__ == "__main__":
    try:
        # Give sensors a moment to initialize
        time.sleep(1)
        main()
    except Exception as e:
        print(f"\nAn error occurred: {str(e)}")
    finally:
        print("\nExiting...")
Editor is loading...
Leave a Comment