seveibar/usb-reseter
A tscircuit package created by seveibar.
- Version
- 1.1.4
- License
- unset
- Stars
- 0
firmware/main.py
# USB resetter firmware (MicroPython, RP2040 / Raspberry Pi Pico build)
#
# Send newline-terminated commands over the control USB serial port:
# off cut power to the output port
# on restore power to the output port
# cycle [secs] cut power, wait (default 1s), restore
# status report state and VBUS voltages
# Every command replies with one "OK ..." or "ERR ..." line.
import select
import sys
import time
import neopixel
from machine import ADC, Pin
PWR_CUT = Pin(18, Pin.OUT, value=0) # high = output VBUS off
VBUS_IN = ADC(26)
VBUS_OUT = ADC(27)
led = neopixel.NeoPixel(Pin(29), 1)
DIVIDER = (100 + 150) / 150 # 100k / 150k sense dividers
PRESENT_V = 4.0
def volts(adc):
return adc.read_u16() * 3.3 / 65535 * DIVIDER
def show():
vin, vout = volts(VBUS_IN), volts(VBUS_OUT)
if vin < PRESENT_V:
color = (0, 0, 8) # blue: no power on the input
elif PWR_CUT.value():
color = (16, 0, 0) # red: output cut
elif vout > PRESENT_V:
color = (0, 16, 0) # green: passing power through
else:
color = (16, 8, 0) # amber: enabled but output is low
led[0] = color
led.write()
def status():
state = "off" if PWR_CUT.value() else "on"
return "OK out=%s vin=%.2f vout=%.2f" % (state, volts(VBUS_IN), volts(VBUS_OUT))
def handle(line):
parts = line.split()
if not parts:
return None
cmd, args = parts[0].lower(), parts[1:]
if cmd == "off":
PWR_CUT.value(1)
elif cmd == "on":
PWR_CUT.value(0)
elif cmd in ("cycle", "reset"):
PWR_CUT.value(1)
show()
time.sleep(float(args[0]) if args else 1.0)
PWR_CUT.value(0)
elif cmd != "status":
return "ERR unknown command: " + cmd
return status()
poller = select.poll()
poller.register(sys.stdin, select.POLLIN)
buf = ""
while True:
show()
if not poller.poll(100):
continue
ch = sys.stdin.read(1)
if ch not in ("\n", "\r"):
buf += ch
continue
try:
reply = handle(buf)
except Exception as e:
reply = "ERR " + str(e)
buf = ""
if reply:
print(reply)
