Newby advice needed

Hi Everyone,

This is my first project, and I really need some advice please.

I'm busy setting up a Mega 2560 board with a 8 way relay board and a LCD shield with buttons for our business. The relays wil control blower motors, and the "up" and "down" screen buttons need to change one value.

I have managed to get the code working for the 8 relays, which will control the blowers. Each blower blows for 10 seconds in a sequence, and that will not change. The only value that needs to change is the time between blows. I've set the two values as "int on = 10" and "int off = 10". These values are seconds as I multiply by 1000 to achieve the correct milliseconds when each relay is called.

Is there a simple way of using the up and down buttons on the LCD shield to change the off value, and also displaying the changed value on the screen? I currently print the off value on the LCD so that it is known, but it has to also change as the off value changes in the code.

Please don't laugh, it's my first time coding, it's probably a bit of a confusing code, but I hope someone can point me in the right direction :wink:
My code so far is,

int Machine1 = 22 ; // I/O pin connected by the first relay
int Machine2 = 24 ;
int Machine3 = 26 ;
int Machine4 = 28 ;
int Machine5 = 30 ;
int Machine6 = 32 ;
int Machine7 = 34 ;
int Machine8 = 36 ;
int on = 10 ; // seconds
int off = 10 ; // seconds

int NUM = 1 ; // Change to 0 to stop relay sequence, 1 to start



#include <LiquidCrystal.h>

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);



void setup()


{
  for (int i1 = Machine1; i1 < Machine1 + NUM; i1 ++)
  {
    pinMode(i1, OUTPUT); //set digital I/O pin as output
  }
  {
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("CHINCO FIRESIDE");
    lcd.setCursor(0, 1);
    lcd.print("TREATMENT");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("D:"); // Delay time
    lcd.print(off);
    lcd.print("s");
    lcd.setCursor(11, 0);
    lcd.print("B:"); //Blow time
    lcd.print(on);
    lcd.print("s");
    lcd.setCursor(3, 0);
  }
}

void loop()



// Machine 1
{
  {
    lcd.setCursor(6, 1);
    lcd.print("DaysOn:");
    lcd.print(millis() / 864000000);
  }
  {}
  {
    lcd.setCursor(0, 1);
    lcd.print("APPL1");
    lcd.setCursor(0, 0);
  }
  for (int i1 = Machine1; i1 < Machine1 + NUM; i1 ++)
  {
    digitalWrite(i1, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
    delay(on * 1000); //delay
  }

  {
    for (int i1 = Machine1; i1 < Machine1 + NUM; i1 ++)
    {
      digitalWrite(i1, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
      delay(off * 1000); //delay
    }

    // Machine 2
    {
      {
        lcd.setCursor(0, 1);
        lcd.print("APPL2");
        lcd.setCursor(0, 0);
      }
      for (int i2 = Machine2; i2 < Machine2 + NUM; i2 ++)
      {
        pinMode(i2, OUTPUT); //set digital I/O pin as output
      }
      {
        for (int i2 = Machine2; i2 < Machine2 + NUM; i2 ++)
        {
          digitalWrite(i2, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
          delay(on * 1000); //delay
          {
          }
          for (int i2 = Machine2; i2 < Machine2 + NUM; i2 ++)
          {
            digitalWrite(i2, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
            delay(off * 1000); //delay
          }
        }

        // Machine 3
        {
          {
            lcd.setCursor(0, 1);
            lcd.print("APPL3");
            lcd.setCursor(0, 0);
          }
          for (int i3 = Machine3; i3 < Machine3 + NUM; i3 ++)
          {
            pinMode(i3, OUTPUT); //set digital I/O pin as output
          }
          {
            for (int i3 = Machine3; i3 < Machine3 + NUM; i3 ++)
            {
              digitalWrite(i3, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
              delay(on * 1000); //delay
            }
            for (int i3 = Machine3; i3 < Machine3 + NUM; i3 ++)
            {
              digitalWrite(i3, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
              delay(off * 1000); //delay
            }

            // Machine 4

          }
          {
            lcd.setCursor(0, 1);
            lcd.print("APPL4");
            lcd.setCursor(0, 0);
          }
          for (int i4 = Machine4; i4 < Machine4 + NUM; i4 ++)
          {
            pinMode(i4, OUTPUT); //set digital I/O pin as output
          }
          {
            for (int i4 = Machine4; i4 < Machine4 + NUM; i4 ++)
            {
              digitalWrite(i4, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
              delay(on * 1000); //delay
            }
            for (int i4 = Machine4; i4 < Machine4 + NUM; i4 ++)
            {
              digitalWrite(i4, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
              delay(off * 1000); //delay
            }
          }

          // Machine 5
          {
            lcd.setCursor(0, 1);
            lcd.print("APPL5");
            lcd.setCursor(0, 0);
          }
          for (int i5 = Machine5; i5 < Machine5 + NUM; i5 ++)
          {
            pinMode(i5, OUTPUT); //set digital I/O pin as output
          }
          {
            for (int i5 = Machine5; i5 < Machine5 + NUM; i5 ++)
            {
              digitalWrite(i5, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
              delay(on * 1000); //delay
            }
            for (int i5 = Machine5; i5 < Machine5 + NUM; i5 ++)
            {
              digitalWrite(i5, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
              delay(off * 1000); //delay
            }
          }

          // Machine 6
          {
            lcd.setCursor(0, 1);
            lcd.print("APPL6");
            lcd.setCursor(0, 0);
          }
          for (int i6 = Machine6; i6 < Machine6 + NUM; i6 ++)
          {
            pinMode(i6, OUTPUT); //set digital I/O pin as output
          }
          {
            for (int i6 = Machine6; i6 < Machine6 + NUM; i6 ++)
            {
              digitalWrite(i6, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
              delay(on * 1000); //delay
            }
            for (int i6 = Machine6; i6 < Machine6 + NUM; i6 ++)
            {
              digitalWrite(i6, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
              delay(off * 1000); //delay
            }
          }

          // Machine 7
          {
            lcd.setCursor(0, 1);
            lcd.print("APPL7");
            lcd.setCursor(0, 0);
          }
          for (int i7 = Machine7; i7 < Machine7 + NUM; i7 ++)
          {
            pinMode(i7, OUTPUT); //set digital I/O pin as output
          }
          {
            for (int i7 = Machine7; i7 < Machine7 + NUM; i7 ++)
            {
              digitalWrite(i7, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
              delay(on * 1000); //delay
            }
            for (int i7 = Machine7; i7 < Machine7 + NUM; i7 ++)
            {
              digitalWrite(i7, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
              delay(off * 1000); //delay
            }
          }

          //Machine 8
          {
            lcd.setCursor(0, 1);
            lcd.print("APPL8");
            lcd.setCursor(0, 0);
          }
          for (int i8 = Machine8; i8 < Machine8 + NUM; i8 ++)
          {
            pinMode(i8, OUTPUT); //set digital I/O pin as output
          }
          {
            for (int i8 = Machine8; i8 < Machine8 + NUM; i8 ++)
            {
              digitalWrite(i8, HIGH); //set digital I/O pin as ‘high’, i.e. turning on the relay gradually
              delay(on * 1000); //delay
            }
            for (int i8 = Machine8; i8 < Machine8 + NUM; i8 ++)
            {
              digitalWrite(i8, LOW); // set digital I/O pin as ‘low’, i.e. turning off the relay gradually
              delay(off * 1000); //delay
            }
          }




        }
      }
    }
  }
}

Thanks for the help.

Lance

LanceRoberts:
Is there a simple way of using the up and down buttons on the LCD shield to change the off value, and also displaying the changed value on the screen?

Assuming you have one of these or similar, then reply #8 in this thread may help. Maybe not beginner code though?

Personally I think for things and people like me, anyway, I don't like the shields unless They're for much bigger things.

I figure just use buttons you rig up, and connect them to arduino pins, and assign each pin.

I believe there is an easy tutorial that has a single button select 3 or more led's in sequence, each button push brings the arduino to the next led.

You could probably just find the led tutorial, and then the code wouldn't use any libraries, or be very long at all.

Thanks for the advice, I'll look at all options.

If you ever decide to have more than one or more blowers running independently at the same time, the delays() will cause a serious problem.

To avoid this, study the "blink without delay" or the "how to do several things at once" examples.

Thanks a lot, I'll take a look at it now.

@trmspace: I don't think your suggestion addresses OP's question, which (if I read it correctly, anyway) is that he wants to have a value say 1234 displayed on the LCD, and wants to button up / down to desired value of say 1200 or 1250, then accepting that value as the new "off" value.

The thread I linked to does exactly that, allowing the user to highlight the digit to be changed, say digit 2 in 1234 then up and down to change that to 1534, then accept the final 1534 as a value to use.

The buttons on the DFR0009 LCD shield are all part of a resistor network onto one single analog pin; there's a unique analog value for each button, so it can tell which button is pressed via one pin.

I needed something sinilar for a project: the relevant bit of code is

    case mod_times : {
        static unsigned int mod_time_value;
        if (statechange == true) {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print(F("Change time ^v :"));
          lcd.setCursor(12, 1);
          lcd.print("secs");
          lcd.setCursor(4, 1);
          lcd.print(F("        "));
          lcd.setCursor(4, 1);
          lcd.print(targetTIME);
          mod_time_value = targetTIME;
          statechange = false;
          //Serial.write("          mod_time");
          //Serial.write("\n");
        }

        if (readbutton(up)) {
          if (actTIME < maxTIME) {
            mod_time_value++;
            lcd.setCursor(4, 1);
            lcd.print(F("        "));
            lcd.setCursor(4, 1);
            lcd.print(mod_time_value);
            //Serial.print (mod_time_value);
            //Serial.print (" \n");
          }
        }

        if (readbutton(down)) {
          if (mod_time_value > minTIME) {
            mod_time_value--;
            lcd.setCursor(4, 1);
            lcd.print(F("        "));
            lcd.setCursor(4, 1);
            lcd.print(mod_time_value);
            //Serial.print(mod_time_value);
            //Serial.print (" \n");
          }
        }

        if (readbutton(menu)) {
          state = mod_temp;
          statechange = true;
        }

        if (readbutton(startstop)) {
          EEPROM.update(ETIME, mod_time_value);
          targetTIME = mod_time_value;
          state = start;
          statechange = true;
        }

      }
      break;

This is part of a state machine, whose state change is signalled by statechange, which forces the new state to set up it's appropriate display ......

I saved the changed values in eeprom to survive powerdowns.

regards

Allan

Thanks guys,

This thing is kicking my ass, I'm a total newby with this coding and I'm trying to put multiple sections into one program.

  1. 8 relays working in sequence with the same off time (Which needs to be changed occasionally), and an on time which doesn't change.
  2. a Menu system controlled by the buttons on the shield
  3. a Menu which shows the current on and off times
  4. a Menu which will enable me to change the off time in the global settings

Every time I put two of the parts together I get loads of "not declared" errors... And it takes me forever to try and figure out what it means.

So, I'm having quite a frustrating new years day, but I'll get it going somehow.

Started with a beginners guide to programing, but I don't think it has what I need.

Happy new years guys, hope it's a good one!

The eight very similar sections of your code each labelled MachineX are a big red flag indicating that something is not quite right. You need to find a way to adapt that code so that you can just have one copy that serves all blowers. Depending on whether you're relishing the challenge or just want to get it working, I'd be happy to refactor it for you.

If you want a series of menus you'll need to get to understand the concept of a state machine. Each menu is handled in it's own different state, with it's own properties and means of transitions to other states .

There are various tutorials.

If you've done little software before it'll take a bit of learning.

good luck

Allan.

wildbill:
The eight very similar sections of your code each labelled MachineX are a big red flag indicating that something is not quite right. You need to find a way to adapt that code so that you can just have one copy that serves all blowers. Depending on whether you're relishing the challenge or just want to get it working, I'd be happy to refactor it for you.

I would really like to learn the coding because I always like a new challenge... Only problem is that I've only got a few weeks before I need to use this device for a trial in China. I'm still trying to figure everything out, so will keep on doing so, and I cant really expect someone else to do it for me.

I've been looking at at setting up the blowers with the blinking code in stead of a delay after each blower, but I'm still busy looking into that route.

Guess I should've done more research before going the Arduino route, I just thought it would be the best solution for my problem.

Thanks for all the advice so far guys, really appreciate it.

Fair enough. If there's a time crunch, you might consider the gigs and collaborations section - there are a number of folks there who may be able to help you trade time for money. In the mean time, I'll just back this up here so I don't lose it :wink:

#include <LiquidCrystal.h>

const byte Machine1 = 22; // I/O pin connected by the first relay
const byte Machine2 = 24;
const byte Machine3 = 26;
const byte Machine4 = 28;
const byte Machine5 = 30;
const byte Machine6 = 32;
const byte Machine7 = 34;
const byte Machine8 = 36;

unsigned long BlowerStartTime;
unsigned long BlowerStopTime;

int onTime = 10 ; // seconds
int offTime = 10 ; // seconds

bool BlowerIsRunning=false;
byte CurrentBlower=Machine1;

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{
for (int i = Machine1; i <= Machine8; i +=2)
  {
  pinMode(i, OUTPUT); //set digital I/O pin as output
  }

lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("CHINCO FIRESIDE");
lcd.setCursor(0, 1);
lcd.print("TREATMENT");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("D:"); // Delay time
lcd.print(offTime);
lcd.print("s");
lcd.setCursor(11, 0);
lcd.print("B:"); //Blow time
lcd.print(onTime);
lcd.print("s");
lcd.setCursor(3, 0);
}

void loop()
{
DisplayDaysOn();  
if(BlowerIsRunning)
  {
  if(millis()-BlowerStartTime > onTime * 1000UL)
    {
    StopBlower(CurrentBlower);
    CurrentBlower+=2;
    if(CurrentBlower > Machine8)
      CurrentBlower=Machine1;
    }
  }
else
  {  
  if(millis()-BlowerStopTime > offTime * 1000UL)
    {
    StartBlower(CurrentBlower);
    }
  }
}

void DisplayDaysOn()
{
lcd.setCursor(6, 1);
lcd.print("DaysOn:");
lcd.print(millis() / 864000000UL);  
}

void StopBlower(int BlowerPin)
{
digitalWrite(BlowerPin, LOW);
BlowerIsRunning=false;
BlowerStopTime=millis();  
}

void StartBlower(int BlowerPin)
{
digitalWrite(BlowerPin, HIGH);
BlowerIsRunning=true;
BlowerStartTime=millis();  
lcd.setCursor(0, 1);
lcd.print("APPL");
lcd.print((BlowerPin-Machine1)/2+1);
lcd.setCursor(0, 0);
}

wildbill:
Fair enough. If there's a time crunch, you might consider the gigs and collaborations section - there are a number of folks there who may be able to help you trade time for money. In the mean time, I'll just back this up here so I don't lose it :wink:

How did you do that!?!? I've been trying for ages now to get the blowers going without "delays"... Thanks a million! Going to read your code now to try decipher it.

Now I can start looking at changing the off value with the buttons on my lcd shield.

Thanks again

LanceRoberts:
Now I can start looking at changing the off value with the buttons on my lcd shield.

And that's where my reply#1 comes back into play. For ease of reference here's the link I gave in #1: look at #8 here. I'd advise understanding that code fully before you try to incorporate that thinking into your real blower code. (Assumption is that you have a DFR0009 or similar LCD with buttons.)

(I did some messing around with that yesterday where I change the on- and off- times of an led, on the fly. Next step is to use that to set the parameters for a servo: min degrees, max degrees and speed.)

Was just going to read that thread. :slight_smile:
Thanks

Ok, this is as far as I can get now. When I add my menu structure the errors start. In the code below I have excluded the blower motor section at the bottom, with the /* tags, and as soon as I take the tags out I get a "error: expected unqualified-id before '{' token" error on the '{' which is just before 'if (BlowerIsRunning)'.

I have no idea if this menu structure is going to work in conjunction with the blower section... And I still have to get the part of the menu working where I change the delay times...

Any advise?

#include <LiquidCrystal.h>
const byte Machine1 = 22; // I/O pin connected by the first relay
const byte Machine2 = 24;
const byte Machine3 = 26;
const byte Machine4 = 28;
const byte Machine5 = 30;
const byte Machine6 = 32;
const byte Machine7 = 34;
const byte Machine8 = 36;
unsigned long BlowerStartTime;
unsigned long BlowerStopTime;
int onTime = 1 ; // seconds
int offTime = 100 ; // seconds
bool BlowerIsRunning = false;
byte CurrentBlower = Machine1;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int currentMenuItem = 0;
int lastState = 0;

void setup()
{
  for (int i = Machine1; i <= Machine8; i += 2)
  {
    pinMode(i, OUTPUT); //set digital I/O pin as output
  }

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
  lcd.print("TREATMENT");
  delay(2000);
  lcd.clear();
  clearPrintTitle();
}

void loop()
{
  mainMenu();
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0, 0);

  //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 250) {
    //Up
    state = 1;
  } else if (x < 450) {
    //Down
    state = 2;
  } else if (x < 650) {
    //Left
  } else if (x < 850) {
    //Select
    state = 3;
  }

  //If we are out of bounds on the menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
    currentMenuItem = 0;
  }

  //If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 1) {
      //If Up
      currentMenuItem = currentMenuItem - 1;
      displayMenu(currentMenuItem);
    } else if (state == 2) {
      //If Down
      currentMenuItem = currentMenuItem + 1;
      displayMenu(currentMenuItem);
    } else if (state == 3) {
      //If Selected
      selectMenu(currentMenuItem);
    }
    //Save the last State to compare.
    lastState = state;
  }
  //Small delay
  //  delay(5);
}

//Display Menu Option based on Index.
void displayMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.print ("Timings");
      break;
    case 2:
      clearPrintTitle();
      lcd.print ("Days On");
      break;
    case 3:
      clearPrintTitle();
      lcd.print ("TimeBetweenBlows");
      break;
    case 4:
      clearPrintTitle();
      lcd.print ("BlowTime");
      break;
  }
}

//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
}

//Show the selection on Screen.
void selectMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print("D:"); // Delay time
      lcd.print(offTime);
      lcd.print("s");
      lcd.setCursor(11, 1);
      lcd.print("B:"); // Blow time
      lcd.print(onTime);
      lcd.print("s");
      //Call the function that belongs to Option 1
      break;
    case 2:
      clearPrintTitle();
      void DisplayDaysOn();
      lcd.setCursor(0, 1);
      lcd.print("DaysOn:");
      lcd.print(millis() / 864000000UL);
      //Call the function that belongs to Option 2
      break;
    case 3:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("Off Delay=");
      lcd.print (offTime);
      lcd.print ("s");
      //Call the function that belongs to Option 3
      break;
    case 4:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("On Delay=");
      lcd.print (onTime);
      lcd.print ("s");
      //Call the function that belongs to Option 4
      break;
  }
}


/*
{
  if (BlowerIsRunning)
  {
    if (millis() - BlowerStartTime > onTime * 1000UL)
    {
      StopBlower(CurrentBlower);
      CurrentBlower += 2;
      if (CurrentBlower > Machine8)
        CurrentBlower = Machine1;
    }
  }
  else
  {
    if (millis() - BlowerStopTime > offTime * 1000UL)
    {
      StartBlower(CurrentBlower);
    }
  }
}



void StopBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, LOW);
  BlowerIsRunning = false;
  BlowerStopTime = millis();
}

void StartBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, HIGH);
  BlowerIsRunning = true;
  BlowerStartTime = millis();
  //  lcd.setCursor(0, 1);
  //  lcd.print("APPL");
  //  lcd.print((BlowerPin - Machine1) / 2 + 1);
  //  lcd.setCursor(0, 0);
}
*/

Here is a version that compiles:

#include <LiquidCrystal.h>
const byte Machine1 = 22; // I/O pin connected by the first relay
const byte Machine2 = 24;
const byte Machine3 = 26;
const byte Machine4 = 28;
const byte Machine5 = 30;
const byte Machine6 = 32;
const byte Machine7 = 34;
const byte Machine8 = 36;
unsigned long BlowerStartTime;
unsigned long BlowerStopTime;
int onTime = 1 ; // seconds
int offTime = 100 ; // seconds
bool BlowerIsRunning = false;
byte CurrentBlower = Machine1;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int currentMenuItem = 0;
int lastState = 0;

void setup()
{
  for (int i = Machine1; i <= Machine8; i += 2)
  {
    pinMode(i, OUTPUT); //set digital I/O pin as output
  }

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
  lcd.print("TREATMENT");
  delay(2000);
  lcd.clear();
  clearPrintTitle();
}

void loop()
{
  mainMenu();
  ManageBlowers();
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0, 0);

  //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 250) {
    //Up
    state = 1;
  } else if (x < 450) {
    //Down
    state = 2;
  } else if (x < 650) {
    //Left
  } else if (x < 850) {
    //Select
    state = 3;
  }

  //If we are out of bounds on the menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
    currentMenuItem = 0;
  }

  //If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 1) {
      //If Up
      currentMenuItem = currentMenuItem - 1;
      displayMenu(currentMenuItem);
    } else if (state == 2) {
      //If Down
      currentMenuItem = currentMenuItem + 1;
      displayMenu(currentMenuItem);
    } else if (state == 3) {
      //If Selected
      selectMenu(currentMenuItem);
    }
    //Save the last State to compare.
    lastState = state;
  }
  //Small delay
  //  delay(5);
}

//Display Menu Option based on Index.
void displayMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.print ("Timings");
      break;
    case 2:
      clearPrintTitle();
      lcd.print ("Days On");
      break;
    case 3:
      clearPrintTitle();
      lcd.print ("TimeBetweenBlows");
      break;
    case 4:
      clearPrintTitle();
      lcd.print ("BlowTime");
      break;
  }
}

//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
}

//Show the selection on Screen.
void selectMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print("D:"); // Delay time
      lcd.print(offTime);
      lcd.print("s");
      lcd.setCursor(11, 1);
      lcd.print("B:"); // Blow time
      lcd.print(onTime);
      lcd.print("s");
      //Call the function that belongs to Option 1
      break;
    case 2:
      clearPrintTitle();
      void DisplayDaysOn();
      lcd.setCursor(0, 1);
      lcd.print("DaysOn:");
      lcd.print(millis() / 864000000UL);
      //Call the function that belongs to Option 2
      break;
    case 3:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("Off Delay=");
      lcd.print (offTime);
      lcd.print ("s");
      //Call the function that belongs to Option 3
      break;
    case 4:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("On Delay=");
      lcd.print (onTime);
      lcd.print ("s");
      //Call the function that belongs to Option 4
      break;
  }
}


void ManageBlowers()
{
  if (BlowerIsRunning)
  {
    if (millis() - BlowerStartTime > onTime * 1000UL)
    {
      StopBlower(CurrentBlower);
      CurrentBlower += 2;
      if (CurrentBlower > Machine8)
        CurrentBlower = Machine1;
    }
  }
  else
  {
    if (millis() - BlowerStopTime > offTime * 1000UL)
    {
      StartBlower(CurrentBlower);
    }
  }
}



void StopBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, LOW);
  BlowerIsRunning = false;
  BlowerStopTime = millis();
}

void StartBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, HIGH);
  BlowerIsRunning = true;
  BlowerStartTime = millis();
  //  lcd.setCursor(0, 1);
  //  lcd.print("APPL");
  //  lcd.print((BlowerPin - Machine1) / 2 + 1);
  //  lcd.setCursor(0, 0);
}

I compiled the last version but didn't test it; did it run the blowers as expected?

As to your menus, it looks as though you're adapting existing menu code but for your needs, at least at the moment, you can get away with a simpler scheme. All you need are three modes and the select button can cycle between them.

In the first mode you display your screen that shows how long the system has been running. In the next mode, you display onTime. The up button increments it, the down button decrements it. The final mode does the same for offTime.

If desired, you can have a fourth mode that just displays the two timing variables.

wildbill:
Here is a version that compiles:

#include <LiquidCrystal.h>

const byte Machine1 = 22; // I/O pin connected by the first relay
const byte Machine2 = 24;
const byte Machine3 = 26;
const byte Machine4 = 28;
const byte Machine5 = 30;
const byte Machine6 = 32;
const byte Machine7 = 34;
const byte Machine8 = 36;
unsigned long BlowerStartTime;
unsigned long BlowerStopTime;
int onTime = 1 ; // seconds
int offTime = 100 ; // seconds
bool BlowerIsRunning = false;
byte CurrentBlower = Machine1;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int currentMenuItem = 0;
int lastState = 0;

void setup()
{
  for (int i = Machine1; i <= Machine8; i += 2)
  {
    pinMode(i, OUTPUT); //set digital I/O pin as output
  }

lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
  lcd.print("TREATMENT");
  delay(2000);
  lcd.clear();
  clearPrintTitle();
}

void loop()
{
  mainMenu();
  ManageBlowers();
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0, 0);

//Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 250) {
    //Up
    state = 1;
  } else if (x < 450) {
    //Down
    state = 2;
  } else if (x < 650) {
    //Left
  } else if (x < 850) {
    //Select
    state = 3;
  }

//If we are out of bounds on the menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
    currentMenuItem = 0;
  }

//If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 1) {
      //If Up
      currentMenuItem = currentMenuItem - 1;
      displayMenu(currentMenuItem);
    } else if (state == 2) {
      //If Down
      currentMenuItem = currentMenuItem + 1;
      displayMenu(currentMenuItem);
    } else if (state == 3) {
      //If Selected
      selectMenu(currentMenuItem);
    }
    //Save the last State to compare.
    lastState = state;
  }
  //Small delay
  //  delay(5);
}

//Display Menu Option based on Index.
void displayMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.print ("Timings");
      break;
    case 2:
      clearPrintTitle();
      lcd.print ("Days On");
      break;
    case 3:
      clearPrintTitle();
      lcd.print ("TimeBetweenBlows");
      break;
    case 4:
      clearPrintTitle();
      lcd.print ("BlowTime");
      break;
  }
}

//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
}

//Show the selection on Screen.
void selectMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print("D:"); // Delay time
      lcd.print(offTime);
      lcd.print("s");
      lcd.setCursor(11, 1);
      lcd.print("B:"); // Blow time
      lcd.print(onTime);
      lcd.print("s");
      //Call the function that belongs to Option 1
      break;
    case 2:
      clearPrintTitle();
      void DisplayDaysOn();
      lcd.setCursor(0, 1);
      lcd.print("DaysOn:");
      lcd.print(millis() / 864000000UL);
      //Call the function that belongs to Option 2
      break;
    case 3:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("Off Delay=");
      lcd.print (offTime);
      lcd.print ("s");
      //Call the function that belongs to Option 3
      break;
    case 4:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("On Delay=");
      lcd.print (onTime);
      lcd.print ("s");
      //Call the function that belongs to Option 4
      break;
  }
}

void ManageBlowers()
{
  if (BlowerIsRunning)
  {
    if (millis() - BlowerStartTime > onTime * 1000UL)
    {
      StopBlower(CurrentBlower);
      CurrentBlower += 2;
      if (CurrentBlower > Machine8)
        CurrentBlower = Machine1;
    }
  }
  else
  {
    if (millis() - BlowerStopTime > offTime * 1000UL)
    {
      StartBlower(CurrentBlower);
    }
  }
}

void StopBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, LOW);
  BlowerIsRunning = false;
  BlowerStopTime = millis();
}

void StartBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, HIGH);
  BlowerIsRunning = true;
  BlowerStartTime = millis();
  //  lcd.setCursor(0, 1);
  //  lcd.print("APPL");
  //  lcd.print((BlowerPin - Machine1) / 2 + 1);
  //  lcd.setCursor(0, 0);
}




I compiled the last version but didn't test it; did it run the blowers as expected?

As to your menus, it looks as though you're adapting existing menu code but for your needs, at least at the moment, you can get away with a simpler scheme. All you need are three modes and the select button can cycle between them. 

In the first mode you display your screen that shows how long the system has been running. In the next mode, you display onTime. The up button increments it, the down button decrements it. The final mode does the same for offTime.

If desired, you can have a fourth mode that just displays the two timing variables.

Fantastic!!
The code works great now, at least I know the menu actually works with the timer section.

Your suggestion that the select button cycles through the modes sounds great. I just feel bad using everyone else's code to get my project working. As soon as I can get the first unit up and running I'll have more time to study the different methods of coding, and perfect the units.

Do you have any examples that would achieve the mentioned four mode method? As well as the increment/decrement section which would then update the offTime value in the global settings?

Thanks again!

wildbill:
Here is a version that compiles:

I compiled the last version but didn't test it; did it run the blowers as expected?

As to your menus, it looks as though you're adapting existing menu code but for your needs, at least at the moment, you can get away with a simpler scheme. All you need are three modes and the select button can cycle between them.

In the first mode you display your screen that shows how long the system has been running. In the next mode, you display onTime. The up button increments it, the down button decrements it. The final mode does the same for offTime.

If desired, you can have a fourth mode that just displays the two timing variables.

Ok, I got the "Select to Cycle" method working. Now I just need to get the increment/decrement to working on the third and fourth menus to change the value before the "s", and so that it changes the global "onTime" and "offTime" values which in turn affects the time delays of the blowers.

One thing I just thought about, would the changed value stay the same, even after the device reboots?

#include <LiquidCrystal.h>
const byte Machine1 = 22; // I/O pin connected by the first relay
const byte Machine2 = 24;
const byte Machine3 = 26;
const byte Machine4 = 28;
const byte Machine5 = 30;
const byte Machine6 = 32;
const byte Machine7 = 34;
const byte Machine8 = 36;
unsigned long BlowerStartTime;
unsigned long BlowerStopTime;
int onTime = 1 ; // seconds
int offTime = 10 ; // seconds
bool BlowerIsRunning = false;
byte CurrentBlower = Machine1;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int currentMenuItem = 0;
int lastState = 0;

void setup()
{
  for (int i = Machine1; i <= Machine8; i += 2)
  {
    pinMode(i, OUTPUT); //set digital I/O pin as output
  }

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
  lcd.print("TREATMENT");
  delay(2000);
  lcd.clear();
  clearPrintTitle();
}

void loop()
{
  mainMenu();
  ManageBlowers();
}

void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0, 0);

  //Check analog values from LCD Keypad Shield
  if (x < 50) {
    //Right
  } else if (x < 250) {
    //Up
    state = 1;
  } else if (x < 450) {
    //Down
    state = 2;
  } else if (x < 650) {
    //Left
  } else if (x < 850) {
    //Select
    state = 3;
  }

  //If we are out of bounds on the menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
    currentMenuItem = 0;
  }

  //If we have changed Index, saves re-draws.
  if (state != lastState) {
    if (state == 3) {
      //If Up
      currentMenuItem = currentMenuItem + 1;
      displayMenu(currentMenuItem);
//    } else if (state == 2) {
//      //If Down
//      currentMenuItem = currentMenuItem + 1;
//      displayMenu(currentMenuItem);
//    } else if (state == 3) {
//      //If Selected
//      selectMenu(currentMenuItem);
    }
    //Save the last State to compare.
    lastState = state;
  }
  //Small delay
  //  delay(5);
}

//Display Menu Option based on Index.
void displayMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print("D:"); // Delay time
      lcd.print(offTime);
      lcd.print("s");
      lcd.setCursor(11, 1);
      lcd.print("B:"); // Blow time
      lcd.print(onTime);
      lcd.print("s");
      //Call the function that belongs to Option 1
      break;
    case 2:
      clearPrintTitle();
      void DisplayDaysOn();
      lcd.setCursor(0, 1);
      lcd.print("DaysOn:");
      lcd.print(millis() / 864000000UL);
      //Call the function that belongs to Option 2
      break;
    case 3:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("OffDelay=");
      lcd.print (offTime);
      lcd.print ("s");
      //Call the function that belongs to Option 3
      break;
    case 4:
      clearPrintTitle();
      lcd.setCursor(0, 1);
      lcd.print ("OnDelay=");
      lcd.print (onTime);
      lcd.print ("s");
      //Call the function that belongs to Option 4
      break;
  }
}

//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CHINCO FIRESIDE");
  lcd.setCursor(0, 1);
}


void ManageBlowers()
{
  if (BlowerIsRunning)
  {
    if (millis() - BlowerStartTime > onTime * 1000UL)
    {
      StopBlower(CurrentBlower);
      CurrentBlower += 2;
      if (CurrentBlower > Machine8)
        CurrentBlower = Machine1;
    }
  }
  else
  {
    if (millis() - BlowerStopTime > offTime * 1000UL)
    {
      StartBlower(CurrentBlower);
    }
  }
}



void StopBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, LOW);
  BlowerIsRunning = false;
  BlowerStopTime = millis();
}

void StartBlower(int BlowerPin)
{
  digitalWrite(BlowerPin, HIGH);
  BlowerIsRunning = true;
  BlowerStartTime = millis();
  lcd.setCursor(13, 1);
  lcd.print("AP");
  lcd.print((BlowerPin - Machine1) / 2 + 1);
  lcd.setCursor(0, 0);
}