adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.1k stars 1.22k forks source link

pIRkey Memory Allocation Error #1211

Closed limited660 closed 6 years ago

limited660 commented 6 years ago

I'm having issues with (2) pIRkey's throwing the following error:

Traceback (most recent call last): File "main.py", line 57, in <module> File "adafruit_irremote.py", line 217, in read_pulses MemoryError: memory allocation failed, allocating 512 bytes

This occurs with the example provided on the pIRkey called "NEC Keyboard Example". One device is running 2.2.3 and I can trigger the error on unmodified code simply by pushing a button on an IR remote in quick succession, adding a time.sleep(.1) to the end does not prevent this from happening. The other device is running 3.0.2 with upgraded libraries (only replaced those that were already on the device) and it shows the same symptoms as 2.2.3 on unmodified code. When the 3.0.2 device has time.sleep(.1) at the end I get the error immediately after pushing a button.

The code below is the "NEC Keyboard Example" that is included but with modifications that allow it to run without the memory error. It will not run without error until you comment out import adafruit_dotstar, I tried one by one with all the lines further in the code and it errors until the previously mentioned one is removed.

# Simple NEC remote decode-and-type keyboard example
# When used with the Adafruit NEC remote will act like a keyboard and
# type out keypresses.

import adafruit_irremote
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
#import adafruit_dotstar
import pulseio
import board
import time

#led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)

# The keyboard object!
time.sleep(1)  # Sleep for a bit to avoid a race condition on some systems
keyboard = Keyboard()
keyboard_layout = KeyboardLayoutUS(keyboard)  # Were in the US :)

# our infrared pulse decoder helpers
pulsein = pulseio.PulseIn(board.REMOTEIN, maxlen=120, idle_state=True)
decoder = adafruit_irremote.GenericDecode()
# size must match what you are decoding! for NEC use 4
received_code = bytearray(4)

# Make a list of lists with the IR code expected and our keypress outs
infrared_to_key = (
    ([255, 2, 191, 64], (Keycode.LEFT_CONTROL, Keycode.UP_ARROW)),  # Vol+
    ([255, 2, 255, 0],  (Keycode.LEFT_CONTROL, Keycode.DOWN_ARROW)), # Vol-
    ([255, 2, 127, 128],(Keycode.SPACE,)),
    ([255, 2, 111, 144],(Keycode.ENTER,)),        # Enter / Save
    ([255, 2, 143, 112],(Keycode.DELETE,)),       # Backwards arrow
    ([255, 2, 159, 96], (Keycode.ESCAPE,)),       # Setup
    ([255, 2, 79, 176], (Keycode.DOWN_ARROW,)),
    ([255, 2, 239, 16], (Keycode.LEFT_ARROW,)),
    ([255, 2, 95, 160], (Keycode.UP_ARROW,)),
    ([255, 2, 175, 80], (Keycode.RIGHT_ARROW,)),
    ([255, 2, 207, 48], (Keycode.ZERO,)),
    ([255, 2, 247, 8],  (Keycode.ONE,)),
    ([255, 2, 119, 136],(Keycode.TWO,)),
    ([255, 2, 183, 72], (Keycode.THREE,)),
    ([255, 2, 215, 40], (Keycode.FOUR,)),
    ([255, 2, 87, 168], (Keycode.FIVE,)),
    ([255, 2, 151, 104],(Keycode.SIX,)),
    ([255, 2, 231, 24], (Keycode.SEVEN,)),
    ([255, 2, 103, 152],(Keycode.EIGHT,)),
    ([255, 2, 167, 88], (Keycode.NINE,)),

)

print("Ready for NEC remote input!")

while True:
    #led[0] = (0, 0, 0)   # LED off
    pulses = decoder.read_pulses(pulsein)
    #print("\tHeard", len(pulses), "Pulses:", pulses)
    try:
        code = decoder.decode_bits(pulses, debug=False)
        print("Decoded:", code)
        # Reads 4-byte code transmitted by NEC remotes and
        # sends a matching key command
        for pairs in infrared_to_key:
            if pairs[0] == code:
                #led[0] = (0, 100, 0)                   # flash green
                print("Matched IR code to keypresses: ", pairs[1])
                keyboard.press(*pairs[1])
                keyboard.release_all()
    except adafruit_irremote.IRNECRepeatException:     # unusual short code!
        print("NEC repeat!")
    except adafruit_irremote.IRDecodeException as e:   # failed to decode
        #led[0] = (100, 0, 0)                           # flash red
        print("Failed to decode: ", e.args)
    print("----------------------------")
    time.sleep(.1) # this line was added by me
jerryneedell commented 6 years ago

the necessary libraries are in the "frozen" into the build. Try removing everything in the CIRCUITPY/lib. a tleast remove adadruit_hid/ , adafruit_dotstar.mpy and adafruit_IRremore.mpy. I just tried this under the 4.0 alpha and it works.

jerryneedell commented 6 years ago

Also verified it works on CP 3.0.2 when lib/ is empty

jerryneedell commented 6 years ago

This may be related to https://github.com/adafruit/Adafruit_CircuitPython_Bundle/issues/93

limited660 commented 6 years ago

Verified on my pIRkey, removing the "lib" folder and contents removes issue.

limited660 commented 6 years ago

To see what is included or "frozen", at the REPL type help(‘modules’) that will show the built in modules. - @jerryneedell

ladyada commented 6 years ago

OK great - we're working on a solution to this common issue :)

KaleidoscopeSci commented 5 years ago

I know I'm kinda necroposting here, but I'm trying to use the CPX IR, getting the same error. Tried deleting files in /lib. When I REPL the modules though, adafruit_IRremote isn't showing up as frozen. So no IR functions work. What can I do?

dhalbert commented 5 years ago

@KaleidoscopeSci adafruit_irremote is only frozen on the PirKey (which isn't for sale at the moment), so on the CPX you need your lib directory back (or at least that library). Also, as of CircuitPython 3.1.1, frozen modules will be imported first, so you don't need to delete the lib directory to save RAM anymore for frozen modules.

KaleidoscopeSci commented 5 years ago

Sadly with the lib directory installed on CPX, I'm still getting the memory allocation error. Anything else I can try? I've tried changing maxlenth, setting different time. sleep amounts, still keep getting the same error. This is the only documentation I've been able to find that describes anything similar to what I'm experiencing.

dhalbert commented 5 years ago

OK, then, there's nothing really to be done, unfortunately. This issue is partly why the pirKey is not available right now - we haven't figured out an easy fix. Making the library frozen saves RAM, but there are still issues.