Skip to content

Hard fault in non blocking example (caused by print statements?) #76

@SuperThunder

Description

@SuperThunder

I've found with the nonblocking example if I either

  • hold down one IR remote button then quickly switch to holding down a different one
  • mash the buttons (maybe just the same behaviour as the previous point)

Then it quickly triggers a crash with the error
Hard fault: memory access or instruction error.

However, the fault doesn't occur if:

  • I add a time.sleep(0.1) to the end of the while loop
  • or remove all the print statements
  • or wait a few seconds in between holding down buttons
  • I press the buttons one at a time
  • I write the example into the REPL and run it there
  • (edit) the pulseio object maxlen is increased to ~300

My hardware is

  • Pi Pico with CircuitPython 9.2.8 and 5.0.5 of the library (also have a Feather RP2040 available for testing)
  • generic IR receiver module wired to Pico's GND, 3v3, GP16 through a breadboard
  • generic "Car MP3" remote

Here's my simplified version of the non blocking example. The issue happens with examples/irremote_nonblocking.py as well but the output is a bit spammy.

import pulseio,adafruit_irremote,time,board

pulsein = pulseio.PulseIn(board.GP16, maxlen=120, idle_state=True)
decoder = adafruit_irremote.NonblockingGenericDecode(pulsein)

next_heartbeat = time.monotonic()
while True:
    for message in decoder.read():
        # If all of these are commented out, then no crash. But if any are uncommented, then the hard fault occurs
        if isinstance(message, adafruit_irremote.IRMessage):
            print("Decoded:", message.code)
        elif isinstance(message, adafruit_irremote.NECRepeatIRMessage):
            print("NEC repeat!")
        elif isinstance(message, adafruit_irremote.UnparseableIRMessage):
            print("Failed to decode", message.reason)
    t = time.monotonic()
    if t > next_heartbeat:
        print("tick")
        next_heartbeat = t + 3

    # time.sleep(0.1) -> fixes (or hides?) issue

At first I suspected a memory leak but the behaviour still happened with gc.mem_free() reporting 150KB+ available.

It seems like some kind of interaction that happens when the decoded messages are printed too often?
Is there a way to be able to get more details from CircuitPython about the cirumstances of the fault, like capture the state of the internal variables of NonblockingGenericDecode and PulseIn or get the specific access fault?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions