help with custom menu

Do you have a question on how to do something.
Ask in here.
Post Reply
ahmedess
Posts: 173
Joined: Sun May 22, 2011 2:29 pm

help with custom menu

Post by ahmedess »

I m using RAgen version 1.1.0.126 and libraries version v0.8.5.19-9. I m trying to create a custom menu as following:

1-Feeding
2-Water Change
3-MultiDosing setup
4-pH Calibration
5-Sal Calibration

I don't know the code I need to put in the void MenuEntry3() and void MenuEntry5() sections of the code which are the sections for multi-dosing setup and salinity calibration respectively.

here is the code I have for the menu:

Code: Select all

prog_char menu0_label[] PROGMEM = "Feeding";
prog_char menu1_label[] PROGMEM = "Water Change";
prog_char menu2_label[] PROGMEM = "Dosing setup";
prog_char menu3_label[] PROGMEM = "pH Calibration";
prog_char menu4_label[] PROGMEM = "Sal Calibration";
PROGMEM const char *menu_items[] = {
menu0_label, menu1_label, menu2_label, menu3_label, menu4_label  };

void MenuEntry1()
{
	ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
	ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
  // multidosing menu???  

}
void MenuEntry4()
{
	ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry5()
{
  // salinity calibration menu???
}
Also if i would like to exit the menu and go back to the main screen do i need to create a menu item called "Exit"?
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: help with custom menu

Post by binder »

Salinity Calibration would be like this:

Code: Select all

void MenuEntry5()
{
  ReefAngel.SetupCalibrateSalinity();
  ReefAngel.DisplayMenu = ALT_SCREEN_MODE;
}
The "Exit" menu is added for you automatically. So you do not need to add it.

What do you mean by "Multidosing menu"? The dosing repeat interval that is on the standard menu?

curt
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: help with custom menu

Post by rimai »

One quick note about the salinity option.
You have to make sure to add this to the top of your PDE:

Code: Select all

#include <ReefAngel_Salinity.h>
And this to your ReefAngel_Features.h file:

Code: Select all

 #define SALINITYEXPANSION
Roberto.
ahmedess
Posts: 173
Joined: Sun May 22, 2011 2:29 pm

Re: help with custom menu

Post by ahmedess »

binder wrote:
The "Exit" menu is added for you automatically. So you do not need to add it.

What do you mean by "Multidosing menu"? The dosing repeat interval that is on the standard menu?

curt
Yes, The dosing repeat interval that is on the standard menu. how do i add that one
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: help with custom menu

Post by binder »

ahmedess wrote: Yes, The dosing repeat interval that is on the standard menu. how do i add that one
This option / ability is not currently available in the libraries when using the simple menu or when creating a custom menu. The reason is that the main function to display the setup options and allow for toggling/changing the values up and down is removed when you create your custom menus. It is removed to reduce code size. The function itself is approximately 170 lines of code (not sure how that impacts the overall size of the code though).

This could be added in manually to your PDE file if you needed it right away. Otherwise, I can test making it available in the simpler menus and see what kind of impact it makes. This may take some time to get accomplished though.

If you want to manually add the missing function to your PDE file, let me know and we can do that for you.

FYI...I just tested adding it manually and it adds approximately 2020 bytes to the overall code size.

curt
ahmedess
Posts: 173
Joined: Sun May 22, 2011 2:29 pm

Re: help with custom menu

Post by ahmedess »

I have enough space for it in my code I'd appreciate it if you send me the code. Also I would like to know how i to remove ATO, Standard lights and MH cause i m not using them and i would like to save some space by removing their code to add some extra other stuff
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: help with custom menu

Post by binder »

If you aren't using them, then don't call the functions. If the functions are not referenced (or called) by your code, then they will be removed automatically for you.

Here's a sample PDE that includes the code I was talking about. This code assumes that you have the proper features enabled to display a custom menu entry.

Code: Select all

//
// This version designed for v0.8.5 Beta 17 and later

#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>


#include <avr/pgmspace.h>
prog_char menu1_label[] PROGMEM = "Feeding";
prog_char menu2_label[] PROGMEM = "Water Change";
prog_char menu3_label[] PROGMEM = "Multi Dose";
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label
};

void MenuEntry1()
{
  ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
  ReefAngel.WaterChangeModeStart();
}

// This entry handles displaying the MultiDose menu entry
// COPY THIS FUNCTION
void MenuEntry3()
{
            int v = InternalMemory.DP1RepeatInterval_read();
            int y = InternalMemory.DP2RepeatInterval_read();
            if ( SetupOption(v, y, 1, 1440, 4, "m", "", "Repeat Interval", "DP1:", "DP2:") )
            {
            	InternalMemory.DP1RepeatInterval_write(v);
            	InternalMemory.DP2RepeatInterval_write(y);
            }
            v = InternalMemory.DP1Timer_read();
            y = InternalMemory.DP2Timer_read();
            if ( SetupOption(v, y, 1, 255, 3, "s", "", "Run Time", "DP1:", "DP2:") )
            {
            	InternalMemory.DP1Timer_write(v);
            	InternalMemory.DP2Timer_write(y);
            }
            ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}


void setup()
{
    ReefAngel.Init();  //Initialize controller
    ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));

    // Ports that are always on
    ReefAngel.Relay.On(Port8);
}

void loop()
{
    ReefAngel.ShowInterface();

    // Specific functions
    ReefAngel.SingleATOLow(Port6);
    ReefAngel.Relay.DelayedOn(Port1, 1);
    ReefAngel.StandardLights(Port2);
    ReefAngel.MHLights(Port3);
    ReefAngel.Wavemaker1(Port4);
    ReefAngel.Wavemaker2(Port5);
    ReefAngel.StandardHeater(Port7);
}


// Setup Menu Screen 
// ADD THIS FUNCTION
bool SetupOption(int &v, int &y, int rangemin, int rangemax, byte maxdigits,
                       char* unit, char* subunit, char* title,
                       char* prefix1, char* prefix2)
{
    // return true to save value stored in out in memory
    enum choices {
        OPT1,
        OPT2,
        OK,
        CANCEL
    };
    byte sel = OPT1;
    bool bSave = false;
    bool bDone = false;
    bool bRedraw = true;
    bool bDrawButtons = true;
    bool bSingle = (y < 0) ? true : false;
    byte offset = 50;
    ReefAngel.ClearScreen(DefaultBGColor);
    ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW, title);
    // prefix for each option
    if ( ! bSingle )
    {
        ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW*4, prefix1);
        ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW*6, prefix2);
    }
    do
    {
#if defined WDT || defined WDT_FORCE
		wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
        if ( bRedraw )
        {
            switch ( sel )
            {
                case OPT1:
                    {
                        if ( ! bSingle )
                            ReefAngel.LCD.DrawOption(y, 0, MENU_START_COL+offset, MENU_START_ROW*6, unit, subunit, maxdigits);
                        ReefAngel.LCD.DrawOption(v, 1, MENU_START_COL+offset, MENU_START_ROW*4, unit, subunit, maxdigits);
                        if ( bDrawButtons )
                        {
                            ReefAngel.LCD.DrawOK(false);
                            ReefAngel.LCD.DrawCancel(false);
                        }
                        break;
                    }
                case OPT2:
                    {
                        ReefAngel.LCD.DrawOption(v, 0, MENU_START_COL+offset, MENU_START_ROW*4, unit, subunit, maxdigits);
                        ReefAngel.LCD.DrawOption(y, 1, MENU_START_COL+offset, MENU_START_ROW*6, unit, subunit, maxdigits);
                        if ( bDrawButtons )
                        {
                            ReefAngel.LCD.DrawOK(false);
                            ReefAngel.LCD.DrawCancel(false);
                        }
                        break;
                    }
                case OK:
                    {
                        if ( bDrawButtons )
                        {
                            ReefAngel.LCD.DrawOption(v, 0, MENU_START_COL+offset, MENU_START_ROW*4, unit, subunit, maxdigits);
                            if ( ! bSingle )
                                ReefAngel.LCD.DrawOption(y, 0, MENU_START_COL+offset, MENU_START_ROW*6, unit, subunit, maxdigits);
                            ReefAngel.LCD.DrawOK(true);
                            ReefAngel.LCD.DrawCancel(false);
                        }
                        break;
                    }
                case CANCEL:
                    {
                        if ( bDrawButtons )
                        {
                            ReefAngel.LCD.DrawOption(v, 0, MENU_START_COL+offset, MENU_START_ROW*4, unit, subunit, maxdigits);
                            if ( ! bSingle )
                                ReefAngel.LCD.DrawOption(y, 0, MENU_START_COL+offset, MENU_START_ROW*6, unit, subunit, maxdigits);
                            ReefAngel.LCD.DrawOK(false);
                            ReefAngel.LCD.DrawCancel(true);
                        }
                        break;
                    }
            }
            bRedraw = false;
            bDrawButtons = false;
        } // if bRedraw
        if ( ReefAngel.Joystick.IsUp() )
        {
            bRedraw = true;
            if ( sel == OPT1 )
            {
                v++;
                if ( v > rangemax )
                {
                    v = rangemin;
                }
            }
            else if ( sel == OPT2 )
            {
                y++;
                if ( y > rangemax )
                {
                    y = rangemin;
                }
            }
        }
        if ( ReefAngel.Joystick.IsDown() )
        {
            bRedraw = true;
            if ( sel == OPT1 )
            {
                v--;
                if ( v < rangemin )
                {
                    v = rangemax;
                }
            }
            else if ( sel == OPT2 )
            {
                y--;
                if ( y < rangemin )
                {
                    y = rangemax;
                }
            }
        }
        if ( ReefAngel.Joystick.IsRight() )
        {
            bRedraw = true;
            bDrawButtons = true;  // only redraw the buttons if we are moving right or left
            // move right, if we are on cancel, wrap around to opt1
            sel++;
            if ( bSingle && sel == OPT2 ) sel++; // advance again if single
            if ( sel > CANCEL )
            {
                sel = OPT1;
            }
        }
        if ( ReefAngel.Joystick.IsLeft() )
        {
            bRedraw = true;
            bDrawButtons = true;
            // move left, if we are on opt1, wrap around to cancel
            sel--;
            if ( bSingle && sel == OPT2 ) sel--;
            if ( sel > CANCEL )
            {
                sel = CANCEL;
            }
        }
        if ( ReefAngel.Joystick.IsButtonPressed() )
        {
            // only break when button pressed on ok or cancel
            if ( sel == OK )
            {
                bDone = true;
                bSave = true;
            }
            else if ( sel == CANCEL )
            {
                bDone = true;
            }
        }
    } while ( ! bDone );

    // return true saves the value, false ignores the value
    return bSave;
}
If you add in the sections that are mentioned above (MenuEntry3() and SetupOption()), you should be good to go. Hopefully that code is a good example for you to follow.

curt
Post Reply