From 5fb35c96cb120294fcc27ee365919b99e2b5ad46 Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Thu, 10 Apr 2025 14:41:30 -0600 Subject: [PATCH] Adjust parameters, add firmware update command, add rounding --- src/dimensioner/dimensioner_screen.py | 28 ++++++++++++++++++------- src/dimensioner/dimensioner_utils.py | 26 ++++++++++++++++++----- src/dimensioner/main.py | 30 ++++++++++++++++++++++----- 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/dimensioner/dimensioner_screen.py b/src/dimensioner/dimensioner_screen.py index a454f55..465ce71 100644 --- a/src/dimensioner/dimensioner_screen.py +++ b/src/dimensioner/dimensioner_screen.py @@ -113,7 +113,7 @@ def errorDisplay(code, message = ""): setOLED(oled) oled.fill(0) if code == 1: - line1(" FAULT! ") + line1(" ERROR! ") oled.text(message, 0, 22, 2) if message == "Sensor timeout": pass @@ -155,6 +155,20 @@ def errorDisplay(code, message = ""): oled.text("with current", 0, 38, 2) oled.text("unit setting.", 0, 46, 2) oled.text("Change units.", 0, 54, 2) + elif code == 0x4D: + line1(" REPL ") + oled.text("Device is in", 0, 22, 2) + oled.text("debugging mode.", 0, 30, 2) + oled.text("Power off and", 0, 38, 2) + oled.text("back on to", 0, 46, 2) + oled.text("cancel.", 0, 54, 2) + elif code == 0x50: + line1(" UPDATE ") + oled.text("Device is in", 0, 22, 2) + oled.text("firmware update", 0, 30, 2) + oled.text("mode. Power off", 0, 38, 2) + oled.text("and back on to", 0, 46, 2) + oled.text("cancel.", 0, 54, 2) oled.show() def updateDisplay(measurement, units, tempC): @@ -162,22 +176,22 @@ def updateDisplay(measurement, units, tempC): if ENABLE_DISPLAY: setOLED(oled) wholeNumber = str(math.floor(abs(measurement))) - decimalPart = str(abs(measurement % 1) * 1000) + decimalPart = str(int(abs(measurement % 1) * 100)) numberLine = " " if measurement < 0: numberLine = "-" if units == "mm": - numberLine = numberLine + f"{wholeNumber:>5}.{decimalPart:.1}" + numberLine = numberLine + f"{wholeNumber:>7}" elif units == "cm": - numberLine = numberLine + f"{wholeNumber:>4}.{decimalPart:.2}" + numberLine = numberLine + f"{wholeNumber:>5}.{decimalPart:0<1}" elif units == "in": - numberLine = numberLine + f"{wholeNumber:>4}.{decimalPart:.2}" + numberLine = numberLine + f"{wholeNumber:>4}.{decimalPart:0<2}" elif units == "ft": - numberLine = numberLine + f"{wholeNumber:>3}.{decimalPart:.3}" + numberLine = numberLine + f"{wholeNumber:>4}.{decimalPart:0<2}" oled.fill(0) # Fill with black to clear screen - line1(numberLine) # Write measurement to screen + line1(numberLine[:8]) # Write measurement to screen (but only first 8 chars to prevent IndexError: list index out of range) oled.text(f"{units:^16}", 0, 22, 1) # Write units centered below measurement if measurement == 0: # Write zero indicator on right below measurement oled.text(" ZERO", 0, 22, 1) diff --git a/src/dimensioner/dimensioner_utils.py b/src/dimensioner/dimensioner_utils.py index b89343d..574a86c 100644 --- a/src/dimensioner/dimensioner_utils.py +++ b/src/dimensioner/dimensioner_utils.py @@ -68,17 +68,33 @@ def getUnitsFromByte(byte): def convertMMToUnits(mm, units="in"): units = units.lower() + val = mm if units == "mm": - return mm + val = mm elif units == "cm": - return mm / 10.0 + val = mm / 10.0 elif units == "in": - return mm / 25.4 + val = mm / 25.4 elif units == "ft": - return convertMMToUnits(mm, "in") / 12.0 + val = convertMMToUnits(mm, "in") / 12.0 else: return 0 - + return roundUnits(val, units) + +# Round off the amount to a hardcoded precision suitable for the units used.. +def roundUnits(x, units): + units = units.lower() + precision = 5 + if units == "mm": + precision = 5 + elif units == "cm": + precision = .5 + elif units == "in": + precision = .25 + elif units == "ft": + precision = .05 + return precision * round(x/precision) + # # # Serial communication diff --git a/src/dimensioner/main.py b/src/dimensioner/main.py index a5029af..634933e 100644 --- a/src/dimensioner/main.py +++ b/src/dimensioner/main.py @@ -62,7 +62,7 @@ import sys import select import math -from machine import Pin, UART, time_pulse_us +from machine import Pin, UART, time_pulse_us, reset, bootloader from time import sleep, sleep_us, ticks_diff, ticks_ms import usb.device from micropython import const @@ -80,9 +80,9 @@ SENSOR_MIN_MM = 100 # Minimum range below which sensor is not accurate SENSOR_PIN = 18 # Analog pin for PING sensor SENSOR_TX = 4 # Digital pin for US-100 SENSOR_RX = 5 # Digital pin for US-100 -ZERO_RANGE_MM = 5 # +/- mm away from zero before a non-zero value is transmitted -SAMPLE_SIZE = 50 # Number of times to sample distance per reading, averaging the results -UNSTABLE_DELTA_MM = 25 # Max difference between largest and smallest samples (before averaging), larger than this will report as unstable +ZERO_RANGE_MM = 10 # +/- mm away from zero before a non-zero value is transmitted +SAMPLE_SIZE = 20 # Number of times to sample distance per reading, averaging the results +UNSTABLE_DELTA_MM = 50 # Max difference between largest and smallest samples (before averaging), larger than this will report as unstable ZERO_BUTTON_PIN = 13 # Pin to read if hardware zero button is pressed UNITS_BUTTON_PIN = 14 # Pin to read if hardware unit change button is pressed FIRMWARE_VERSION = "1.0" @@ -141,6 +141,14 @@ class USBHIDInterface(HIDInterface): # Set ambient temperature in degrees C setAmbientTemp(report_data[2]) print("A1: TEMP: "+ambientTempC) + elif report_data[1] == 0x4D: + errorDisplay(0x4D) + print("Soft resetting to MicroPython REPL, power cycle to undo. Goodbye for now!") + machine.reset() + elif report_data[1] == 0x50: + errorDisplay(0x50) + print("Entering firmware update mode, power cycle to undo. Goodbye for now!") + machine.bootloader() else: # Can't understand command send_data(b'\x02\x08\x00\x00\x00\x00\x00') @@ -331,6 +339,18 @@ try: print("A2: UNIT: "+reportUnits) elif data == "?": printConfig() + elif data == "REPL": + errorDisplay(0x4D) + print("REPL: Resetting to MicroPython REPL, power cycle to undo. Goodbye for now!") + sleep_us(500) + machine.reset() + break + elif data == "UPDATE": + errorDisplay(0x50) + print("FWUPD: Entering firmware update mode, power cycle to undo. Goodbye for now!") + sleep_us(500) + machine.bootloader() + break else: errorDisplay(8) print("E8: Unsupported Command from Host: ", data) @@ -338,7 +358,7 @@ try: errorDisplay(8) print("E8: Unsupported Command from Host") try: - dist = getAverageDistanceMM() + dist = getAverageDistanceMM() # Get distance to object if dist < 0: # distance measurement timed out, ultrasonic ping never came back? usbinterface.send_data(b'\x02\x01\x00\x00\x00\x00\x00')