Pass parameter from array to function

I am building a programmable hot water thermostat.
The menu for my LCD is an array, i’d like to be able to send variables from the menu to a function for setting time values (clock, on times and off times, that sort of thing)

This way i can have one function for hours and one for minutes rather than having an individual function for every hour and every minute of the day.

Here is the menu itself, the whole sketch won’t fit here and i thought this would be the important bit, currently the numbered menu items below refer to hours and minutes and each one runs a function that sets either the clock, an on time or an off time (using if statements). It’d be more streamlined if just 2 functions existed (one for minute and one for hours) that accepting a value from a menu item and set that as the hour or minute.

#include <TimeAlarms.h>
#include <Time.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <nokia_3310_lcd.h>



// Temp/humidity display using nokia 3310 LCD display shield from nuelectronics.com

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

//keypad debounce parameter
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON  10
#define DEBOUNCE_OFF 3 

#define NUM_KEYS 5

#define NUM_MENUS      20
#define NUM_MENU_ITEM      6

// joystick number
#define UP_KEY 3
#define LEFT_KEY 0
#define CENTER_KEY 1
#define DOWN_KEY 2
#define RIGHT_KEY 4

// Pin used by Backlight, so we can turn it on and off. Pin setup in LCD init function
#define BL_PIN 7

// menu starting points
#define MENU_X      0            // 0-83
#define MENU_Y      0            // 0-5

int test;
// adc preset value, represent top value,incl. noise & margin,that the adc reads, when a key is pressed
// set noise & margin = 30 (0.15V@5V)
int  adc_key_val[5] ={
  30, 150, 360, 535, 760 };

// debounce counters
byte button_count[NUM_KEYS];
// button status - pressed/released
byte button_status[NUM_KEYS];
// button on flags for user program 
byte button_flag[NUM_KEYS];

// menu definition
static const prog_char menu_items[NUM_MENUS][NUM_MENU_ITEM][16] PROGMEM = {
  {  
    "Temperature",
    "Water Request",
    "Program",
    "Set Clock",
    "Display Time"    }
  ,
  {  
    "1",
    "1.5",
    "2",
    "2.5",
    "Bath",
    "None"     }
  ,
  { 
    "Toggle Program",
    "Set On",
    "Set Off",
    "Water Request",
    "View Program",
    "Main Menu"    }
  ,
  { 
    "Set Hour",
    "Set Minute",
    "Main Menu"    }
  ,
  { 
    "Hours 0-5",
    "Hours 6-11",
    "Hours 12-17",
    "Hours 18-23"    }
  ,
  { 
    "Minutes 0-5",
    "Minutes 5-11",
    "Minutes 12-17",
    "Minutes 18-23",
    "Minutes 24-29",
    "Minutes 30-35"    }
  ,
  { 
    "0",
    "1",
    "2",
    "3",
    "4",
    "5"    }
  ,
  { 
    "6",
    "7",
    "8",
    "9",
    "10",
    "11"    }
  ,
  { 
    "12",
    "13",
    "14",
    "15",
    "16",
    "17"    }
  ,
  { 
    "18",
    "19",
    "20",
    "21",
    "22",
    "23"    }
  ,
  { 
    "0",
    "1",
    "2",
    "3",
    "4",
    "5"    }
  ,
  { 
    "6",
    "7",
    "8",
    "9",
    "10",
    "11"    }
  ,
  { 
    "12",
    "13",
    "14",
    "15",
    "16",
    "17"    }
  ,
  { 
    "18",
    "19",
    "20",
    "21",
    "22",
    "23"    }
  ,
  { 
    "24",
    "25",
    "26",
    "27",
    "28",
    "29"    }
  ,
  { 
    "30",
    "31",
    "32",
    "33",
    "34",
    "35"    }
  ,
  { 
    "36",
    "37",
    "38",
    "39",
    "40",
    "41"    }
  ,
  { 
    "42",
    "43",
    "44",
    "45",
    "46",
    "47"    }
     ,
  { 
    "48",
    "49",
    "50",
    "51",
    "52",
    "53"    }
  ,
  { 
    "54",
    "55",
    "56",
    "57",
    "58",
    "59"    }

};
void (*menu_funcs[NUM_MENUS][NUM_MENU_ITEM])(void) = {
  { 
    temperature,
    waterreq,
    setProg,
    setClock,
    displayTime     }
  ,
  { 
    shower1,
    shower15,
    shower2,
    shower25,
    bath,
    none     }
  ,
  { 
    toggleProg,
    setOn,
    setOff,
    waterreq,
    viewProg,
    mainmenu    }
  ,
  { 
    setHour,
    setMin,
    mainmenu    }
  ,
  { 
    hour0to5,
    hour6to11,
    hour12to17,
    hour18to23   }
  ,
  { 
    minute0to5,
    minute6to11,
    minute12to17,
    minute18to23,
    minute24to29,
    minute30to35    }
  ,
  { 
    hour0,
    hour1,
    hour2,
    hour3,
    hour4,
    hour5    }
  ,
  { 
    hour6,
    hour7,
    hour8,
    hour9,
    hour10,
    hour11    }
  ,
  { 
    hour12,
    hour13,
    hour14,
    hour15,
    hour16,
    hour17    }
  ,
  { 
    hour18,
    hour19,
    hour20,
    hour21,
    hour22,
    hour23    }

};

Any ideas?
Thanks

It'd be more streamlined if just 2 functions existed (one for minute and one for hours) that accepting a value from a menu item and set that as the hour or minute.

So, what is the problem? Why can't you do this?

Any ideas?

Not without understanding the problem.

Show the function you would like to call, and what you want to pass to it.

A value in an array is no different from a value in a scalar variable, in a pass-by-value function call.

if i change the menu from hour0 to hour(0) i get this error:

error: void value not ignored as it ought to be

This is the function i'd like to call, i've temporarily user the name 'test' for the parameter:

void hour(int test)
{
  int  hour_temp = test;

  if (previous_menu_num == 0 ) 
  {
    clockHour = hour_temp;
    SetTime();
  }
  else if ((previous_menu_num == 2) && (settingProgTime == 2))
  {
    onHour = hour_temp;
  }
  else if ((previous_menu_num == 2) && (settingProgTime == 1))
  {
    offHour = hour_temp;
  }
  settingProgTime = 0;

  current_menu_num = 0;
  current_menu_item = 0;

}

This is what i currently have (which would need 24 for hours and 60 for minutes, bloated code or what!)

void hour0()
{
  int  hour_temp = 0;

  if (previous_menu_num == 0 ) 
  {
    clockHour = hour_temp;
    SetTime();
  }
  else if ((previous_menu_num == 2) && (settingProgTime == 2))
  {
    onHour = hour_temp;
  }
  else if ((previous_menu_num == 2) && (settingProgTime == 1))
  {
    offHour = hour_temp;
  }
  settingProgTime = 0;

  current_menu_num = 0;
  current_menu_item = 0;

}

You have a fundamental flaw in your program, I'm afraid.

You have a 2 dimensional array of pointers to functions that take no arguments, menu_funcs. One of those functions that you have stored a pointer to is hour0.

Given the array that you have, the best you could do is have hour0() call hour(0), and have hour1() call hour(1), etc.

void hour0()
{
   hour(0);
}

void hour(int h)
{
   // Do something with h
}

Alternatively, you could change the type of menu_funcs, to be an array of pointers to functions that take one integer argument. Some of the functions pointed to would do nothing with the dummy value passed to them. Some would do something useful with it.

Figuring out what to pass the function is not trivial.

As a third choice, you could replace hour0, hour1, etc. with hour, and have a global variable that contains the value to be operated on.

Oh ok.

Your first solution seems reasonable, still saves a lot of unnecessary code.

I'm not sure i understand the third solution, each menu item needs to refer to a single hour of the day, how would this be determined without it being passed from the array pointer? i.e. there are 24 different values that potentially need to be accepted by an hour function and assigned to the clock/timer variables.

Thanks for your help

I'm not sure i understand the third solution, each menu item needs to refer to a single hour of the day, how would this be determined without it being passed from the array pointer? i.e. there are 24 different values that potentially need to be accepted by an hour function and assigned to the clock/timer variables.

The way your program is structured now, there is a separate function for each hour and each minute. You determine which function to call based on its position in an array.

You could have another array, similarly sized, that contained values at each position.

The function pointer array would end up with a lot of duplicates, but the value array would have unique values in each cell. Get the value from the cell that corresponds to the cell that contains the pointer to the function to call.

Ah i understand!

I think will go with the bloated but simpler first solution for now, buti'll bear in mind what you have suggested.

Thanks very much