Problem facing with simultaneous operation

Hi,

I am using arduino mega 2560 to drive two set of relays using two push buttons.I want to operate two push buttons independently.Here if i press push button1 ,the first "if"statements cycle start but mean while if i press push button 2,the second "if"statements cycle won't starts until the first cycle completes.So i need to operate two push buttons independently.So plz suggest me to to add codes in between to operate two cycles independently.

const int button1Pin = 30; const int button2Pin = 31; const int relay1Pin = 32; const int relay2Pin = 34; const int relay3Pin = 36; const int relay4Pin = 38; const int relay5Pin = 33; const int relay6Pin = 35; const int relay7Pin = 37; const int relay8Pin = 39;

int button1State = 0; int button2State = 0;

void setup() { pinMode(button1Pin, INPUT); pinMode(button2Pin, INPUT); pinMode(relay1Pin, OUTPUT); pinMode(relay2Pin, OUTPUT); pinMode(relay3Pin, OUTPUT); pinMode(relay4Pin, OUTPUT); pinMode(relay5Pin, OUTPUT); pinMode(relay6Pin, OUTPUT); pinMode(relay7Pin, OUTPUT); pinMode(relay8Pin, OUTPUT);

}

void loop() { button1State = digitalRead(button1Pin); button2State = digitalRead(button2Pin); if (button1State == HIGH) { digitalWrite(relay1Pin, HIGH); delay(15000); digitalWrite(relay2Pin, HIGH); delay(3000); digitalWrite(relay3Pin, HIGH); delay(5000); digitalWrite(relay3Pin, LOW); delay(1000); digitalWrite(relay2Pin, LOW); delay(1000); digitalWrite(relay1Pin, LOW);

} if (button2State == HIGH) { digitalWrite(relay5Pin, HIGH); delay(15000); digitalWrite(relay6Pin, HIGH); delay(3000); digitalWrite(relay7Pin, HIGH); delay(5000); digitalWrite(relay7Pin, LOW); delay(1000); digitalWrite(relay6Pin, LOW); delay(1000); digitalWrite(relay5Pin, LOW);

} }

Start here:

https://forum.arduino.cc/index.php?topic=223286.0

its too difficult to understand.Is there any simple way to execute two different if statements independently using any statements??

shashimech2012: its too difficult to understand.Is there any simple way to execute two different if statements independently using any statements??

The main thing to take away from Paul's example is that you cannot use delay() to control timings in a program where you need to control several things independently. As you've already discovered, while it's in a delay() it can't manage the other task.

So you need to move away from using delay() and look at polling the run time counter, millis(), instead. In other words you have to keep your main loop ticking over at all times and just keep polling the state of millis() to work out when tasks need to happen (outputs need switching on/off etc).

Please edit your post and embed your code in [code] and [/code].

Below a description / guide how to approach; please read the explanations to understand how to approach it (or how I would approach it).

The big trick is to split every 'block' into smaller pieces and not use delay() but a millis() based timing.

First step is to create two functions and call them from loop when needed. The name of the function should represent what it does (I did not do that in below).

For button1

void action1()
{
  digitalWrite(relay1Pin, HIGH);
  delay(15000);
  digitalWrite(relay2Pin, HIGH);
  delay(3000);
  digitalWrite(relay3Pin, HIGH);
  delay(5000);
  digitalWrite(relay3Pin, LOW);
  delay(1000);
  digitalWrite(relay2Pin, LOW);
  delay(1000);
  digitalWrite(relay1Pin, LOW);
}

void action2()
{
  ...
  ...
}

void loop()
{
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  if (button1State == HIGH)
  {
    action1();
  }
  if (button2State == HIGH)
  {
    action2();
  }
}

You can see how nice and tidy (small) loop is; it keeps your code readable.

Next you break the 'actions' into smaller pieces; we will use a so-called statemachine. Both action functions consist of a number of steps (states). E.g. (for action1) a state where relay1Pin is high for a given time, a state where relayPin2 is high for a given time etc.

void action1()
{
  // current state
  static byte currentState = 0;

  switch (currentState)
  {
    case 0:
      digitalWrite(relay1Pin, HIGH);
      delay(15000);
      currentState++;
      break;
    case 1:
      digitalWrite(relay2Pin, HIGH);
      delay(3000);
      currentState++;
      break;
    case 2:
      digitalWrite(relay3Pin, HIGH);
      delay(5000);
      currentState++;
      break;
    case 3:
      digitalWrite(relay3Pin, LOW);
      delay(1000);
      currentState++;
      break;
    case 4:
      digitalWrite(relay2Pin, LOW);
      delay(1000);
      currentState++;
      break;
    case 5:
      digitalWrite(relay1Pin, LOW);
      currentState = 0;
      break;
  }
}

The initial value for the currentState is 0, so the first time the function action1 is called, it will execute the associated case. So switch a relay on and wait. Next the currentState is updated and the function returns to loop(). In loop() a new check for the buttonState is done and if it's high action1() is called again, but currentState is now 1 and hence the code for that state is executed. Note that due to the use of the 'static' keyword, the currentState variable will be remembered between calls to action1().

For the last step, the currentState is set back to 0 so a new call to actionX will result in the first step / state / case being executed again.

As long as you keep the button pressed, this will do exactly the same as your original code and will still block. If you release the button, the process will stop after the current delay has lapsed and continue when the button is pressed again.

Next we will write functions for every state; this keeps the switch tidy.

/*
  execute step 0 of action 1 (statemachine 1)
  returns:
    true if the step is completed (no else yet)
*/
bool action1_step0()
{
  digitalWrite(relay1Pin, HIGH);
  delay(15000);
  return true;
}

And call them from actionX(); again, use sensible names.

void action1()
{
  // current state
  static byte currentState = 0;


  switch (currentState)
  {
    case 0:
      action1_step0();
      currentState++;
      break;
    case 1:
      ...
      ...

Use sensible names for your functions !

And finally you can get rid of delay. Add a static variable to each actionX_stepY

/*
  execute step 0 of action 1 (statemachine 1)
  returns:
    true if the step is completed, else false
*/
bool action1_step0()
{
  // start time of the delay
  static unsigned long delayStartTime = 0;
  // if delay not started yet
  if (delayStartTime == 0)
  {
    // switch relay on (or off, whatever HIGH means)
    digitalWrite(relay1Pin, HIGH);
    // set the start time of the delay
    delayStartTime = millis();
  }
  // check if delay has lapsed
  if(millis() - delayStartTime >= 15000)
  {
    // reset the start time
    delayStartTime = 0;
    // indicate that the step is completed
    return true;
  }
  // indicate step is not complete yet
  return false;
}

Be aware that this is a little expensive on memory because each actionX_stepY has its own variable (4 bytes) to remember the delayStartTime. It's the safer approach in my opinion but if needed you can use one global variable for each actionX.

And in the switch

void action1()
{
  // current state
  static byte currentState = 0;

  switch (currentState)
  {
    case 0:
      if (action1_step0() == true)
      {
        // 'go to' the next step / state
        currentState++;
      }
      break;
    case 1:
      ...
      ...

As said; the above will work as long as you keep the button pressed; this is probably not what you want. You can solve that by letting the actionX functions return true when they have completed the sequence.

/*
  action when button1 is pressed
  returns:
    true when sequence completed, else false
*/
bool action1()
{
  // current state
  static byte currentState = 0;

  switch (currentState)
  {
    case 0:
      if (action1_step0() == true)
      {
        // 'go to' the next step / state
        currentState++;
      }
      break;
    case 1:
      ...
      ...
    case 5:
      if (action1_step5() == true)
      {
        // reset the current state for the next time that the button is high
        currentState = 0;
        // indicate that action1 is complete
        return true;
      }
      break;
  }
  // indicate that action1 is in progress
  return false;
}

And in loop() we use two additional flags to remember the status of the actions

void loop()
{
  // flags to indicate if actionX is complete
  // default true
  static bool fAction1Complete = true;
  static bool fAction2Complete = true;

  // if an action is in progress
  if(fAction1Complete == false)
  {
    // continue the action
    fAction1Complete = action1();
  }
  if(fAction2Complete == false)
  {
    // continue the action
    fAction2Complete = action1();
  }

  // read the buttons
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  
  if (button1State == HIGH)
  {
    // set the flag to indicate that action1 needs to be executed (not completed)
    fAction1Complete = false;
  }
  if (button2State == HIGH)
  {
    // set the flag to indicate that action2 needs to be executed (not completed)
    fAction2Complete = false;
  }
}

Note that the button presses do not directly call the actionX functions any longer but set a flag that is checked in loop().

Code not tested (does compile if implemented correctly ;) )

Thanks a lot for explaining but basically i am not a electronics guy.And i am new to this field so since after reading your suggestion, i am in dilemma with final conclusion of writing codes.So if you don't mind can you plz suggest me the final codes??

shashimech2012: Thanks a lot for explaining but basically i am not a electronics guy.And i am new to this field so since after reading your suggestion, i am in dilemma with final conclusion of writing codes.So if you don't mind can you plz suggest me the final codes??

The solution to your code problem is not the electronics, its the programming. Can you tell us your electronics, programming, arduino, hardware experience? The machine from the looks of the nameplate, looks like a commercially assembled unit where is their programmer?

Tom.... :)

You need to learn about state machines and event-driven programming - powerful techniques and ideas.

If you're a n a hurry, perhaps dig in your pocket, and head over to gigs and collaborations. The project isn't all that complicated from what you've explained so far - but it needs more skills than you have at the moment.

Before you post your collaboration request, i'd suggest you draw up your electro-mechanical block diagram, and a (more logical) explanation of operation.

$ can solve many things! P.S. don't cross-post!

Hi Shashimech,

Are you trying to get something to work quickly, or are you a newbie trying to learn? Our answers will vary depending on your answer. This forum is full of folks who are willing to help you learn and will walk you through the process.

If you’re looking for something quick and really just want someone else to write your code for you, then post a request for paid support over in Gigs and Collaborations.

It sounds to me like electrical interference is causing false presses of your foot switches. How are the switches wired? Since you are not using INPUT_PULLUP you must have an external pull-up or pull-down resistor on each input pin. What value of resistor? Have you tried a lower resistance to decrease the chance of a false closure?