could use some help with progmem

I would like to use this code with progmem but can't figure it out .Here is the first part of the code

#include <LiquidCrystal.h>

#include <avr/pgmspace.h>  // library for keeping variables in Flash RAM
//#include <LiquidTWI.h>     // i2c liquid crystal library
#include <ooPinChangeInt.h>
#include <AdaEncoder.h>    // adafruit.com eoncoder routine.
#include <Wire.h>

#define menuTimeout 10000  //delay before settings menus time out & return

#define sumpLevelSwitchPin 2
#define EncoderPin1 6        // Rotary Encoder Pins
#define EncoderPin2 7        //
#define buttonPin A2         // pin for encoder button

#define ATOlevel 20 

#define FanPin 0
#define Heater1Pin 1  
#define Heater2Pin 2
#define Light1Pin 3
#define Light2Pin 4
#define Light3Pin 5
#define ATOPin 6
#define SkimmerPin 7
#define Powerhead1Pin 8
#define Powerhead2Pin 9
#define Powerhead3Pin 10
#define ReturnPumpPin 11
#define CircPumpPin 12
#define Doser1Pin 13
#define Doser2Pin 14
#define AuxPin 15

unsigned long lastTime;
unsigned long lastMills=0;
unsigned long timeout;

byte time[] = {
  12, 00, 00, 00}; // hr, min, sec, msec
byte Date[] = {
  01, 01, 13};     // month, day, year
byte Light1On[] = {
  9, 00};      // hr, min
byte Light1Off[] = {
  22, 00};    // hr, min
byte Light2On[] = {
  10, 00};
byte Light2Off[] = {
  21, 00};
byte Light3On[] = {
  21,00};
byte Light3Off[] = {
  9,00};
byte ATO[] = {
  1, 30};           // full, empty depth of ATO in cm
byte Doser1On[] = {
  0,0};
byte Doser1Off[] = {
  0,0};
byte Doser2On[] = {
  0,0};
byte Doser2Off[] = {
  0,0};

byte Outlets[16] = {
  1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1};
char buffer[18];
const char mainMenu1[] PROGMEM = "1.Water Change ";
const char mainMenu2[] PROGMEM = "2.Feed         ";
const char mainMenu3[] PROGMEM = "3.Man Override ";
const char mainMenu4[] PROGMEM = "4.Settings     ";
const char mainMenu5[] PROGMEM = "5.Exit         ";
 const char * const mainMenu[]PROGMEM  = {
  mainMenu1, mainMenu2, mainMenu3, mainMenu4, mainMenu5};

const char OverrideMenu0[] PROGMEM = "1. Fan         ";
const char OverrideMenu1[] PROGMEM = "2. Heater 1    ";
const char OverrideMenu2[] PROGMEM = "3. Heater 2    ";
const char OverrideMenu3[] PROGMEM = "4. Light1      ";
const char OverrideMenu4[] PROGMEM = "5. Light2      ";
const char OverrideMenu5[] PROGMEM = "6. Light3      ";
const char OverrideMenu6[] PROGMEM = "7. ATO         ";
const char OverrideMenu7[] PROGMEM = "8. Skimmer     ";
const char OverrideMenu8[] PROGMEM = "9. Powerhead 1 ";
const char OverrideMenu9[] PROGMEM = "10.Powerhead 2 ";
const char OverrideMenu10[] PROGMEM = "11.Powerhead 3 ";
const char OverrideMenu11[] PROGMEM = "12.Return Pump ";
const char OverrideMenu12[] PROGMEM = "13.Circ Pump   ";
const char OverrideMenu13[] PROGMEM = "14.Dosing Pump1";
const char OverrideMenu14[] PROGMEM = "15.Dosing Pump2";
const char OverrideMenu15[] PROGMEM = "16.Aux Outlet  ";
const char OverrideMenu16[] PROGMEM = "17.Exit        ";
 const char *const OverrideMenu[]PROGMEM = {
  OverrideMenu0, OverrideMenu1, OverrideMenu2, OverrideMenu3, OverrideMenu4, OverrideMenu5,
  OverrideMenu6, OverrideMenu7, OverrideMenu8, OverrideMenu9, OverrideMenu10, OverrideMenu11,
  OverrideMenu12, OverrideMenu13, OverrideMenu14, OverrideMenu15, OverrideMenu16};

const char OverrideSelect0[] PROGMEM = "1. Auto        ";
const char OverrideSelect1[] PROGMEM = "2. Off         ";
const char OverrideSelect2[] PROGMEM = "3. On          ";
 const char*const OverrideSelect[]PROGMEM ={
  OverrideSelect0, OverrideSelect1, OverrideSelect2};

const char settingsMenu0[] PROGMEM = "1. Time        ";
const char settingsMenu1[] PROGMEM = "2. Date        ";
const char settingsMenu2[] PROGMEM = "3. Light Times ";
const char settingsMenu3[] PROGMEM = "4. Temps       ";
const char settingsMenu4[] PROGMEM = "5. ATO Level   ";
const char settingsMenu5[] PROGMEM = "6. Dosing Pumps";
const char settingsMenu6[] PROGMEM = "7. Return      ";
 const char*const settingsMenu[]PROGMEM ={
  settingsMenu0, settingsMenu1, settingsMenu2, settingsMenu3, settingsMenu4, settingsMenu5, settingsMenu6};

const char lightTimeMenu0[] PROGMEM = "1. Low On      ";
const char lightTimeMenu1[] PROGMEM = "2. High On     ";
const char lightTimeMenu2[] PROGMEM = "3. High Off    ";
const char lightTimeMenu3[] PROGMEM = "4. Low Off     ";
const char lightTimeMenu4[] PROGMEM = "5. Return      ";
 const char*const lightTimeMenu[]PROGMEM ={
  lightTimeMenu0, lightTimeMenu1, lightTimeMenu2,  lightTimeMenu3, lightTimeMenu4};
const char tempMenu0[] = "1. Heater On   ";
const char tempMenu1[] = "2. Fan On      ";
const char tempMenu2[] = "3. Lights Off  ";
const char tempMenu3[] = "4. Return      ";
 const char*  tempMenu[] ={
  tempMenu0, tempMenu1, tempMenu2, tempMenu3};
const char ATOMenu0[] = "1. Set Full    "; 
const char ATOMenu1[] = "2. Set Empty   ";
const char ATOMenu2[] = "3. Add 1 cm    ";
const char ATOMenu3[] = "4. Return      ";
 const char* ATOMenu[]={
  ATOMenu0, ATOMenu1, ATOMenu2, ATOMenu3};

byte heatOnTemp = 77; // Temp to turn Heat on
byte fanOnTemp = 79; // Temp to turn fan on
byte lightOffTemp = 82;

char id=0;
int total = 0;
int8_t clicks;
char *LCDline1[4]; // pointer array for pointers to LCD line 1 strings
char Line1Msg0[] = "00:00  Temp 88 F";
char Line1Msg1[] = "***Temp High ***";
char Line1Msg2[] = "*** Temp Low ***";
char Line1Msg3[] = "*** ATO  Low ***";
char Line1Msg4[] = "**No Temp Probe*";
char Line1Msg5[] = "**No Echo Probe*";
char LCDline2[] =  "Fan: Off  Htr: Off  ATO: 100%  ";

//LiquidTWI lcd(0);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
AdaEncoder encoderA = AdaEncoder('a', EncoderPin1, EncoderPin2);
AdaEncoder *knob=NULL;

void setup(){
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, LOW);
  lcd.begin(16,2);
  Serial.print("free ram: ");
  Serial.println(freeRam());


}

void loop(){
  lcd.clear();
  lcd.print("push button");
  lcd.setCursor(0,1);
  lcd.print("to start...");
  while(!digitalRead(buttonPin)){
  }
  knob = AdaEncoder::genie();  // check for input from rotary encoder
  if (knob != NULL || digitalRead(buttonPin)){
    while(digitalRead(buttonPin));
    delay(20);
    lcd.clear();
    lcd.print("going to menu");
    delay(1000);
    menu();
    // for(int currentItem =0;currentItem<6;currentItem ++){
  }
//}
}
int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

And the second part.

// Routines for settings menus:
// - menu()
// - waterChange()
// - feed()
// - Override()
// - settings()
// - dateSet()
// - setLightTimes()
// - setTemps()
// - setATO()
// - setDosers()
// - setTime

void menu(){
  int item;
  timeout = millis() + menuTimeout;
  do{
    item =(mainMenu, 5);
    switch (item) {
    case 0:
      waterChange();
      break;
    case 1:
      feed();
      break;
    case 2:
      overrideMenu(); // man override...
      break;
    case 3:
      settings();
      break;
    case 4:
      return;
      break;
    }
  }
  while (item != 3 && timeout > millis());
}
// ****************************************************

void waterChange(){
  i2cWrite(SkimmerPin%8, 0, SkimmerPin/8+1);  // Skimmer off
  i2cWrite(ATOPin%8, 0, ATOPin/8+1);          // ATO off
  i2cWrite(Powerhead1Pin%8, 0, Powerhead1Pin/8+1);  // Powerheads off
  i2cWrite(Powerhead2Pin%8, 0, Powerhead2Pin/8+1);
  i2cWrite(Powerhead3Pin%8, 0, Powerhead3Pin/8+1);
  i2cWrite(ReturnPumpPin%8, 0, ReturnPumpPin/8+1);  // Return pump off

  lcd.clear();
  lcd.print(F("Pwrhds, Skimmer"));
  lcd.setCursor(0,1);
  lcd.print(F("ATO, return off"));
  delay(3000);
  lcd.clear();
  lcd.print(F("Press to turn on"));
  lcd.setCursor(3,1);
  lcd.print(F("Return pump"));
  while(!digitalRead(buttonPin));  // wait for button to be pressed
  delay(30);                       // debouncing delay
  while(digitalRead(buttonPin)); // now wait for release
  delay(30);
  i2cWrite(ReturnPumpPin%8, Outlets[ReturnPumpPin]%2, ReturnPumpPin/8+1);

  lcd.setCursor(3,1);
  lcd.print(F("Powerheads "));
  while(!digitalRead(buttonPin));
  delay(30);
  while(digitalRead(buttonPin)); // now wait for release
  delay(30);
  i2cWrite(Powerhead1Pin%8, Outlets[Powerhead1Pin]%2, Powerhead1Pin/8+1);
  i2cWrite(Powerhead2Pin%8, Outlets[Powerhead2Pin]%2, Powerhead2Pin/8+1);
  i2cWrite(Powerhead3Pin%8, Outlets[Powerhead3Pin]%2, Powerhead3Pin/8+1);

  lcd.setCursor(3,1);
  lcd.print(F(" Skimmer   "));
  while(!digitalRead(buttonPin));
  delay(30);
  while(digitalRead(buttonPin)); // now wait for release
  delay(30);
  Outlets[SkimmerPin] = 0b001 + 0b10*(digitalRead(sumpLevelSwitchPin)); //Skimmer on
  i2cWrite(SkimmerPin%8, Outlets[SkimmerPin]%2, SkimmerPin/8+1);

  lcd.setCursor(3,1);
  lcd.print(F("  ATO   "));
  while(!digitalRead(buttonPin));
  delay(30);
  while(digitalRead(buttonPin)); // now wait for release
  delay(30);
  i2cWrite(ATOPin%8, Outlets[ATOPin]%2, ATOPin/8+1);

  return;
}

// ****************************************************

void feed(){
  // Return pump and skimmer off
  i2cWrite(ReturnPumpPin%8, 0, ReturnPumpPin/8+1);
  i2cWrite(SkimmerPin%8, 0, SkimmerPin/8+1);
  lcd.clear();
  lcd.print(F("Pump/skimmer off"));
  lcd.setCursor(0,1);
  lcd.print(F("press to cont..."));
  while(!digitalRead(buttonPin));
  delay(30);
  while(digitalRead(buttonPin)); // now wait for release
  delay(30); // debounce
  timeout = millis() -1; // exit out of menus on return
  return; // pup and skimmer will be returned to their normal states in the main loop
}

// ****************************************************

void overrideMenu(){
  int item;

  do{
    item =(OverrideMenu, 17);
    if (item == 16) return;    // 17 = exit;
    int mode = (OverrideSelect, 3);
    Outlets[item] = Outlets[item]%2 + 2*mode;
    // 'item' indexes the pointer to the proper spot; mode will be
    // 0 for auto, 1 for always off, 2 for always on; LSB (=*outlet%2)
    // is the default value, so it stays unchangedd. 2nd bit (2^1) override off, 
    // 3rd bit (2^2) override on, so multiply menuSelect by 2 for bit values
    // and add.
    lcd.clear();
    lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(OverrideMenu[item]))) + 3);
    lcd.setCursor(0,1);
    lcd.print(F("Set to "));
    lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(OverrideSelect[mode]))) + 3);
    delay(2000);    
  } 
  while (item != 16);
}

// ****************************************************

void settings(){
 // for(int i = 0; i<8;i++)
  int item;
  do{
    item = (settingsMenu, 7);
    switch (item) {
    case 0:
      setTime("Set Time: ", time);
      break;
    case 1:
      dateSet();
      break;
    case 2:
      setLightTimes();
      break;
    case 3:
      setTemps();
      break;
    case 4:
      setATO();
      break;
    case 5:
      setDosers();
      break;
    case 6:
      return;
      break;
    }
  }
  while (item != 6);
  return;
}

// ****************************************************

void dateSet(){
  lcd.clear();
  lcd.print(F("Date:   "));
  if (Date[0] < 10) lcd.print(F("0"));
  lcd.print(Date[0]); 
  lcd.print(F("/"));
  if (Date[1] < 10) lcd.print(F("0"));
  lcd.print(Date[1]); 
  lcd.print(F("/"));
  lcd.print(Date[2]);  
  Date[2] = lcdNumberChg(Date[2], 1, 24, 14); // get year first in case it's a leap year
  if (timeout < millis()) return;             // return if we've timed out

  Date[0] = lcdNumberChg(Date[0], 1, 12, 8);  // now get month
  if (timeout < millis()) return;             // return if we've timed out

  if (Date[0] == 4 || Date[0] == 6 || Date[0] == 9 || Date[0] == 11)
    lcdNumberChg(Date[1], 1, 30, 11); // 30 days hath september....
  else if (Date[0] == 2) {            //check for leap year
    if (Date[2]%4 == 0) lcdNumberChg(Date[1], 1, 29, 11);
    else lcdNumberChg(Date[1], 1, 28, 11);
  }
  else lcdNumberChg(Date[1], 1, 31, 11);
}

// ****************************************************

void setLightTimes(){
  int item;

  do{
    item =(lightTimeMenu, 5);
    switch (item) {
    case 0:
      setTime("Low On:   ", Light1On );
      break;
    case 1:
      setTime("High On:  ", Light2On );
      break;
    case 2:
      setTime("High Off: ", Light2Off );
      break;
    case 3:
      setTime("Low Off:  ", Light1Off );
      break;
    case 4:
      return;
      break;
    }
  }
  while (item != 6);  
}

// ****************************************************

void setTemps(){
  int item;
  do{
    item =(tempMenu, 4);
    lcd.clear();
    switch (item){
    case 0:
      lcd.print(F("Heat on at "));
      lcd.print(heatOnTemp);
      lcd.print(F(" F"));
      heatOnTemp = lcdNumberChg(heatOnTemp, 65, 80, 11);
      break;
    case 1:
      lcd.print(F("Fan on at "));
      lcd.print(fanOnTemp);
      lcd.print(F(" F"));
      fanOnTemp = lcdNumberChg(fanOnTemp, 75, 82, 10);
      break;
    case 2:
      lcd.print(F("Lights off: "));
      lcd.print(lightOffTemp);
      lcd.print(F(" F"));
      lightOffTemp = lcdNumberChg(lightOffTemp, 75, 85, 12);
      break;
    case 3:
      return;
      break;
    }
  } 
  while (item != 3);
}

// ****************************************************

void setATO(){
  boolean noATOflag = false;

  int item =(ATOMenu, 4);
  lcd.clear();

  int ATOavg = 0;
  for (int i = 5; i > 0; i--){
    int newATO = 25; // getATO();
    ATOavg += newATO;
    if (newATO < 1) {
      ATOavg = -1;
      i = 0;      //break from loop
    }
  }
  if (ATOavg < 0){      // Make sure the echo probe is reading properly 1st
    lcd.print(F("No sensor found "));
    lcd.setCursor(0,1);
    lcd.print(F("No changes made "));
    delay(2000);
    return;
  }

And the last part.

 ATOavg = ATOavg/5;  // take the average of the 5 values...

  switch (item){
  case 0:
    ATO[0] = ATOavg;
    lcd.print(F(" Full level set "));
    lcd.setCursor(0,1);
    lcd.print(F("to current level"));
    break;
  case 1:
    ATO[1] = ATOavg;
    lcd.print(F("Empty level set "));
    lcd.setCursor(0,1);
    lcd.print(F("to current level"));
    break;
  case 2:
    ATO[1] = ATOavg + 1;
    lcd.print(F("Empty level set "));
    lcd.setCursor(0,1);
    lcd.print(F("at current+1 cm "));
    break;
  }
  delay(2000);
  return;
}

// ****************************************************

void setDosers(){
  lcd.clear();
  lcd.print(F("     Not yet    "));
  lcd.setCursor(0,1);
  lcd.print(F("   implemented  "));
  delay(2000);
  return;
}

// ****************************************************

// Function to set the time on the LCD display
// Display will show  "[.label..]00:00"
//                    "          ^^   "
// label must be 10 characters so carats allign with digits
// time[] is an integer array with hrs & mins
void setTime(char* label, byte time[]){  // label must be 10 characters
  lcd.clear();
  // print label followed by time 
  lcd.print(label);
  if (time[0] < 10) lcd.print(F("0"));
  lcd.print(time[0]);
  lcd.print(F(":"));
  if (time[1] < 10) lcd.print(F("0"));
  lcd.print(time[1]);
  lcd.setCursor(10,1);
  lcd.print(F("^^"));  // carats under hr positio
  time[0] = lcdNumberChg(time[0], 0, 23, 10);
  time[1] = lcdNumberChg(time[1], 0, 59, 13);
  delay(2000);
}  

// set a two digit number on the LCD display between Max & min (inclusive)
// at LCD column loc
// returns the nuber selected

int lcdNumberChg (int number, int numberMin, int numberMax, int loc){
  lcd.setCursor(loc,1);
  lcd.print(F("^^"));
  timeout = millis() + menuTimeout;

  byte inByte;
  do{
    AdaEncoder *thisEncoder=NULL;
    thisEncoder=AdaEncoder::genie();
    if (thisEncoder != NULL){
      timeout = millis() + menuTimeout;
      int clicks = thisEncoder->query(); // int instead of byte to make compatible with number var
      number += clicks;
      clicks = 0;
      if (number > numberMax) number = numberMin;
      if (number < numberMin) number = numberMax;
      lcd.setCursor(loc,0);
      if (number < 10) lcd.print('0');
      lcd.print(number);
    }
    if(digitalRead(buttonPin)){                   // if button's been pushed
      while (digitalRead(buttonPin)){delay(20);}  // wait for it to be released
      delay(20);                                  // delay for button debounce
      timeout = millis() - 1;                     // set timeout to exit while loop
    }
  } while (timeout > millis());
  lcd.setCursor(loc,1);
  lcd.print(F("  "));
  timeout = millis() + menuTimeout;
  return number;
}

// menuSelect - scroll through a menu, return # of selected item
//
//int menuSelect(const char* menustring[], int menuItems){

//  int currentItem = 0; //item that's currently selected/highlighted
  for(int( currentItem) =0;currentItem<6;currentItem) ++)){
     int currentItem = 0;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F)(">"))); 
  lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[0]))));
  lcd.setCursor(0,1);
  lcd.print(F)(" "))); 
  lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[(1)%menuItems]))));
  timeout = millis() + menuTimeout;
  do {
    AdaEncoder *knob=NULL;
    knob=AdaEncoder::genie();

    if (knob != NULL){
      clicks=knob->query();
      currentItem += clicks;
      clicks = 0;
      timeout = millis() + menuTimeout; // reset timer if there's input
      currentItem = (currentItem + menuItems)%menuItems;  // wrap around 
      // '+ menuitems' makes equation work if curentitem <0
      lcd.setCursor(0,0);
      lcd.print(F(">")); 
      lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[currentItem]))));
      lcd.setCursor(0,1);
      if(currentItem<menuItems-1){          // we're not at the last selection ('exit')
        lcd.print(F(" ")); 
        lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[(currentItem +1)%menuItems]))));
      } else {                              // print the next selection
        lcd.println(F("                ")); // otherwise print a blank line on line 2
      } 
    }
    if(digitalRead(buttonPin)){                  // if button's been pushed
      while (digitalRead(buttonPin)){
        delay(20);                               // wait for it to be released
      } 
      delay(30);                                  //delay for btton debounce
      timeout = millis() + menuTimeout;          // reset timeout time
      return currentItem;
    }
  } 
  while (timeout > millis());   // end do

  timeout = millis() + menuTimeout;
  return (menuItems-1);
} 


void pause(char* msg){
  Serial.print(msg);
  Serial.println(F(", Proceed?"));
  while(!Serial.available());
  while(Serial.available()) Serial.read();
  return;
}

// ************************************
// routine to turn outlets on/off 
// Pins 0-7 are in outlet bank 1, 8-15 in bank 2
// pin%8 converts to 0-7, 
// pin/8+1 converts to i2c address 1 for 0-7, 2 for 8-15
// to allow for automatic assignment if pins are changed

void outlets(){
  i2cWrite(FanPin%8, Outlets[FanPin]%2, FanPin/8+1);
  i2cWrite(Heater1Pin%8, Outlets[Heater1Pin]%2, Heater1Pin/8+1);
  i2cWrite(Heater2Pin%8, Outlets[Heater2Pin]%2, Heater2Pin/8+1);
  i2cWrite(Light1Pin%8, Outlets[Light1Pin]%2, Light1Pin/8+1);
  i2cWrite(Light2Pin%8, Outlets[Light2Pin]%2, Light2Pin/8+1);
  i2cWrite(Light3Pin%8, Outlets[Light3Pin]%2, Light3Pin/8+1);
  i2cWrite(ATOPin%8, Outlets[ATOPin]%2, ATOPin/8+1);
  i2cWrite(SkimmerPin%8, Outlets[SkimmerPin]%2, SkimmerPin/8+1);
  
  i2cWrite(Powerhead1Pin%8, Outlets[Powerhead1Pin]%2, Powerhead1Pin/8+1);
  i2cWrite(Powerhead2Pin%8, Outlets[Powerhead2Pin]%2, Powerhead2Pin/8+1);
  i2cWrite(Powerhead3Pin%8, Outlets[Powerhead3Pin]%2, Powerhead3Pin/8+1);
  i2cWrite(ReturnPumpPin%8, Outlets[ReturnPumpPin]%2, ReturnPumpPin/8+1);
  i2cWrite(CircPumpPin%8, Outlets[CircPumpPin]%2, CircPumpPin/8+1);
  i2cWrite(Doser1Pin%8, Outlets[Doser1Pin]%2, Doser1Pin/8+1);
  i2cWrite(Doser2Pin%8, Outlets[Doser2Pin]%2, Doser2Pin/8+1);
  i2cWrite(AuxPin%8, Outlets[AuxPin]%2, AuxPin/8+1);
  Serial.println();

}

void i2cWrite(byte pin, byte value, byte addr){
  Serial.print("Write "); Serial.print(value);
  Serial.print(" to pin #"); Serial.print(pin);
  Serial.print(" at address ");Serial.println(addr);
}

If there is some thing I am missing please let me know? This code originally was using the old AVR I have already changed all of prog_char too const char and the i believe it is called an array to const char* const but still get this error.
In function 'int menuSelect(const char **, int)':
error: expected primay-expression before ')' token
error: expected ':' before ')'
error: expected '}' at end of input
error: expected primary-expression before ')' token

Sorry about the last part of the code, I had a bunch commented out. I fixed the part with the errors and it now compiles. The LCD screen prints "push button to start...", when I push the button the LCD screen prints "going to menu..." but it doesn't go to the menu. Any idea where the problem is? And here is the last part of the code, fixed.

  ATOavg = ATOavg/5;  // take the average of the 5 values...

  switch (item){
  case 0:
    ATO[0] = ATOavg;
    lcd.print(F(" Full level set "));
    lcd.setCursor(0,1);
    lcd.print(F("to current level"));
    break;
  case 1:
    ATO[1] = ATOavg;
    lcd.print(F("Empty level set "));
    lcd.setCursor(0,1);
    lcd.print(F("to current level"));
    break;
  case 2:
    ATO[1] = ATOavg + 1;
    lcd.print(F("Empty level set "));
    lcd.setCursor(0,1);
    lcd.print(F("at current+1 cm "));
    break;
  }
  delay(2000);
  return;
}

// ****************************************************

void setDosers(){
  lcd.clear();
  lcd.print(F("     Not yet    "));
  lcd.setCursor(0,1);
  lcd.print(F("   implemented  "));
  delay(2000);
  return;
}

// ****************************************************

// Function to set the time on the LCD display
// Display will show  "[.label..]00:00"
//                    "          ^^   "
// label must be 10 characters so carats allign with digits
// time[] is an integer array with hrs & mins
void setTime(char* label, byte time[]){  // label must be 10 characters
  lcd.clear();
  // print label followed by time 
  lcd.print(label);
  if (time[0] < 10) lcd.print(F("0"));
  lcd.print(time[0]);
  lcd.print(F(":"));
  if (time[1] < 10) lcd.print(F("0"));
  lcd.print(time[1]);
  lcd.setCursor(10,1);
  lcd.print(F("^^"));  // carats under hr positio
  time[0] = lcdNumberChg(time[0], 0, 23, 10);
  time[1] = lcdNumberChg(time[1], 0, 59, 13);
  delay(2000);
}  

// set a two digit number on the LCD display between Max & min (inclusive)
// at LCD column loc
// returns the nuber selected

int lcdNumberChg (int number, int numberMin, int numberMax, int loc){
  lcd.setCursor(loc,1);
  lcd.print(F("^^"));
  timeout = millis() + menuTimeout;

  byte inByte;
  do{
    AdaEncoder *thisEncoder=NULL;
    thisEncoder=AdaEncoder::genie();
    if (thisEncoder != NULL){
      timeout = millis() + menuTimeout;
      int clicks = thisEncoder->query(); // int instead of byte to make compatible with number var
      number += clicks;
      clicks = 0;
      if (number > numberMax) number = numberMin;
      if (number < numberMin) number = numberMax;
      lcd.setCursor(loc,0);
      if (number < 10) lcd.print('0');
      lcd.print(number);
    }
    if(digitalRead(buttonPin)){                   // if button's been pushed
      while (digitalRead(buttonPin)){delay(20);}  // wait for it to be released
      delay(20);                                  // delay for button debounce
      timeout = millis() - 1;                     // set timeout to exit while loop
    }
  } while (timeout > millis());
  lcd.setCursor(loc,1);
  lcd.print(F("  "));
  timeout = millis() + menuTimeout;
  return number;
}

// menuSelect - scroll through a menu, return # of selected item

int menuSelect(const char* menustring[], int menuItems){

  int currentItem = 0; //item that's currently selected/highlighted
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F(">")); 
  lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[0]))));
  lcd.setCursor(0,1);
  lcd.print(F(" ")); 
  lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[(1)%menuItems]))));
  timeout = millis() + menuTimeout;
  do {
    AdaEncoder *knob=NULL;
    knob=AdaEncoder::genie();

    if (knob != NULL){
      clicks=knob->query();
      currentItem += clicks;
      clicks = 0;
      timeout = millis() + menuTimeout; // reset timer if there's input
      currentItem = (currentItem + menuItems)%menuItems;  // wrap around 
      // '+ menuitems' makes equation work if curentitem <0
      lcd.setCursor(0,0);
      lcd.print(F(">")); 
      lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[currentItem]))));
      lcd.setCursor(0,1);
      if(currentItem<menuItems-1){          // we're not at the last selection ('exit')
        lcd.print(F(" ")); 
        lcd.println(strcpy_P(buffer, (char*)pgm_read_word(&(menustring[(currentItem +1)%menuItems]))));
      } else {                              // print the next selection
        lcd.println(F("                ")); // otherwise print a blank line on line 2
      } 
    }
    if(digitalRead(buttonPin)){                  // if button's been pushed
      while (digitalRead(buttonPin)){
        delay(20);                               // wait for it to be released
      } 
      delay(30);                                  //delay for btton debounce
      timeout = millis() + menuTimeout;          // reset timeout time
      return currentItem;
    }
  } 
  while (timeout > millis());   // end do

  timeout = millis() + menuTimeout;
  return (menuItems-1);
} 


void pause(char* msg){
  Serial.print(msg);
  Serial.println(F(", Proceed?"));
  while(!Serial.available());
  while(Serial.available()) Serial.read();
  return;
}

// ************************************
// routine to turn outlets on/off 
// Pins 0-7 are in outlet bank 1, 8-15 in bank 2
// pin%8 converts to 0-7, 
// pin/8+1 converts to i2c address 1 for 0-7, 2 for 8-15
// to allow for automatic assignment if pins are changed

void outlets(){
  i2cWrite(FanPin%8, Outlets[FanPin]%2, FanPin/8+1);
  i2cWrite(Heater1Pin%8, Outlets[Heater1Pin]%2, Heater1Pin/8+1);
  i2cWrite(Heater2Pin%8, Outlets[Heater2Pin]%2, Heater2Pin/8+1);
  i2cWrite(Light1Pin%8, Outlets[Light1Pin]%2, Light1Pin/8+1);
  i2cWrite(Light2Pin%8, Outlets[Light2Pin]%2, Light2Pin/8+1);
  i2cWrite(Light3Pin%8, Outlets[Light3Pin]%2, Light3Pin/8+1);
  i2cWrite(ATOPin%8, Outlets[ATOPin]%2, ATOPin/8+1);
  i2cWrite(SkimmerPin%8, Outlets[SkimmerPin]%2, SkimmerPin/8+1);
  
  i2cWrite(Powerhead1Pin%8, Outlets[Powerhead1Pin]%2, Powerhead1Pin/8+1);
  i2cWrite(Powerhead2Pin%8, Outlets[Powerhead2Pin]%2, Powerhead2Pin/8+1);
  i2cWrite(Powerhead3Pin%8, Outlets[Powerhead3Pin]%2, Powerhead3Pin/8+1);
  i2cWrite(ReturnPumpPin%8, Outlets[ReturnPumpPin]%2, ReturnPumpPin/8+1);
  i2cWrite(CircPumpPin%8, Outlets[CircPumpPin]%2, CircPumpPin/8+1);
  i2cWrite(Doser1Pin%8, Outlets[Doser1Pin]%2, Doser1Pin/8+1);
  i2cWrite(Doser2Pin%8, Outlets[Doser2Pin]%2, Doser2Pin/8+1);
  i2cWrite(AuxPin%8, Outlets[AuxPin]%2, AuxPin/8+1);
  Serial.println();

}

void i2cWrite(byte pin, byte value, byte addr){
  Serial.print("Write "); Serial.print(value);
  Serial.print(" to pin #"); Serial.print(pin);
  Serial.print(" at address ");Serial.println(addr);
}

I not sure what code I need to add to print to lcd this code was originally used with the old avr i made the changes from prog_char to const char. A lot to learn .Can You make a suggestion?

In one of my programs I use a similar solution :

#define LCD_ROWS         4
#define LCD_COLS        20

const char menu_rows [MENU_ROWS] [LCD_COLS + 1]  PROGMEM = { 
  //1234567890123456789
  {" Set start delay    "},
  {" Set alm_1 speed    "},
  {" Set alm_2 speed    "},
  {" Force alm_1        "},
  {" Force alm_2        "},
  {" Force bypass       "},
  {" Exit menu          "}
};

char lcdBuf[LCD_COLS + 1];

//copy menu string to buffer

memcpy_P(&lcdBuf, &menu_rows [row], LCD_COLS);

It works, but I note just now that the string miss the '\0' terminator, better adding one, or no?

Hope can help.

Cheers, Ale.

I know the code is long and i am using it now. Only not in progmem but have run out of memory. All did for that was very little changes too the strcpy_p lines. I just removed strcpy_P(buffer(char*)pgm_read_word and that works.But not in progmem.I am really new to programming.

I made the changes but still is doing the same problem here are the changes

 int menuSelect(const char*  menustring[], int menuItems){

  int currentItem = 0; //item that's currently selected/highlighted
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F(">")); 
  lcd.println(strcpy_P(buffer,menustring[0]));
  lcd.setCursor(0,1);
  lcd.print(F(" ")); 
  lcd.println(strcpy_P(buffer,menustring[(1)%menuItems]));
  timeout = millis() + menuTimeout;
  do {
    AdaEncoder *knob=NULL;
    knob=AdaEncoder::genie();

    if (knob != NULL){
      clicks=knob->query();
      currentItem += clicks;
      clicks = 0;
      timeout = millis() + menuTimeout; // reset timer if there's input
      currentItem = (currentItem + menuItems)%menuItems;  // wrap around 
      // '+ menuitems' makes equation work if curentitem <0
      lcd.setCursor(0,0);
      lcd.print(F(">")); 
      lcd.println(strcpy_P(buffer,menustring[currentItem]));
      lcd.setCursor(0,1);
      if(currentItem<menuItems-1){          // we're not at the last selection ('exit')
        lcd.print(F(" ")); 
        lcd.println(strcpy_P(buffer,menustring[(currentItem +1)%menuItems]));
      } else {                              // print the next selection
        lcd.println(F("                ")); // otherwise print a blank line on line 2
      } 
    }

all of the code is there just copy and paste the first second and forth pieces of code as the third one has errors all the code is there and in order

I will attach a copy of the code as an attachment. I am very new to this forum. I really do appreciate all of your help, and I know that time is very valuable. I was unsure if you were aware that all of the code was there. Thanks.

controller6.ino (19.4 KB)

I figured it out I was missing a const char* const beside int menuSelect.I only had const char* and in void menu ,menuSelect is missing that goes right to the left of(mainMenu, 5) thanks for your help, Sorry you thought I was wasting your time.I really was just looking for help.THANKS

Why is the function declaration of menuSelect commented out?

I was getting errors when I was trying to use progmem I got progmem working and forgot to un comment function MenuSelect I put all the menuSelect back in now everything is working.