Open
Description
CircuitPython version
Adafruit CircuitPython 9.0.3 on 2024-04-04; Waveshare ESP32-S3-Zero with ESP32S3
Board ID:waveshare_esp32_s3_zero
UID:437BAD95F6CC
Libraries updated to adafruit-circuitpython-bundle-9.x-mpy-20240411.zip. Plus async_button library from https://github.com/furbrain/CircuitPython_async_button/releases/download/1.2.3/circuitpython-async-button-py-1.2.3.zip
Code/REPL
import time
import board
import busio
import supervisor
from digitalio import DigitalInOut, Direction, Pull
from pwmio import PWMOut
from adafruit_motor import motor as Motor
import gc
import rtc
import displayio
import adafruit_displayio_ssd1306
import adafruit_ina219
import wifi
import adafruit_ds3231
import adafruit_ntp
import socketpool
import asyncio
from async_button import Button, MultiButton
extended_debug = False
timeset = False
displayio.release_displays()
scl_pin = board.IO2
sda_pin = board.IO1
i2c = busio.I2C(scl_pin, sda_pin)
rtc_module = adafruit_ds3231.DS3231(i2c)
ina219 = adafruit_ina219.INA219(i2c)
ina219.bus_adc_resolution = adafruit_ina219.ADCResolution.ADCRES_12BIT_16S
ina219.shunt_adc_resolution = adafruit_ina219.ADCResolution.ADCRES_12BIT_16S
maxcurrent = 300
maxovercurrent = 4
mincurrent = 50
maxundercurrent = 10
light_state = False
if (True):
display_bus = displayio.I2CDisplay(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
display.root_group[0].hidden = False
display.root_group[1].hidden = True
display.root_group[2].hidden = True
try:
display.root_group.remove(display.root_group[2])
display.root_group.remove(display.root_group[1])
except Exception as e:
# print(e)
e = None
supervisor.reset_terminal(display.width, 84)
display.root_group[0].y = 3
display.root_group[0].x = 0
drv8833_ain1 = PWMOut(board.IO5, frequency=100)
drv8833_ain2 = PWMOut(board.IO4, frequency=100)
drv8833_enable = DigitalInOut(board.IO3)
drv8833_enable.direction = Direction.OUTPUT
drv8833_enable.value = True
# Note: Inverted, goes low for Fault conditions.
drv8833_fault = DigitalInOut(board.IO6)
drv8833_fault.direction = Direction.INPUT
drv8833_fault.pull = Pull.UP
motor_a = Motor.DCMotor(drv8833_ain1, drv8833_ain2)
motor_a.throttle = None
def print_timestamp():
print("Time: " + f'{time.localtime().tm_hour:02d} {time.localtime().tm_min:02d} {time.localtime().tm_sec:02d}')
CLICK_NAMES = {
Button.SINGLE: "Single click",
Button.DOUBLE: "Double click",
Button.TRIPLE: "Triple click",
Button.LONG: "Long click",
Button.PRESSED: "Pressed",
Button.RELEASED: "Released",
}
door_moving = False
door_direction = None
door_closed = True
door_opened = False
# 0 = stopped, positive = opening, negative = closing
door_throttle = 0
lastDirection = 1
DOOR_STATES = {
"Opened": 1,
"Closed": 0,
}
async def click_watcher(button: MultiButton):
global door_moving
while True:
button_name, click = await button.wait(BTN1=Button.ANY_CLICK , BTN2=Button.ANY_CLICK, BTN3=Button.ANY_CLICK)
print(f"{button_name}: {CLICK_NAMES[click]}")
async def async_stop_btn(button: MultiButton):
global door_throttle
while True:
await button.wait(BTN2=Button.SINGLE)
print_timestamp()
print("Stop.")
door_throttle = 0
await asyncio.sleep(0.10)
print("Throttle: " + str(motor_a.throttle))
async def async_open_btn(button: MultiButton):
global door_throttle
while True:
await button.wait(BTN3=Button.SINGLE)
door_throttle = 1
async def async_close_btn(button: MultiButton):
global door_throttle
while True:
await button.wait(BTN4=Button.SINGLE)
door_throttle = -1
async def async_light_btn(button: MultiButton):
global light_state
while True:
button_name, click = await button.wait(BTN1=Button.SINGLE)
light_state = not light_state
print("Light: " + str(light_state))
asyncio.sleep(0.25)
async def async_kill_switch(button: MultiButton):
global lastDirection
global motor_a
global door_throttle
while True:
button_name, click = await button.wait(BTN5=Button.PRESSED)
print_timestamp()
print("Kill switch.")
door_throttle = None
asyncio.sleep(0.100)
print("Opening door.")
door_throttle = -1
async def async_open_close_btn(button: MultiButton):
global lastDirection
global motor_a
global door_throttle
while True:
button_name, click = await button.wait(BTN3=Button.SINGLE)
print("Last: " + str(lastDirection))
if ( (door_throttle is None) or (door_throttle == 0) ):
print("Starting")
door_throttle = -lastDirection
lastDirection = door_throttle
else:
lastDirection = door_throttle
door_throttle = 0
print("Starting.")
print("Throttle: " + str(motor_a.throttle))
print("Now: " + str(lastDirection))
async def async_move_door(throttle: int):
global motor_a
global door_throttle
motor_a.throttle = throttle
while True:
if (door_throttle == 0):
motor_a.throttle = None
else:
motor_a.throttle = door_throttle
await asyncio.sleep(0.05)
#async def async_monitor_current(duration: int):
async def async_monitor_current():
global motor_a
global ina219
global door_throttle
global lastDirection
# print_timestamp()
overcount = 0
undercount = 0
while (True):
# now = time.monotonic() # Time in seconds since power on
# while (now + duration) > time.monotonic():
while ( ( door_throttle != 0 ) ):
while ( (overcount < maxovercurrent) and (undercount < maxundercurrent) ):
await asyncio.sleep(0.005)
current = ina219.current # current in mA
# print("Current: {:5.0f} mA".format(current))
if ( current > maxcurrent ):
overcount += 1
print("Current: {:5.0f} mA".format(current))
print("Over-Current Count: {:1d}".format(overcount))
elif ( ( door_throttle != 0 ) and ( current <mincurrent )):
pass
undercount += 1
print("Current: {:5.0f} mA".format(current))
print("Under-Current Count: {:1d}".format(undercount))
elif ( (current < maxcurrent) and (current > mincurrent) ):
undercount = 0
overcount = 0
print("Stopping.")
door_throttle = 0
overcount = 0
undercount = 0
print_timestamp()
await asyncio.sleep(0.10)
print("Throttle: " + str(motor_a.throttle))
await asyncio.sleep(0.05)
async def async_dump_throttle():
global motor_a
while (True):
# print("Throttle: " + str(motor_a.throttle))
# print("Enable: " + str(drv8833_enable.value))
# print("Fault: " + str(not drv8833_fault.value))
# print("Memory free: " + f'{gc.mem_free():>7}')
await asyncio.sleep(1)
async def async_monitor_fault():
global drv8833_fault
while (True):
# Pin is inverted
if not drv8833_fault:
print_timestamp()
print("Fault: " + str(not drv8833_fault.value))
print("Stopping due to Fault.")
door_throttle = 0
await asyncio.sleep(0.005)
async def async_ntp():
global ntp
global pool
global timeset
global rtc_module
while(False):
loopcount = 0
while ( (not timeset) and (loopcount < 5) ):
if ( extended_debug ):
print("Entering NTP loop.")
print("loopcount: " + str(loopcount))
try:
loopcount += 1
rtc.RTC().datetime = ntp.datetime
rtc_module.datetime = ntp.datetime
timeset = True
except Exception as e:
pass
await asyncio.sleep(4 * 60 * 60) # sleep 4 hours
async def main():
global door_throttle
# Yellow / Light
BTN1 = Button(
board.IO10,
value_when_pressed=False,
long_click_enable=True,
long_click_min_duration=0.7,
triple_click_enable=False,
double_click_enable=False,
)
# Red / Stop
BTN2 = Button(
board.IO9,
value_when_pressed=False,
long_click_enable=True,
long_click_min_duration=0.7,
triple_click_enable=False,
double_click_enable=False,
)
# Green / Go
BTN3 = Button(
board.IO8,
value_when_pressed=False,
long_click_enable=True,
long_click_min_duration=0.7,
triple_click_enable=False,
double_click_enable=False,
)
# Door Kill Switch
BTN5 = Button(
board.IO11,
value_when_pressed=False,
triple_click_enable=False,
double_click_enable=False,
)
multibutton = MultiButton(BTN1=BTN1, BTN2=BTN2, BTN3=BTN3, BTN5=BTN5)
await asyncio.gather(async_open_close_btn(multibutton),
async_kill_switch(multibutton),
async_stop_btn(multibutton),
async_light_btn(multibutton),
async_monitor_current(),
async_move_door(0),
async_dump_throttle(),
async_ntp(),
async_monitor_fault(),
)
print("End of Main")
rtc.RTC().datetime = rtc_module.datetime
rtc.set_time_source(rtc_module)
print(str(wifi.radio.ipv4_address))
pool = socketpool.SocketPool(wifi.radio)
ntp = adafruit_ntp.NTP(pool, tz_offset=0)
# print("Localtime: " + str(time.localtime()))
# print("RTC time: " + str(rtc.RTC().datetime))
# print("i2c time: " + str(rtc_module.datetime))
print("Date: " + f'{time.localtime().tm_year:04d} {time.localtime().tm_mon:02d} {time.localtime().tm_mday:02d}')
print("Time: " + f'{time.localtime().tm_hour:02d} {time.localtime().tm_min:02d} {time.localtime().tm_sec:02d}')
asyncio.run(main())
Behavior
Eventually the board reboots into safe mode.
Auto-reload is off.
Running in safe mode! Not running saved code.
You are in safe mode because:
CircuitPython core code crashed hard. Whoops!
Hard fault: memory access or instruction error.
Please file an issue with your program at github.com/adafruit/circuitpython/issues.
Press reset to exit safe mode.
Press any key to enter the REPL. Use CTRL-D to reload.
Description
No response
Additional information
I hooked up a USB-TTL adapter to the TX pin on the board and got this. Is there anything that can be done to output more debug info?
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xb (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x138
load:0x403c9700,len:0x4
load:0x403c9704,len:0xa9c
load:0x403cc700,len:0x26d4
entry 0x403c9870
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xb (SPI_FAST_FLASH_BOOT)
Saved PC:0x4037cd5e
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x138
load:0x403c9700,len:0x4
load:0x403c9704,len:0xa9c
load:0x403cc700,len:0x26d4
entry 0x403c9870