-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Moving Menu Names and Items into PROGMEM #32
Comments
I'm glad you find the library useful. As you've said, to store the MenuItem strings in Flash memory instead of SRAM you need to use
I've never done this so that code above is not tested. Realise that there's more than one way to run out of memory. You more or less have three things competing:
If you make lots of nested/recursive function calls, a stack frame is added each time, increasing the stack size; nothing is freed until a function exits. Static data are things like the MenuSystem instances. They are when the program starts and not freed until it ends, so that space is in most cases not recoverable. Lastly you have the heap. This is where dynamically allocation data goes (e.g. created with malloc). Memory here can be freed once it's no-longer required. Since I can only count 300 bytes of strings, assuming I can count, that leaves 1748 bytes on an UNO, which is still quite a bit of SRAM. Of course, that doesn't include all the Menu objects and anything else you have. It's also possible that some other library is hogging your SRAM. The following function (taken from adafruit) can be called at points in your code to see how much RAM is available. This might help with debugging. You can also look into
It'll probably (sadly) a case of looking closely at how much RAM is being used by various parts of your code until you find the bit that's the problem. It might be that all the code is fine and that you just have a lot of it, in which case, you need more RAM - a Mega2560 has 8k which is four times as much as the Uno. :) Good luck. Get in touch if you need more help. |
Thanks for the extensive explanation and the time you spent to write it. I have some basic understanding of what's going on under the hood, but only just enough to be dangerous. As I had mentioned, I tried every implementation of PROGMEM that was applicable from here: http://www.github.com/abcminiuser/avr-tutorials/blob/master/Progmem/Output/Progmem.pdf?raw=true without any luck. I just tried your suggestion with the same results. A single, gibberish character is displayed at 0,0 on the LCD. This is on a 328 part, so the 2048 limitation is correct. I'm currently at 1,489 and still have a number of menus to add. I will go through my code and clean up any problem areas that I can find, but right now the addition of more menus is eating up space fastest. I can already see a few areas that can free up some space, but I'm not sure it will be enough if I can't get the menu text into flash. The sad thing is, I originally had planned to use the 2560, but was talked out of it. Thanks again, John |
So, I think I've found the solution but I'm not sure how to implement it. I was having a similar problem after declaring a constant array of constant character arrays with PROGMEM. Like this:
If I tried to print by directly referencing the table of arrays, it wouldn't work, like this:
But, after finding and using this approach, everything worked fine:
So the question would be, how to do that in this function:
|
That page has the following to say about
This means that it copied from FLASH to SRAM. Because the MenuItem components are built at the start and are always in memory, The only way It's an interesting problem you have and I wish I could give you a solution other than "you need more RAM" and "optimize your code". In any case, I'm going to leave this issue open to remind myself to look at the library's memory usage - perhaps it can be improved. |
One way to deal with this problem is to keep an alternative name pointer inside each MenuComponent.
An alternative to dual pointers is to use an union:
But then a bool has to be stored alongside the union to differentiate between the two. |
Being capable of storing 'flash memory' strings side by side with 'dynamic memory' inside MenuComponents will also require the signature or getName() to change. It will need to return the data via a 'dynamic memory' buffer or a stack allocated String (the class). |
Okay, I may have figured it out.... const char string_example[] PROGMEM = {"Example"}; instead of I have I created this function to print to the LCD screen:
And then modified the MyRenderer class to simply be this:
So far it seems to print to the LCD perfectly well but I'm unsure if it's just reading the strings from PROGMEM initially and then storing them in RAM afterwards. |
I'm running up against a dynamic memory limit with an involved menu tree. I've tried all of the PROGMEM ideas presented by Dean Camera (fourwalledcubicle) and I haven't been successful. Is there any way to achieve that?
Here is the beginning of my menu system:
Thanks for developing and sharing your code. It's been an INCREDIBLE help with my latest project.
John
The text was updated successfully, but these errors were encountered: