Skip to content
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

Reduction of memory usage? #35

Closed
LuckyLuzz opened this issue Jul 24, 2016 · 14 comments
Closed

Reduction of memory usage? #35

LuckyLuzz opened this issue Jul 24, 2016 · 14 comments

Comments

@LuckyLuzz
Copy link
Contributor

Hey,
I got my Menu quiet finished and now it takes up to 30% of program storage space and about 50% of dynamic memory on an UNO. Is it possible to reduce the footprint?

//*-------------------------------------------------------------------------------------------------------------------------------------
// MENU DEFINITION
//*-------------------------------------------------------------------------------------------------------------------------------------

  TOGGLE(Firti_ManualON,Ferti_TOG,"PumpMan     ",
  VALUE("On",HIGH),
  VALUE("Off",LOW)
);
MENU(subMenuTimer, "Fertilization",
     SUBMENU(Ferti_TOG),
     FIELD(FertiPumpSpeed ,       "PumpSpeed  ", "%", 0, 60, 1, 0),
     FIELD(Ferti_StartTime,       "StartTime  ", "h", 0, 24, 1, 0),
     FIELD(Ferti_DurationTime ,   "Duration   ", "s", 0, 60, 1, 0)
    );

MENU(subDateTime, "Date/Time",
     FIELD(hour1 ,   "Hour    ", " ", 0, 24, 1, 0),
     FIELD(minute1 , "Minute  ", " ", 0, 60, 1, 0),
     OP("SaveClockMemory", setTimeRTC)
    );

MENU(subMenuTemperature,  "Temp/Light/PID",
     FIELD(TempSetpoint,   "SetPoint", "C", 15, 30, 1, 0),
     FIELD(TempAlarm,      "Alarm   ", "C", 15, 30, 1, 0),
     FIELD(PID_AutoManOff, "PID Mode   ", "", 0, 3, 1, 0),
     FIELD(Xd,             "PID Xd     ", "", 0, 10, 1, 0),
     FIELD(Xi,             "PID Xi     ", "", 0, 10, 1, 0),
     FIELD(Xs,             "PID Xs     ", "", 0, 10, 1, 0),
     FIELD(PID_MAN,        "PID MAN-Y  ", "%", 0, 100, 1, 0),
     FIELD(LightMaxY,      "PID MaX-Y  ", "%", 50, 100, 1, 0),
     FIELD(LightMinY,      "PID MiN-Y  ", "%", 0, 50, 0, 0),
     FIELD(LightOn ,       "Light On   ", "h", 0, 24, 1, 0),
     FIELD(LightOff ,      "Light Off  ", "h", 0, 24, 1, 0)
    );

MENU(mainMenu, "Aquarium",
     SUBMENU(subMenuTemperature),
     SUBMENU(subMenuTimer),
     SUBMENU(subDateTime),
     OP("Exit", pauseMenu)
    );


@neu-rah
Copy link
Owner

neu-rah commented Jul 24, 2016

probably yes #6

@LuckyLuzz
Copy link
Contributor Author

yeah I have read that and I have read a couple tutorials to use PROGMEN but I am not able to get this infos into my sketch. Could you give an example?

@neu-rah
Copy link
Owner

neu-rah commented Jul 24, 2016

not yet, it was just an idea

@neu-rah
Copy link
Owner

neu-rah commented Jul 24, 2016

I've send updates for some navigation bugs, support for looping menus, and U8glib support, guess i will read something about progmem

@LuckyLuzz
Copy link
Contributor Author

I guess a good start would be to use the F ( ) Macro like in lcd.print(F("Hallo")); or here https://www.arduino.cc/en/Reference/PROGMEM :) just as an idea.

I am pretty much a hobby programmer so I am dependent on your grace ^^

@LuckyLuzz
Copy link
Contributor Author

LuckyLuzz commented Jul 24, 2016

ok I guess it will be nessasary to work with string as all the other Menu's out the, as I startet my project I had no idea why they using them, but now it's clear, it saves memory. Insteard of putting the "Text" in a Field there should be a

const char mainMenuSTRING_ID_0 [] PROGMEM = "Aquarium"
const char mainMenuSTRING_ID_4[] PROGMEM = "Exit Menu"

MENU(mainMenu, mainMenuSTRING_ID_0,
SUBMENU(subMenuTemperature),
SUBMENU(subMenuTimer),
SUBMENU(subDateTime),
OP(mainMenuSTRING_ID_4, pauseMenu)
);

And then the libary need the read the PROGMEN with pgm_read_word_near(mainMenuSTRING_ID_0);

And there my knowlege stop's, cause I don't fully understand the MACROS of the lib...

@christophepersoz
Copy link
Collaborator

I pointed out this example and discussion on Arduino forum, http://forum.arduino.cc/index.php?topic=110307.0, maybe this can help you to implement PROGMEM text var.
I tried on my side but I'm stuck and got a lot of errors, mostly in the MACRO part definition, because I do not understand all the syntax you are using to generate the menu.

@neu-rah
Copy link
Owner

neu-rah commented Jul 25, 2016

I've done some checkings, by moving strings and menus data (list of options) to PROGMEM and it is not a big saving.. still checking

pratical compile measures ---------------------------
nomenu 622
normal menu 1119 - 497
progmem menu 1067 - 445 (text and data lists to progmem)
saved 52

structures sizeof ----------------------------------
promptAction: 2
prompt: 7
menu: 22
menuValue: 9
menuField: 33
menuSelect: 24
menuChoice: 24
menuToggle: 24

rough estimates =====================================

menu struct:
lists 4
prompts 2+2+7+6+4=21

strings ------------------------------------------
texts: 2+2+7+3+4=18
chars: 10+9+24+24=67
total chars: 67+18=85 (zero terminated)

test menu struct size ----------------------------
values: 9x9=81
ops: 4x7=28
fields: 1x33
menu: 4x22=88
total: 81+28+33+88=230

even moving text and data to flash, the remainder of menu structure is bigger than the moved part
as we normally use short texts due to small screen usage, I think we can save only less than 20% of menu ram space.. not very good

to make bigger savings all menu structure would have to be revised by separating things that can be constant and status variables, in some cases with worst results. A simple prompt can be all in progmem except for the enabled status var, spliting the class between memory types will result in more memory usage.
some status variables can be moved out of the structure by making a navigation stack...

things for version 3 i guess

@christophepersoz
Copy link
Collaborator

Each time I had used F() macro on String I never noticed big savings on memory usage.
Maybe it worth it on large menu, otherwise I'm not really sure.
You (I mean not you directly, but much more people) can also think to save memory by using the smallest data type capable of holding the information. i.e. uint8_t instead of int (1 byte saved each time), etc.

@LuckyLuzz
Copy link
Contributor Author

LuckyLuzz commented Jul 25, 2016

I my project I have a lot blank space character to format the print. I guess other users do that too, so I thought, and I am actullay not sure if blank space character getting saved in strings, it could be good to implement a Format class so that just the nessasary characters will be saved.
Meanwhile I orderd a Mega ;)

@neu-rah
Copy link
Owner

neu-rah commented Jul 26, 2016

yes, datatypes are important and in some cases we can exchange data by code...
example, the prompt class can be all const (progmem) except for the "enabled" bool...
I can sacrifice an extra byte on flash mem (progmem) and use a pointer to a function that returns the enabled state. that way the function pointer is const (can go to flash mem) , we loose a bit of performance because we have to execute the code for every check, but all the prompt data will exist as one object in flash.
have to check other classes about separation between const (compile time->progmem) and dynamic data. And avoid splitting the object as much as possible.

@neu-rah
Copy link
Owner

neu-rah commented Jul 26, 2016

and yes, blank space is stored, you can use tabs, but your driver must understand tabs
and all strings terminate with a zero byte (c convention).
but string are probably less than 30% of the data

@neu-rah
Copy link
Owner

neu-rah commented Jul 26, 2016

here's a small code that uses no macros if you want to play with PROGMEM

bool ledOn() {return false;}//returning true here makes the menu exit after
bool ledOff() {return false;}

prompt sub1("LED ON",ledOn);
prompt sub2("LED OFF",ledOff);
prompt* const subMenuData[]={&sub1,&sub2};
menu subMenu("Sub-menu",2,subMenuData);

prompt empty("Empty");

prompt* mainMenuData[]={&subMenu,&empty};
menu mainMenu("Main menu",2,mainMenuData);

@neu-rah
Copy link
Owner

neu-rah commented Jul 28, 2016

Just sent update with text strings and menu data stored in PROGMEM
next i might target preferences...

@neu-rah neu-rah mentioned this issue Jul 28, 2016
@neu-rah neu-rah closed this as completed Jul 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants