adafruit / adafruit/Adafruit_CircuitPython_IRRemote
Hard fault in non blocking example (caused by print statements?)
- Dominant language
- Python
- Stars
- 29
- Forks
- 31
- PR merge metrics
- No merged PRs in 30d
Description
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.
```python
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?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with examples/irremote_nonblocking.py and trace the interaction between pulseio.PulseIn and NonblockingGenericDecode on the stated Pico and CircuitPython versions. Reproduce rapid button presses while varying print statements, loop delay, and maxlen; done means identifying the fault's cause and establishing a targeted fix or a clearly documented limitation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100