0

memory allocation failed for neopixel
Moderators: adafruit_support_bill, adafruit

Forum rules
Adafruit MicroPython is currently EXPERIMENTAL and BETA - Please visit https://learn.adafruit.com/category/micropython and http://forum.micropython.org/ in addition to our section here!
Please be positive and constructive with your questions and comments.

memory allocation failed for neopixel

by Mummel on Wed Oct 11, 2017 4:55 pm

Hi,

I am running the file:

https://github.com/Meresmata/NeoText/bl ... X_short.PY

on a Trinket M0 with CurcuitPython 2.0.0. For 4 Neopixels matrixes chained together, to have the maximum 256 leds per pin.

When I can the run function I get following error message:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "MAINX_short.py", line 138, in run
File "libraries/drivers/neopixel/neopixel.py", line 200, in show
File "libraries/drivers/neopixel/neopixel.py", line 200, in <listcomp>
MemoryError: memory allocation failed, allocating 4096 bytes


When the function is called afterwards, all works normal. Does anyone know where this error is comming from and why. What can be done against it?

Mummel
 
Posts: 14
Joined: Sun Aug 23, 2015 9:12 am

Re: memory allocation failed for neopixel

by tannewt2 on Wed Oct 11, 2017 9:27 pm

You are using a ton of neopixels!

Its complaining about running out of memory when calling show because it has to copy all of the data to factor in brightness. Try only using brightness 1.0 and adjusting your color values instead. That should use less memory.

tannewt2
 
Posts: 382
Joined: Thu Oct 06, 2016 8:48 pm

Re: memory allocation failed for neopixel

by Mummel on Thu Oct 12, 2017 3:12 pm

Ok! It was strange, to get the error message only for the first call and then seeing it work properly.
I think, it is also due to large library that is imported. In the last try, I had 20 letters, accepted. But there are some more printable ascii symbols... How can this problem be overcome. I would try, to change the tuple of an tuple into an byte array of an byte array, or tuple of bytes? ( Can this work?)... Which should be preferred? How much space can I save per integer? How do I meassure the size of the used data type and and the used ram of that library? sys.getsizeof... does not work?
Hallo and thanks from Germany!

Mummel
 
Posts: 14
Joined: Sun Aug 23, 2015 9:12 am

Re: memory allocation failed for neopixel

by tannewt2 on Thu Oct 12, 2017 4:21 pm

I'm not sure what you mean by tuples and bytes.

I'm not exactly sure on the byte counts of objects. I added a `uheap` module a while back that can be enabled with a custom compile. I'm not sure how accurate it is.

I also added a heap trace mechanic using a J-Link that is documented here: https://github.com/adafruit/circuitpyth ... ctivity.md

I hope that helps. Hello back from Seattle!

tannewt2
 
Posts: 382
Joined: Thu Oct 06, 2016 8:48 pm

Re: memory allocation failed for neopixel

by Mummel on Fri Oct 13, 2017 1:22 pm

Hi,

I currently tried to import heap or uheap. In the support matrix the entrance for for uheap is... DEBUG... But I could not find out what that means.

Concerning my last message: The overall question was, how to lower ram usage be achieved... For example to reduce the footprint of my tupels...

is it better to unpack my tupels from ((1, 2), (3, 4)) to (1,2,3,4), or to use bytearray or array as inner or or what can I do. Are all typels of my function in the ram,, or only that in the which in that if/elif that is evaluated to true...

if X = 1
X = ((1,2), (3, 4), (4, 5))
elif X = 2
X = ((1,2), (3, 4), (4, 5))
.
.
.
Are all the tupels in the ram, or only one? How can this be changed?

Are all removed from ram, after

run(){
for pixel in pixels:
functionwithmanytupels()
neopixels.show()
}
functionwithmanytupels() returns to the scope of the for loop, after the for loop has ended. If it is not so/not shure can I change this with a call of the garbace collector?

Mummel
 
Posts: 14
Joined: Sun Aug 23, 2015 9:12 am

Re: memory allocation failed for neopixel

by danhalbert on Fri Oct 13, 2017 2:06 pm

Did you set brightness to 1.0 as Scott suggested (or just omit the argument: 1.0 is the default). That will halve the memory needed for the pixels.

All the data objects are in RAM, not flash. I'm not sure you're using all that much memory for the tuples. You could use bytearrays, which might or might not save you space. You'll need to do some experimentation.

To find out the current heap use:
Code: Select all | TOGGLE FULL SIZE
import micropython, gc
gc.collect()             # clean up any garbage
micropython.mem_info()   # prints heap info

Insert this wherever you want to see the current heap usage.

Since you reassign tuple each time through the big if statement, the old tuples become garbage and can be collected. You can insert `gc.collect()` statements at judicious points, but it's supposed to be automatic.

danhalbert
 
Posts: 103
Joined: Tue Aug 08, 2017 12:37 pm

Re: memory allocation failed for neopixel

by Mummel on Sat Oct 14, 2017 10:49 am

Thank,

very much for your answer.

I tried to call

micropython.mem_info()

Then I got the error:

AttributeError: 'module' object has no attribute 'mem_info'

Have a nice weekend.
Problem help(micropython) returns:

object <module 'micropython'> is of type module
__name__ -- micropython
const -- <function>
opt_level -- <function>
heap_lock -- <function>
heap_unlock -- <function>
kbd_intr -- <function>

This is why unforutately.

Following your reply and:
http://circuitpython.readthedocs.io/en/ ... t=mem_info

it should be included...

Mummel
 
Posts: 14
Joined: Sun Aug 23, 2015 9:12 am

Re: memory allocation failed for neopixel

by danhalbert on Sat Oct 14, 2017 11:24 am

Sorry, I forgot: we took it out of the Trinket M0, Gemma M0, and Feather M0 Basic/Adalogger versions of CircuitPython to save space. We may be able to put it back in the next release. In any case, you can try not specifying brightness and see if you get memory errors.

danhalbert
 
Posts: 103
Joined: Tue Aug 08, 2017 12:37 pm

Re: memory allocation failed for neopixel

by Mummel on Wed Oct 18, 2017 4:48 pm

Short report:

leaving out the brightness and using the garbage collect, was not enough. Because I have many tupels of the sort ((1, 2), ...(2, 3))
I had to rewrite them to array.array("B", (1, 2, ..., 2, 3)). Which makes the file runnable again... Due to the changes I some bugs... (Wrong number of LEDs, with wrong addresses).

I searched for a way to create frozen modules. But only found one for the esp. You probably have to change the virtual machine, but how?

Thank you.

Mummel
 
Posts: 14
Joined: Sun Aug 23, 2015 9:12 am

Re: memory allocation failed for neopixel

by danhalbert on Wed Oct 18, 2017 5:09 pm

`bytearray(1, 2, 2, 3, 3, 4, ...)` will also work.

You can compile the .py file to a .mpy file, but currently we don't supply `mpy-cross`, the compiler, pre-built. We don't have a version that runs on Windows (yet). You could build `mpy-cross` yourself but it takes some effort. Importing a `.mpy` file will still use up as much RAM after importing as a `.py` file will. But it saves the compilation step, which may need more RAM than is available.

It is also possible to make an "internal frozen module" which is part of the CircuitPython firmware. That does not use up RAM when imported. I'd like to write up how to do this at some point. It is similar to what is described in the ESP8266 guide you looked at. https://github.com/adafruit/circuitpyth ... igboard.mk shows how some modules are internally frozen into the Circuit Playground Express firmware. But you need to be comfortable doing makefile builds on Linux or MacOS to do this.

danhalbert
 
Posts: 103
Joined: Tue Aug 08, 2017 12:37 pm

Please be positive and constructive with your questions and comments.