(Solved) Pass const char [4][20] PROGMEM into function

I have a set of menu items I'd like to print to a 20x4 LCD screen. Rather than make separate functions for each menu that I want to make, I would like to make one function to pass the array pointer to and print the menu that way.

Here is the way I have declared my menu arrays:

// ***************************************************
// Menu PROGMEMs
// ***************************************************
const char config_menu_str[4][20] PROGMEM = 
{
  "Configuration Menu",
  "Backlight:",
  "Contrast:",
  "Zero Offset:"
};
const char analog_menu_str[4][20] PROGMEM = 
{
  "Analog:",
  "Freq:",
  "Amplitude:",
  "DC Offset:"
};

There will be more, these are just the two I'm testing with for now.

Here are the two functions I'm using to write the menus:

void init_CONFIG_menu()
{
  char sbuff[20];
  
  lcd_clear_screen();
  
  for( uint8_t i=0; i<4; i++ )
  {
    lcd_set_cursor( 0, i );
    strcpy_P( sbuff, &config_menu_str[i][0] );
    lcd_print_string( sbuff );
  }
}

void init_ANALOG_menu()
{
  char sbuff[20];
  
  lcd_clear_screen();
  
  for( uint8_t i=0; i<4; i++ )
  {
    lcd_set_cursor( 0, i );
    strcpy_P( sbuff, &analog_menu_str[i][0] );
    lcd_print_string( sbuff );
  }
}

I would like to consolidate these two functions into one init_menu function, but I cannot figure out what type to make the parameter. I've tried const char*, (const char*)[20], const char[][20], and const char [4][20]. None of them work. Here's just one example:

/*void init_menu( (const char*)[20] menu_pointer )
{
  char sbuff[20];
  
  lcd_clear_screen();
  
  for( uint8_t i=0; i<4; i++ )
  {
    lcd_set_cursor( 0, i );
    strcpy_P( sbuff, &menu_pointer[i][0] );
    lcd_print_string( sbuff );
  }
}*/

Does anyone know what I should do to make this work?

NOTE: I'm using an Arduino ONU and IDE version 1.5.7.

If you have the full code, please post it. Also what do you expect to be on the screen, can you provide an example?

Sorry, I should have been more specific. By "none of them work" I mean that they don't even compile. For example for this function:

void init_menu( const char(*)[20] menu_pointer )
{
  char sbuff[20];
  
  lcd_clear_screen();
  
  for( uint8_t i=0; i<4; i++ )
  {
    lcd_set_cursor( 0, i );
    strcpy_P( sbuff, &menu_pointer[i][0] );
    lcd_print_string( sbuff );
  }
}

I get this error:

Arduino: 1.5.7 (Windows 7), Board: "Arduino Uno"

Using library SPI in folder: C:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7\hardware\arduino\avr\libraries\SPI (legacy)

Using library Wire in folder: C:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7\hardware\arduino\avr\libraries\Wire (legacy)



C:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=157 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -IC:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7\hardware\arduino\avr\cores\arduino -IC:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7\hardware\arduino\avr\variants\standard -IC:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7\hardware\arduino\avr\libraries\SPI -IC:\Users\Jiggy\Desktop\PortableApps\PortableApps\arduino-1.5.7\hardware\arduino\avr\libraries\Wire C:\Users\Jiggy\AppData\Local\Temp\build4693557253268471811.tmp\Frequency_Generator.cpp -o C:\Users\Jiggy\AppData\Local\Temp\build4693557253268471811.tmp\Frequency_Generator.cpp.o 

Frequency_Generator.ino:216:33: error: variable or field 'init_menu' declared void
Frequency_Generator.ino:216:17: error: expected primary-expression before 'const'

The two function init_CONFIG_menu() and init_ANALOG_menu() compile and work just fine. The menu shows up on the LCD as I intend. It's only when I try to consolidate them into one function and pass a pointer to the array that it refuses to compile.

My full sketch folder is attached below, and contains one example of the function that refuses to compile.

Frequency_Generator.zip (5.21 KB)

Something like this would work

void init_menu(const char menu[][20])
{
  char sbuff[20];
  
  lcd_clear_screen();
  
  for( uint8_t i=0; i<4; i++ )
  {
    lcd_set_cursor( 0, i );
    strcpy_P( sbuff, &menu[i][0] );
    lcd_print_string( sbuff );
  }
}

init_menu(config_menu_str);

It would be an idea to use a zero-length string to end your menu, then the loop can loop until strlen(sbuff) == 0. That way your menus don't have to have exactly 4 entries.

YES! It works, thank you. Forgot where those stupid brackets are supposed to go.

I have a couple of menus shorter than 4 lines, so I'll take your other suggestion into account.

Thank you again.