Want to turn on a relay by connecting 2 wires

yes because of this condition and also we defined interval as constant 500ms

if (currentMillis - previousMillis >= interval)

  • Can you see this is happening without the need of using delay( . . . ) ?

  • millis( ) returns the time, in milli seconds, since the Arduino was turned on.

We refer to this technique as BWD (blink without delay).

You can think of this as a non-blocking use of a TIMER based on the millis() function.

yes this make sense

Look at this sketch and see if you follow what is being done.

  • Do you fully understand what is happen in the sketch ?
//********************************************^************************************************
//  https://forum.arduino.cc/t/want-to-turn-on-a-relay-by-connecting-2-open-wires/1171160
//
//  Chandu Mca06
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ====================================================================
//  1.00       23/09/22    Running code
//
//
//

#define LEDon                      HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff                     LOW

#define RELAYon                    LOW
#define RELAYoff                   HIGH

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

#define ENABLED                    true
#define DISABLED                   false


//********************************************^************************************************
//GPIOs

const byte relayPin              = 6;
const byte blueWires             = 7;
const byte redWires              = 8;

const byte heartbeatLED          = 13;

byte lastBlueWires               = OPEN;
byte lastRedWires                = OPEN;

//timing stuff
unsigned long heartbeatTime;
unsigned long scanSwitchesTime;

//********************************************^************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(blueWires, INPUT_PULLUP);
  pinMode(redWires, INPUT_PULLUP);

  pinMode(relayPin, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

  digitalWrite(relayPin, RELAYoff);

} //END of   setup()


//********************************************^************************************************
void loop()
{
  //************************************************              T I M E R  heartbeatLED
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //************************************************              T I M E R  scanSwitches
  //is it time to scan our switches ?
  if (millis() - scanSwitchesTime >= 50ul)
  {
    //restart this TIMER
    scanSwitchesTime = millis();

    scanSwitches();
  }



} //END of   loop()

//********************************************^************************************************
void scanSwitches()
{
  byte state;

  //************************************************              blueWires
  state = digitalRead(blueWires);

  //has this switch changed state ?
  if (lastBlueWires != state)
  {
    //update to this new state
    lastBlueWires = state;

    //*************************************
    //are the wires closed ?
    if (state == CLOSED)
    {
      //do something

    }

  } //END of this switch

  //************************************************              redWires
  state = digitalRead(redWires);

  //has this switch changed state ?
  if (lastRedWires != state)
  {
    //update to this new state
    lastRedWires = state;

    //*************************************
    //are the wires closed ?
    if (state == CLOSED)
    {
      //do something

    }

  } //END of this switch

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

} //END of   checkSwitches()



//********************************************^************************************************

Please use code tags when you post your code.


Important:

  • Do you fully understand how the heartbeatLED is toggling while you can still operate the switches ?

Try this sketch:

  • Do you fully understand what is happening ?
//********************************************^************************************************
//  https://forum.arduino.cc/t/want-to-turn-on-a-relay-by-connecting-2-open-wires/1171160
//
//  Chandu Mca06
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ====================================================================
//  1.00       23/09/22    Running code
//
//
//

#define LEDon                      HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff                     LOW

#define RELAYon                    LOW
#define RELAYoff                   HIGH

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

#define ENABLED                    true
#define DISABLED                   false


//********************************************^************************************************
//GPIOs

const byte relayPin              = 6;
const byte blueWires             = 7;
const byte redWires              = 8;

const byte heartbeatLED          = 13;

bool relayFlag                   = DISABLED;

byte lastBlueWires               = OPEN;
byte lastRedWires                = OPEN;

//timing stuff
unsigned long heartbeatTime;
unsigned long scanSwitchesTime;
unsigned long relayTime;

//unsigned long relayInterval    = 15ul * 60 * 1000; //15 minutes
unsigned long relayInterval      = 10 * 1000; //10 seconds for testing



//********************************************^************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(blueWires, INPUT_PULLUP);
  pinMode(redWires, INPUT_PULLUP);

  pinMode(relayPin, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

  digitalWrite(relayPin, RELAYoff);

} //END of   setup()


//********************************************^************************************************
void loop()
{
  //************************************************              T I M E R  heartbeatLED
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //************************************************              T I M E R  scanSwitches
  //is it time to scan our switches ?
  if (millis() - scanSwitchesTime >= 50ul)
  {
    //restart this TIMER
    scanSwitchesTime = millis();

    scanSwitches();
  }

  //************************************************              T I M E R  relayTiming
  //if enabled, is it time to to turn off the relay ?
  if (relayFlag == ENABLED && millis() - relayTime >= relayInterval)
  {
    //we are finished with this TIMER
    relayFlag = DISABLED;
    
    digitalWrite(relayPin, RELAYoff);
  }



} //END of   loop()

//********************************************^************************************************
void scanSwitches()
{
  byte state;

  //************************************************              blueWires
  state = digitalRead(blueWires);

  //has this switch changed state ?
  if (lastBlueWires != state)
  {
    //update to this new state
    lastBlueWires = state;

    //*************************************
    //are the wires closed ?
    if (state == CLOSED)
    {
      digitalWrite(relayPin, RELAYon);

      //enable the TIMER
      relayFlag = ENABLED;

      //restart the TIMER
      relayTime = millis();
    }

  } //END of this switch

  //************************************************              redWires
  state = digitalRead(redWires);

  //has this switch changed state ?
  if (lastRedWires != state)
  {
    //update to this new state
    lastRedWires = state;

    //*************************************
    //are the wires closed ?
    if (state == CLOSED)
    {
      //do something
    }

  } //END of this switch

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

} //END of   checkSwitches()



//********************************************^************************************************

yes the code block of heartbeat led is independent task

  • Please confirm you know how the relay TIMER is made to work ?

Please reword the below.

  1. I want to turn on the relay if the first set of open wires are connected to each other and turn off the relay if they are disconnected.
  2. once the first set of wires are connected to each other and once the relay is on then the relay should be turned off after 15 minutes , once it turned off it should check if the second set of wires are connected with each other. If yes then immediately turn on the relay and wait for another 15 mins and then turn off the relay and again check for the second set of wires are connected with each other or not.
  3. Repeat the step2 until the second set of wires are completely disconnected with each other. Once it is detected as disconnected then we should terminate the loop and relay should be turned off till power on and off again.

First condition is not working as we didn't mention about relay in the redwires section

  • We are taking things one step at a time.

  • You must fully understand what is happening before we proceed to the next step.

  • Please confirm you know how the relay TIMER is made to work i.e. the relay turns ON when blue wires are connected then at 10 seconds turns OFF ?


This needs to be fleshed out more.

  1. once the first set of wires are connected to each other and once the relay is on then the relay should be turned off after 15 minutes , once it turned off it should check if the second set of wires are connected with each other. If yes then immediately turn on the relay and wait for another 15 mins and then turn off the relay and again check for the second set of wires are connected with each other or not.

In the first step only we are triggering the relay. If the 1st step itself not done then steps 2 and 3 are invalid.

  • Do you fully understand why things are working as they are ?

yes because once relay is triggered then we are doing the following

//enable the TIMER
relayFlag = ENABLED;

  //restart the TIMER
  relayTime = millis();
  • Do you understand how we can use Flags to control the execution of blocks of code ?

yes still need to understand in-depth as I just started :slight_smile:

  • Step 1 is a prerequisite for step 2 and 3.

  • Step 2 only happens once the blue wires are closed and stay closed and after 15 seconds, at which time the relay turns OFF.

  • After the relay TIMER expires, the red wire can be examined.
    When the red wires are closed and stay closed, the relay turns ON, after another 15 seconds, the relay turns OFF, we again check the red wires to see if they are closed, if so, the TIMER restarts, relay turns ON, etc. repeat . . . . .



What happens if the red wires are opened while in the 2nd 15 minute TIMER operation ?

  1. Repeat the step2 until the second set of wires are completely disconnected with each other. Once it is detected as disconnected then we should terminate the loop and relay should be turned off till power on and off again.

More information, be exact.

Hello chandu-mca06

Try, check and fine tune this MonoFlop sketch to your needs:

//https://forum.arduino.cc/t/want-to-turn-on-a-relay-by-connecting-2-open-wires/1171160/59
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "Want to turn on a relay by connecting 2 open wires"
#define NotesOnRelease "1"
// -- some useful text replacements used
#define equ ==
#define nequ !=
#define mod %
#define view(x) Serial.println(x)
// make names
enum Wires {One, Two};
// make variables
constexpr  uint8_t Inputs[] {A0, A1};
constexpr  uint8_t Outputs[] {9, 9};
// make structures
struct TIMER
{
  uint32_t now;
  uint32_t interval;
  uint8_t control;
};
struct MONOFLOP
{
  uint8_t button;
  uint8_t relay;
  uint8_t stateOld;
  TIMER   waitTime;
  TIMER   debounce;
};
MONOFLOP monoFlops[]
{
  {Inputs[One], Outputs[One], LOW, 0, 2000, LOW, 0, 20, LOW},
  {Inputs[Two], Outputs[Two], LOW, 0, 2000, LOW, 0, 20, LOW},
};
// make support
void heartBeat(int LedPin, uint32_t currentMillis)
{
  static bool setUp = false;
  if (!setUp) pinMode (LedPin, OUTPUT), setUp = !setUp;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
// make application
void setup()
{
  Serial.begin(115200);
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  for (auto &monoFlop : monoFlops)
  {
    pinMode(monoFlop.relay, OUTPUT);
    pinMode(monoFlop.button, INPUT_PULLUP);
  }
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  uint32_t currentMillis = millis();
  heartBeat(LED_BUILTIN, currentMillis);
  for (auto &monoFlop : monoFlops)
  {
    if (currentMillis - monoFlop.debounce.now >= monoFlop.debounce.interval)
    {
      monoFlop.debounce.now = currentMillis;
      uint8_t stateNew = digitalRead(monoFlop.button) ? LOW : HIGH;
      if ( monoFlop.stateOld nequ stateNew)
      {
        monoFlop.stateOld = stateNew;
        if (stateNew equ HIGH)
        {
          digitalWrite(monoFlop.relay, HIGH);
          monoFlop.waitTime.control = HIGH;
          monoFlop.waitTime.now = currentMillis;
        }
        else
        {
          digitalWrite(monoFlop.relay, LOW);
          monoFlop.waitTime.control = LOW;
        }
      }
    }
    if (currentMillis - monoFlop.waitTime.now >= monoFlop.waitTime.interval and monoFlop.waitTime.control)
    {
      digitalWrite(monoFlop.relay, LOW);
      monoFlop.waitTime.control = LOW;
    }
  }
}

Have a nice day and enjoy coding in C++.

  • Paul-Paulson has offered a solution, I'll back off unless I am ask questions.

Thank you so much. Will try and update you soon :slight_smile:

Hello Larry