It is about controlling 2-no relay contactors based on inputs and feedbacks

Arduino code is working with 2-no. input interrupts in real time instantly.
//C++ code


int buttonPin1 = 2;
int buttonPin2 = 3;
int buttonLED1 = 11;
int buttonLED2 = 12;
int blinkLED = 8;
volatile int buttonState1;
volatile int buttonState2;

void buttonInterrupt() {
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  if (buttonState1 == HIGH && buttonState2==HIGH)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == HIGH && buttonState2==LOW)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, HIGH);
  }
  else if(buttonState1 == LOW && buttonState2==HIGH)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == LOW && buttonState2==LOW)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, HIGH);
  }
}

void setup() {
  pinMode(buttonPin1,INPUT_PULLUP);
  pinMode(buttonPin2,INPUT_PULLUP);
  pinMode(buttonLED1,OUTPUT);
  pinMode(buttonLED2,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(buttonPin1),buttonInterrupt,CHANGE);
  attachInterrupt(digitalPinToInterrupt(buttonPin2),buttonInterrupt,CHANGE);
}

void loop() {
  digitalWrite(blinkLED, HIGH);
  delay(200);
  digitalWrite(blinkLED, LOW);
  delay(200);
}
'''
When there are more than 2-no input interrupts, the outputs are not correct and instant(correct output will come after pressing reset button).
'''
int buttonPin1 = 2
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonLED1 = 11;
int buttonLED2 = 12;
int blinkLED = 8;
volatile int buttonState1;
volatile int buttonState2;
volatile int buttonState3;

void buttonInterrupt() {
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  if (buttonState1 == LOW && buttonState2==LOW && buttonState3==LOW)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == LOW && buttonState2==LOW && buttonState3==HIGH)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, HIGH);
  }
  else if(buttonState1 == LOW && buttonState2==HIGH&& buttonState3==LOW)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == LOW && buttonState2==HIGH && buttonState3==HIGH)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, HIGH);
  }
  else if (buttonState1 == HIGH && buttonState2==LOW && buttonState3==LOW)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == HIGH && buttonState2==LOW && buttonState3==HIGH)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, HIGH);
  }
  else if(buttonState1 == HIGH && buttonState2==HIGH&& buttonState3==LOW)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == HIGH && buttonState2==HIGH && buttonState3==HIGH)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, HIGH);
  }
}

void setup() {
  pinMode(buttonPin1,INPUT_PULLUP);
  pinMode(buttonPin2,INPUT_PULLUP);
  pinMode(buttonPin3,INPUT_PULLUP);
  pinMode(buttonLED1,OUTPUT);
  pinMode(buttonLED2,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(buttonPin1),buttonInterrupt,CHANGE);
  attachInterrupt(digitalPinToInterrupt(buttonPin2),buttonInterrupt,CHANGE);
  attachInterrupt(digitalPinToInterrupt(buttonPin2),buttonInterrupt,CHANGE);
}

void loop() {
  digitalWrite(blinkLED, HIGH);
  delay(200);
  digitalWrite(blinkLED, LOW);
  delay(200);
}

Is it possible to work with more than 2-no inputs with Arduino in real time. Please help.

Welcome to the forum

Thank you for trying to use code tags but you failed. I have fixed them for you

In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

Hello nagrajk

Welcome to the best Arduino forum ever :slight_smile:

What is the task of the sketch in real life?

Why double attachInterrupt for button 2?

I do not see any relays, but for your first program... in this function...

You could also try substitution or combining commands like this...

void buttonInterrupt() {
  digitalWrite(buttonLED1, !digitalRead(buttonPin1)); // write LED1 as the inverse of buttonPin1
  digitalWrite(buttonLED2, !digitalRead(buttonPin2)); // write LED2 as the inverse of buttonPin2
}

And continue using more buttons and LEDs.

Kindly treat buttonLEDs as relays. There is no difference as far as output commands are concerned.

  • As always, show us a good schematic of your proposed circuit. Hand drawn schematics are acceptable.
  • Show us good images of your ‘actual’ wiring.
  • Give WEB links to your major components.

_________________________________________________________________________

  • Avoid using interrupts, they are meant for fast events.

  • You need to look into contact bounce situations and how it can affect things.

  • Just pole your switches every 15ms.

Which Arduino are you using?
Depending on the Arduino you can make any pin an interrupt pin by using interrupt on pin change feature.

Iam using Arduino Uno R3. How to make use of interrupt on pin change feature? Can you Kindly post an example?

  • Why do you need to use interrupts in this project ?

There are total 13-no real time inputs and feedbacks based on which the 2-no. outputs should operate.

  • Please confirm, you will have 13 digital inputs connected to N.O. (normally open) contacts and 2 digital outputs ?

@LarryD My interpretation:

  • "13 ... buttons (inputs) AND ... relays (feedback) based on previous sketch buttons/relays."
  • Your brain works far better than mine :woozy_face:

hhahhaaha. not possible.

  if (buttonState1 == LOW && buttonState2==LOW && buttonState3==LOW)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == LOW && buttonState2==LOW && buttonState3==HIGH)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, HIGH);
  }
  else if(buttonState1 == LOW && buttonState2==HIGH&& buttonState3==LOW)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == LOW && buttonState2==HIGH && buttonState3==HIGH)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, HIGH);
  }
  else if (buttonState1 == HIGH && buttonState2==LOW && buttonState3==LOW)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == HIGH && buttonState2==LOW && buttonState3==HIGH)
  {digitalWrite(buttonLED1, LOW);
   digitalWrite(buttonLED2, HIGH);
  }
  else if(buttonState1 == HIGH && buttonState2==HIGH&& buttonState3==LOW)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, LOW);
  }
  else if(buttonState1 == HIGH && buttonState2==HIGH && buttonState3==HIGH)
  {digitalWrite(buttonLED1, HIGH);
   digitalWrite(buttonLED2, HIGH);
  }
  }
  • OP, do you realize the above can be broken down to what's written below ?
    When buttonState3 is HIGH, turn on buttonLED2
    When buttonState2 is HIGH, turn on buttonLED1

Yes, but I have given above code as example to work on Arduino with more than 2-no. Interrupts. Just illustration.

  • Please be a bit more forthcoming with the information.

  • Below is one way of doing this without interrupts:



//
//                                        Relay Contactors
//================================================^================================================
//                                    T o p   O f   S k e t c h
//
//
//  https://forum.arduino.cc/t/it-is-about-controlling-2-no-relay-contactors-based-on-inputs-and-feedbacks/1274658
//
//  HLD
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ========================================================================
//  1.00       24/06/23    Started writing sketch


//                                           M A C R O S
//================================================^================================================
#define LEDon              HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff             LOW

#define PRESSED            LOW    //+5V---[Internal 50k]---PIN---[Switch]---GND
#define RELEASED           HIGH

#define CLOSED             HIGH    
#define OPENED             LOW

#define ENABLED            true
#define DISABLED           false


//========================================================================  <-------<<<<<<<
//these macros are used for debug purposes
//
//comment next line to stop printing to the Serial Monitor,
//#define DEBUG

//debug Macros
//========================
#ifdef  DEBUG
#define SERIALBEGIN(...)    Serial.begin(__VA_ARGS__)

#define DPRINT(...)         Serial.print(__VA_ARGS__)
#define DPRINTLN(...)       Serial.println(__VA_ARGS__)

#define DPRINTF(...)        Serial.print(F(__VA_ARGS__))   //for text only, using the F macro
#define DPRINTLNF(...)      Serial.println(F(__VA_ARGS__)) //for text only, using the F macro plus new line

#else
#define SERIALBEGIN(...)

#define DPRINT(...)
#define DPRINTLN(...)

#define DPRINTF(...)
#define DPRINTLNF(...)
#endif

//Arduino UNO, produce a 62ns pulse on D13
#define PULSE62Heartbeat   cli(); PINB = bit(PINB5); PINB = bit(PINB5); sei()
//Example:  PULSE62Heartbeat;


//                                            G P I O s
//================================================^================================================
//
//a structure to define input objects, switches or sensors
struct makeInput
{
  const byte pin;                  //the digital input pin number
  unsigned long switchTime;        //the time the switch was closed
  byte lastState;                  //the state the input was last in
  byte counter;                    //a counter used to validate a switch change in state
}; //END of   struct makeInput

const byte inputPins[]           = {2, 3, 4};

//Digital Inputs
//define the input connected to a PB switch

//========================
makeInput buttonPin1 =
{
  2, 0, OPENED, 0                  //pin, switchTime, lastState, counter
};

//========================
makeInput buttonPin2 =
{
  3, 0, OPENED, 0                  //pin, switchTime, lastState, counter
};

//========================
makeInput buttonPin3 =
{
  4, 0, OPENED, 0                  //pin, switchTime, lastState, counter
};



//========================
byte filter                      = 10;
//TIMER "switches" runs every 5ms.
//5ms * 10 = 50ms is needed to validate a switch change in state.
//A switch change in state is valid "only after" 10 identical changes are detected.
//This is used to filter out EMI noise in the system


//OUTPUTS
//===================================
const byte outputPins[]          = {11, 12, 8};

const byte buttonLED1            = 11;
const byte buttonLED2            = 12;
const byte blinkLED              = 8;

//                                        V A R I A B L E S
//================================================^================================================
//



//================================================^================================================
//                          millis() / micros()   B a s e d   T I M E R S
//================================================^================================================
//TIMER objects are non-blocking
struct makeTIMER
{
#define MILLIS             1
#define MICROS             1000    //we can use this value to divide into a variable to get milliseconds

#define ENABLED            true
#define DISABLED           false

#define YES                true
#define NO                 false

#define STILLtiming        0
#define EXPIRED            1
#define TIMERdisabled      2

  //these are the bare minimum "members" needed when defining a TIMER
  int                      TimerType;      //what kind of TIMER is this? MILLIS/MICROS
  unsigned long            Time;           //when the TIMER started
  unsigned long            Interval;       //delay time which we are looking for
  bool                     TimerFlag;      //is the TIMER enabled ? ENABLED/DISABLED
  bool                     Restart;        //do we restart this TIMER   ? YES/NO

  //================================================
  //condition returned: STILLtiming (0), EXPIRED (1) or TIMERdisabled (2)
  //function to check the state of our TIMER  ex: if(myTimer.checkTIMER() == EXPIRED);
  byte checkTIMER()
  {
    //========================
    //is this TIMER enabled ?
    if (TimerFlag == ENABLED)
    {
      //========================
      //has this TIMER expired ?
      if (getTime() - Time >= Interval)
      {
        //========================
        //should this TIMER restart again?
        if (Restart == YES)
        {
          //restart this TIMER
          Time = getTime();
        }

        //this TIMER has expired
        return EXPIRED;
      }

      //========================
      else
      {
        //this TIMER has not expired
        return STILLtiming;
      }

    } //END of   if (TimerFlag == ENABLED)

    //========================
    else
    {
      //this TIMER is disabled
      return TIMERdisabled;
    }

  } //END of   checkTime()

  //================================================
  //function to enable and restart this TIMER  ex: myTimer.enableRestartTIMER();
  void enableRestartTIMER()
  {
    TimerFlag = ENABLED;

    //restart this TIMER
    Time = getTime();

  } //END of   enableRestartTIMER()

  //================================================
  //function to disable this TIMER  ex: myTimer.disableTIMER();
  void disableTIMER()
  {
    TimerFlag = DISABLED;

  } //END of    disableTIMER()

  //================================================
  //function to restart this TIMER  ex: myTimer.restartTIMER();
  void restartTIMER()
  {
    Time = getTime();

  } //END of    restartTIMER()

  //================================================
  //function to force this TIMER to expire ex: myTimer.expireTimer();
  void expireTimer()
  {
    //force this TIMER to expire
    Time = getTime() - Interval;

  } //END of   expireTimer()

  //================================================
  //function to set the Interval for this TIMER ex: myTimer.setInterval(100);
  void setInterval(unsigned long value)
  {
    //set the Interval
    Interval = value;

  } //END of   setInterval()

  //================================================
  //function to return the current time
  unsigned long getTime()
  {
    //return the time             i.e. millis() or micros()
    //========================
    if (TimerType == MILLIS)
    {
      return millis();
    }

    //========================
    else
    {
      return micros();
    }

  } //END of   getTime()

}; //END of   struct makeTIMER


//                             D e f i n e   a l l   t h e   T I M E R S
//================================================^================================================
/*example
  //========================
  makeTIMER toggleLED =
  {
     MILLIS/MICROS, 0, 500ul, ENABLED/DISABLED, YES/NO  //.TimerType, .Time, .Interval, .TimerFlag, .Restart
  };

  Functions we can access:
  toggleLED.checkTIMER();
  toggleLED.enableRestartTIMER();
  toggleLED.disableTIMER();
  toggleLED.expireTimer();
  toggleLED.setInterval(100ul);
*/

//========================
makeTIMER heartbeatTIMER =
{
  MILLIS, 0, 200ul, ENABLED, YES        //.TimerType, .Time, .Interval, .TimerFlag, .Restart
};

//========================
makeTIMER switchesTIMER =
{
  MILLIS, 0, 5ul, ENABLED, YES          //.TimerType, .Time, .Interval, .TimerFlag, .Restart
};

//========================
makeTIMER machineTIMER =
{
  MILLIS, 0, 10ul, ENABLED, YES         //.TimerType, .Time, .Interval, .TimerFlag, .Restart
};


//                                          s e t u p ( )
//================================================^================================================
//
void setup()
{
  //this delay prevents setup() from running twice when we use the serial monitor
  //remove this delay() if the serial monitor is not used.
  delay(1000);

  SERIALBEGIN(115200);

  //Inputs
  //======================
  //use INPUT_PULLUP so the pin does not float, floating pins can cause faulty readings
  //configure the input pins
  for (byte x = 0; x < sizeof(inputPins); x++)
  {
    pinMode(inputPins[x], INPUT_PULLUP);
  }

  //Outputs
  //======================
  //configure the output pins
  for (byte x = 0; x < sizeof(outputPins); x++)
  {
    digitalWrite(outputPins[x], LEDoff);
    pinMode(outputPins[x], OUTPUT);
  }

} //END of   setup()


//                                            l o o p ( )
//================================================^================================================
//
void loop()
{
  //========================================================================  T I M E R  heartbeat
  //condition returned: STILLtiming, EXPIRED or TIMERdisabled
  //if the TIMER is enabled, is it time to toggle the heartbeat LED ?
  if (heartbeatTIMER.checkTIMER() == EXPIRED)
  {
    //when this TIMER expires, toggle the heartbeat LED
    //this LED is a rudimentary way of displaying if the sketch code is blocking or stuttering

    //toggle the heartbeat LED
    digitalWrite(blinkLED, digitalRead(blinkLED) == HIGH ? LOW : HIGH);

  } //END of this   TIMER

  //========================================================================  T I M E R  switches
  //condition returned: STILLtiming, EXPIRED or TIMERdisabled
  //if the TIMER is enabled, is it time to check our switches ?
  if (switchesTIMER.checkTIMER() == EXPIRED)
  {
    //when this TIMER expires, check if any switch/sensor has changed state

    checkSwitches();

  } //END of this   TIMER

  //========================================================================  T I M E R  machine
  //condition returned: STILLtiming, EXPIRED or TIMERdisabled
  //if the TIMER is enabled, is it time to service our State Machines ?
  if (machineTIMER.checkTIMER() == EXPIRED)
  {
    //check all the "State Machines"
    checkMachines();

  } //END of this   TIMER


  //=========================================
  //other none blocking code goes here
  //=========================================


} //END of    loop()


//                                   c h e c k S w i t c h e s ( )
//================================================^================================================
//
void checkSwitches()
{
  byte currentState;

  //========================================================================  buttonPin1.pin
  currentState = digitalRead(buttonPin1.pin);

  //===================================
  //has this switch changed state ?
  if (buttonPin1.lastState != currentState)
  {
    buttonPin1.counter++;

    //is this change in state stable ?
    if (buttonPin1.counter >= filter)
    {
      //get ready for the next sequence
      buttonPin1.counter = 0;

      //update to this new state
      buttonPin1.lastState = currentState;

      //================================================  buttonPin1  CLOSED ?
      //did this switch close ?
      if (currentState == CLOSED)
      {
        DPRINTLNF("buttonPin1 switch closed");

        //the time the switch went closed
        buttonPin1.switchTime = millis();

      }

      //========================
      //did this switch open ?
      else if (currentState == OPENED)
      {
        DPRINTLNF("buttonPin1 switch opened");
      }
    }
  }

  //a valid switch change has not been confirmed
  else
  {
    buttonPin1.counter = 0;
  }

  //END of   buttonPin1.pin

  //========================================================================  buttonPin2.pin
  currentState = digitalRead(buttonPin2.pin);

  //===================================
  //has this switch changed state ?
  if (buttonPin2.lastState != currentState)
  {
    buttonPin2.counter++;

    //is this change in state stable ?
    if (buttonPin2.counter >= filter)
    {
      //get ready for the next sequence
      buttonPin2.counter = 0;

      //update to this new state
      buttonPin2.lastState = currentState;

      //================================================  buttonPin2  CLOSED ?
      //did this switch close ?
      if (currentState == CLOSED)
      {
        DPRINTLNF("buttonPin2 switch closed");

        //the time the switch went closed
        buttonPin2.switchTime = millis();

      }

      //========================
      //did this switch open ?
      else if (currentState == OPENED)
      {
        DPRINTLNF("buttonPin2 switch opened");
      }
    }
  }

  //a valid switch change has not been confirmed
  else
  {
    buttonPin2.counter = 0;
  }

  //END of   buttonPin2.pin

  //========================================================================  buttonPin3.pin
  currentState = digitalRead(buttonPin3.pin);

  //===================================
  //has this switch changed state ?
  if (buttonPin3.lastState != currentState)
  {
    buttonPin3.counter++;

    //is this change in state stable ?
    if (buttonPin3.counter >= filter)
    {
      //get ready for the next sequence
      buttonPin3.counter = 0;

      //update to this new state
      buttonPin3.lastState = currentState;

      //================================================  buttonPin3  CLOSED ?
      //did this switch close ?
      if (currentState == CLOSED)
      {
        DPRINTLNF("buttonPin3 switch closed");

        //the time the switch went closed
        buttonPin3.switchTime = millis();

      }

      //========================
      //did this switch open ?
      else if (currentState == OPENED)
      {
        DPRINTLNF("buttonPin3 switch opened");
      }
    }
  }

  //a valid switch change has not been confirmed
  else
  {
    buttonPin3.counter = 0;
  }

  //END of   buttonPin3.pin
  //===================================

} //END of   checkSwitches()


//                                   c h e c k M a c h i n e s ( )
//================================================^================================================
//
void checkMachines()
{
  //assemble the one of 8 possible input combinations
  byte switchState = buttonPin1.lastState;
  switchState = (switchState << 1) + buttonPin2.lastState;
  switchState = (switchState << 1) + buttonPin3.lastState;
  
  //DPRINTF("State = ");
  //DPRINTLN(switchState);
  
  //========================================================================  switch   State Machine
  switch (switchState)
  {
    //==========================
    case 0:
      {
        digitalWrite(buttonLED1, LEDoff);
        digitalWrite(buttonLED2, LEDoff);
      }
      break;

    //==========================
    case 1:
      {
        digitalWrite(buttonLED1, LEDoff);
        digitalWrite(buttonLED2, LEDon);
      }
      break;

    //==========================
    case 2:
      {
        digitalWrite(buttonLED1, LEDon);
        digitalWrite(buttonLED2, LEDoff);
      }
      break;

    //==========================
    case 3:
      {
        digitalWrite(buttonLED1, LEDon);
        digitalWrite(buttonLED2, LEDon);
      }
      break;

    //==========================
    case 4:
      {
        digitalWrite(buttonLED1, LEDoff);
        digitalWrite(buttonLED2, LEDoff);
      }
      break;

    //==========================
    case 5:
      {
        digitalWrite(buttonLED1, LEDoff);
        digitalWrite(buttonLED2, LEDon);
      }
      break;

    //==========================
    case 6:
      {
        digitalWrite(buttonLED1, LEDon);
        digitalWrite(buttonLED2, LEDoff);
      }
      break;

    //==========================
    case 7:
      {
        digitalWrite(buttonLED1, LEDon);
        digitalWrite(buttonLED2, LEDon);
      }
      break;

  } //END of   switch/case

} //END of   checkMachines()


//
//================================================^================================================
//


  • We really need to see a schematic of the final project.

I offered this to replace all the statements.

Also... it looks like all the relays, microcontrollers and code can be replaced by 13 SPST SPDT switches.

  • We are lacking some involvement.