Help needed for beginner - memory alloc and classes

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Help needed for beginner - memory alloc and classes

Post by ikkeT » Mon Apr 19, 2021 5:03 pm

Hi,

I wrote this piece of code that implements small driving computer for moped with originally broken display.

It get's speed from hall sensor, and ignition from capacitive wire from spark plug. Before I refactored from my scratch code into cleaner python class code it worked somewhat. But now after refactoring I don't get it to start even. I get this:

Code: Select all

repl ~ import mopo ~ mopo.show()
Entering REPL. Use Control-X to exit.
>
MicroPython v1.14 on 2021-02-02; ESP module with ESP8266
Type "help()" for more information.
>>> 
>>> import mopo ; mopo.show()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError: 
which isn't very helpful. I probably do tons of mistakes there, writing class code with python for the first time ever. I actually had it going a bit further, but memory error also hit a bit later back then.

Would anyone be kind enough to have a look what kinda mistakes I make there?

This is a learning path for me, and my son. I used to do C programming for years loooong time ago, and have written small python stuff to do simple stuff. But I'm still quite a beginner to python.

Some things that I wonder...
  1. * I tried to do FOO = const(XX), but none of those work, so I removed the const stuff
    * I perhaps should add underscore to the beginning of class internal variables.
    * Interrupts worked before doing classes by using global variables, but I'm not sure now with classes, if the format is right.
    * Why on earth won't it even load?
Code is here: https://github.com/ikke-t/mopo/blob/main/mopo.py

I would really appreciate on some lessons here :)

ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Re: Help needed for beginner - memory alloc and classes

Post by ikkeT » Mon Apr 19, 2021 5:55 pm

The error is somehow related to Display class. If I comment those parts out, and use print() instead, it won't crash.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Help needed for beginner - memory alloc and classes

Post by stijn » Mon Apr 19, 2021 6:01 pm

Have you tried running it without the display part and just printing to the console or a text file? Could very well be the fonts etc just hit the memory limit of your device. Underscores aren't going to change much as far as memory usage go. What you can do to figure out which component uses most memory is sprinkling some print(gc.mem_alloc()) calls in between the main parts of the code to see which bits use most memory, then focus on those. Btw code looks really fine for the rest :)

*edit* oops you figured the above out yourself already in the time I wrote my comment

ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Re: Help needed for beginner - memory alloc and classes

Post by ikkeT » Mon Apr 19, 2021 6:15 pm

probably found the reason by commenting out bit by bit. Is it so that one can't do the import from within the class?

ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Re: Help needed for beginner - memory alloc and classes

Post by ikkeT » Mon Apr 19, 2021 6:16 pm

thanks stijn, same thing I didn't notice your tip as I had not refreshed the screen. Good point about measuring the mem once in a while. I try.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Help needed for beginner - memory alloc and classes

Post by stijn » Mon Apr 19, 2021 6:33 pm

ikkeT wrote:
Mon Apr 19, 2021 6:15 pm
Is it so that one can't do the import from within the class?
No that's not a problem (assuming you mean 'in a function in a class' or so, not sure what importing at class level does but if it's wrong it'll be a syntax error, it won't just silently mess up)

ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Re: Help needed for beginner - memory alloc and classes

Post by ikkeT » Mon Apr 19, 2021 6:41 pm

I got error saying ssd1306 is unknown variable when I had the import at the beginning of class Display(). Once I moved the imports to beginning of the file, the ssd1306 complaint went away. So it didn't work until I removed from import from:

Code: Select all

class Display():
    """Output information on SSd1306 oled display"""

    # font created by:
    # ../micropython-font-to-py/font_to_py.py \
    #   /usr/share/fonts/google-droid/DroidSans.ttf \
    #   -x 20 droidsans20.py -c 0123456789,.kmhrpm/
    import droidsans20
    # font created by:
    # ../micropython-font-to-py/font_to_py.py \
    #   /usr/share/fonts/google-droid/DroidSans.ttf
    #   -x 48 droidsans48.py 0123456789,. 
    import droidsans48
    import ssd1306
Or should such import be in __init__ function of the class?

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Help needed for beginner - memory alloc and classes

Post by stijn » Mon Apr 19, 2021 7:08 pm

ikkeT wrote:
Mon Apr 19, 2021 6:41 pm
Or should such import be in __init__ function of the class?
Yes, or in any other function. I honestly don't know what the effect is of putting it at class level, just that it doesn't import the names into an available scope..

ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Re: Help needed for beginner - memory alloc and classes

Post by ikkeT » Sun Apr 25, 2021 5:17 pm

Thanks, moving imports into Display.__init__() seems to be the right place. I also added the memory debugs. Seems that there is roughly 37kB of memory on the the device, adding together the gc.mem_alloc and gc.mem_free.

It loads now if I don't load in the the second font. As soon if I import either of these:

Code: Select all

        # import droidsans48
        # import droidsans32
It fails to start due out of mem. The sizes of the fonts are:

Code: Select all

4,6K  droidsans20.py
6,0K droidsans32.py
11K  droidsans48.py
19K  droidsans64.py
While I'm in main loop, the used memory is somewhere between 16k - 22 k. So amount of free mem is correspondingly about the same. So why does it overflow of memory importing few kilos of font? Is there some other problem in the class Display()? Do I do something wrong that causes the fonts to kill the mem?

I now commented out loading of the font_big, which is used in Display.speed(). Is loading the Writer class twice a bad way, should I somehow just switch the font within the class, or somehow unload the other instance of Writer before loading the font at each time drawing the screen?

This is how the mem is allocated at start:

Code: Select all

>>> import mopo ; mopo.show()
mem1:  11360
mem2:  11696
Orientation: horiz Reversal: False
mem3:  16512
mem4:  16832
mem5:  17040
mem  1 :  17088  free:  20864
button presses:  0
rpm:  0  kmh:  0
mem  2 :  20080  free:  17872
button presses:  0
rpm:  0  kmh:  0

ikkeT
Posts: 17
Joined: Sat Mar 06, 2021 7:01 pm

Re: Help needed for beginner - memory alloc and classes

Post by ikkeT » Sun Apr 25, 2021 7:15 pm

Whoa, I cross compiled mpy-cross, and converted fonts and mopo.py into mpy, and now it starts with bigger font too!

Progress, still wondering if I do something wrong adding the two instances of Writer with different fonts at here:

https://github.com/ikke-t/mopo/blob/510 ... po.py#L209

This it what the loop loos now while using two fonts:

Code: Select all

button presses:  -1
mem  40 :  24096  free:  13856
button presses:  1
button presses:  1
rpm:  0  kmh:  0
mem  41 :  21568  free:  16384
button presses:  0

Post Reply