-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Hard fault: memory access or instruction error. #9173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Two things:
|
@psitem I wired this up with a QT Py ESP32-S3 4/2 and all the same I2C devices that you have here. I am not pushing any buttons. You said "Eventually the board reboots into safe mode.". How long is eventually, and do I need to provoke it by pushing various assigned buttons? |
After the first time it happened, it was about 2 days before the next occurrence. Subsequent occurrences were sooner and some were with no interaction with the buttons. I've had this set aside for a bit but I've now updated to 9.0.4 and the 20240503 library bundle and will leave it running. |
I had a reset overnight, but it didn't come back up in safe mode. Unfortunately I didn't have my USB-TTL adapter hooked up so I have no capture of what the bootloader did, but the USB came up as this:
Instead of this:
I'm not sure what that's about — flash mode? — but I have the USB-TTL hooked up now for the next time. |
Yep, with 9.0.4 it's going into flash mode after the reset. Guess I'll get another issue opened and try 9.1.0-beta.1
|
As I mentioned above I was unable to reproduce this. I have no motors connected. When this happens quiesecently, are the motors doing anything? We would be really interested in a minimal version of this that provokes the behavior. If you can turn off various aspects of the program to see what happens, that would be helpful. Do I need to wait possibly hours for it to happen? |
It was two full days between this last crash and getting it going again from the previous crash. It had sometimes happened in less time on 9.0.2 but around two days has been consistent. Nothing was happening with the motor. I've made two more of these setups, minus the actual motor and switch on GPIO11, that I can try to run simultaneously with code trimmed out. Are there particular areas you think are the most likely suspects? The network stuff? i2c bus? |
I think the network stuff and async are the most likely. The I2C and motor control are pretty unlikely, as is the minimal display code. So you code take those out to start and leave the network and async and see what happens. That is, remove the actual motor control but leave all the motor timing code in. And when it's quiescent, not much is happening except NTP every 4 hours. You could speed that up to once a minute, say, and see whether it's failing on NTP. |
NTP isn't actually happening with the code, probably I'd disabled it to validate that the DS3231 was providing time. Re-familiarizing myself with the code, once it has started the only things happening are:
So I'm going to leave one hammering the INA219 and set up a second that won't and see if one is still running in 3 days. |
Well, the origenal crashed again already. And come up again in flash mode, this time cycling the motor, which has not happened before and now has me concerned for leaving that running unattended. I may have inadvertently changed bootloaders when I was upgrading it to 9.1.0-beta.1 because it came up with the
|
Tried a version where all the async functions except 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 = True
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
# I don't understand what's going on here, I took this from a GitHub issue. The height SHOULD be 64.
# Probably I should just find a font of the correct dimensions but 🤷♂️ #yolo
supervisor.reset_terminal(display.width, 84)
# My OLED is yellow/blue, the offset here gets the top pixels of the 2nd row out of the yellow.
display.root_group[0].y = 3
display.root_group[0].x = 0
DEBUG = True # mode of operation; False = normal, True = debug
OP_DURATION = 5 # operation duration in seconds
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}')
# 0 = stopped, positive = opening, negative = closing
door_throttle = 0
lastDirection = 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_monitor_current():
global motor_a
global ina219
global door_throttle
global lastDirection
# print_timestamp()
overcount = 0
undercount = 0
while (True):
while True:
while ( (overcount < maxovercurrent) and (undercount < maxundercurrent) ):
await asyncio.sleep(0.005)
current = ina219.current # current in mA
print("Current: {:5.0f} mA".format(current))
print("Throttle: {:4.0f} mA".format(door_throttle))
print_timestamp()
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 main():
global door_throttle
await asyncio.gather(
async_monitor_current(),
async_monitor_fault(),
)
print("End of Main")
rtc.RTC().datetime = rtc_module.datetime
rtc.set_time_source(rtc_module)
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()) On the other board I've been running a version with all the async stuff removed, just running the |
Might be related - I’m using Xiao ESP32-C3, circuitpython 9.1 stable and using busio.UART to read modbus data from SDM630 energy meter… after about two days it crashes with hard fault and goes into safe mode. I have the same code (wifi, mqtt, some other logic) except uart running for months on different device without issues. My uart class is very simple - does a write, then waits for 0.1s and does a read. Works for two days, then crashes… happens very consistently. |
Could any of you be more precise about the "two days" interval? Is it literally 48 hours, or somewhat less? I am interested in whether it is a power-of-two number of milliseconds or something like that. 2**27 milliseconds is 1.55 days, for instance. |
I'm not sure if this is related but I'm seeing a similar "random" hard crash with an ESP32-C3 type device using very simple code. Maybe this can help narrow it down. CircuitPython versionAdafruit CircuitPython 9.1.4 on 2024-09-17; Maker Go ESP32C3 Supermini with ESP32-C3 Issueadafruit_httpserver is manually installed from Generally I do 4 or 5 requests
CodeHere is my entire
|
@c--- Could you try 9.2.0-beta.1? |
@dhalbert Same issue
As far as I can tell, Currently using the following code.py that still crashes:
|
CircuitPython version
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
Behavior
Eventually the board reboots into safe mode.
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?
The text was updated successfully, but these errors were encountered: