Return GPIO state to Low after delay of 2 seconds(NOT BLINKING)

Hi,
I have spent quite some time looking for a solution.
I am using Particle along with RPI and Google Home Mini.

I can turn LED on with my voice - But I have to also tell GA to turn LED off.

My problem is that I am using this option to open gates using a relay and I need the GPIO pin to
return to original status.

What I have so far... this require for 2 command open followed by a close command.

Would really appreciate any help

int relay = D0; //pin to which relay is connected
int boardLed = D7;
bool vin = LOW; //a virtual boolean variable

// setup() is run only once, it's where we set up GPIO and initialise peripherals
void setup() {

// Setup GPIO
pinMode(relay,OUTPUT); // relay pin is set as output
digitalWrite(relay,HIGH);
// Subscribe to events published by IFTTT using Particle.subscribe
Particle.subscribe("Unique_Event_Name", myHandler); //turning off function declaration
Particle.subscribe("Unique_Event_Name2", thisHandler); //turning on function declaration
}

// loop() runs continuously, it's our infinite loop.
void loop() {
if (vin==HIGH)
{
digitalWrite(relay,LOW);
}
else if (vin==LOW)
{
digitalWrite(relay,HIGH);
}

}

//our events are called when IFTTT applets are triggered
void myHandler(const char *event, const char *data)
{
vin=LOW;
}
void thisHandler(const char *event, const char *data)
{
vin=HIGH;
}

Do you want the pin to go LOW 2 seconds after it goes HIGH ?

If so, then when you set it HIGH save the current value of millis() and set a boolean to true. Then in loop() if the boolean is true and the current value of millis() - start time >= 2000 set the output LOW and the boolean to false.

Thanks for replying. Maybe doing this wrong. Can you please point me in direction of what you suggested.
I think it makes sense but above my pay grade.

Thank you for your time
Seán

Maybe doing this wrong

Post what you tried

Actually not live at the moment. In my parents. But Was looking up what you suggested.
I can’t figure how to bring both Millie and boolean together as yet

Thanks again really appreciate it

Hi UKHeliBob,

Im back at it... heres what I have since we talked.

int relay = D0; //pin to which relay is connected
int boardLed = D7;
bool vin = LOW; //a virtual boolean variable

// setup() is run only once, it's where we set up GPIO and initialise peripherals
void setup() {

// Setup GPIO
pinMode(relay,OUTPUT); // relay pin is set as output
//digitalWrite(relay,HIGH);
// Subscribe to events published by IFTTT using Particle.subscribe
Particle.subscribe("gate_open", myHandler); //turning off function declaration

// loop() runs continuously, it's our infinite loop.//void loop()

if(vin=HIGH)
{
digitalWrite(relay,LOW);
delay(5000);
digitalWrite(relay,HIGH);
}
//else if (vin==LOW)
// {
// digitalWrite(relay,HIGH);
//}
}

//our events are called when IFTTT applets are triggered

void thisHandler(const char *event, const char *data)
{
vin=HIGH;
}

  if (vin = HIGH)

Whoops !

I didn't look any further

Going back to the original code…

If I change

//our events are called when IFTTT applets are triggered
void myHandler(const char *event, const char *data)
{
    // vin=LOW;
    vin = millis() - 1;
}
void thisHandler(const char *event, const char *data)
{
     // vin=HIGH;
    vin = millis() + 2000;
}

You would also need to change declaration of vin to a unassigned long type.

So loop should now be looking to see if current milliseconds - vin <= 0.

Once triggered, vin will be set 2 seconds ahead of current time so the if statement will be true and you should set you output to on.

If nothing else happens, after 2000 milliseconds pass, millis() will be bigger than vin and your if statement should then set the output to off.

By leaving the “voice off” function in and setting it to 1 less than current millis(), you can stop the cycle before 2 seconds.

Don’t ask me to write out the actual rest of code, use the “Using Millis() thread” above to see how the code should look.

Hi Slumpert & UKHeliBob,
i really appreciate you taking the time to help me on this… I just seem to be stuck at present.

Can you pls have a look at my code now, I feel that I am very close but no matter what variations I am hitting a wall.

int relay = D0; //pin to which relay is connected
int boardLed = D7;
//bool vin = LOW; //a virtual boolean variable

unsigned long vin;
//unsigned long currentMillis;

unsigned long currentMillis;

// setup() is run only once, it’s where we set up GPIO and initialise peripherals
void setup() {

// Setup GPIO
pinMode(relay,OUTPUT); // relay pin is set as output

digitalWrite(relay,HIGH);
// Subscribe to events published by IFTTT using Particle.subscribe
Particle.subscribe(“gate_closed”, myHandler); //turning off function declaration
Particle.subscribe(“gate_open”, thisHandler); //turning on function declaration
}

// loop() runs continuously, it’s our infinite loop.
void loop() {

if(currentMillis - vin <= 0)

{
digitalWrite(relay,HIGH);
}
else
{
digitalWrite(relay,LOW);
}

}

//our events are called when IFTTT applets are triggered
void myHandler(const char *event, const char *data)
{
// vin=LOW;
vin = millis() - 1;
}
void thisHandler(const char *event, const char *data)
{
// vin=HIGH;
vin = millis() + 2000;
}

Just a hint - to get more help, faster - USE CODE TAGS
How to post code is explained at the top of every forum section.
LIKE THIS

int relay = D0; //pin to which relay is connected
int boardLed = D7;
//bool vin = LOW; //a virtual boolean variable

unsigned long vin;
//unsigned long currentMillis;

unsigned long currentMillis;




// setup() is run only once, it's where we set up GPIO and initialise peripherals
void setup() {
    
  // Setup GPIO
  pinMode(relay,OUTPUT); // relay pin is set as output
  
  digitalWrite(relay,HIGH);
  // Subscribe to events published by IFTTT using Particle.subscribe
  Particle.subscribe("gate_closed", myHandler); //turning off function declaration
  Particle.subscribe("gate_open", thisHandler); //turning on function declaration
}

// loop() runs continuously, it's our infinite loop.
void loop() {

        if(currentMillis - vin <= 0)
  
     {
        digitalWrite(relay,HIGH);
     }
else  
    {
        digitalWrite(relay,LOW);
     }

}

//our events are called when IFTTT applets are triggered
void myHandler(const char *event, const char *data)
{
   // vin=LOW;
   vin = millis() - 1;
}
void thisHandler(const char *event, const char *data)
{
    // vin=HIGH;
   vin = millis() + 2000;
}

You seem to be using millis() as a timing method in a very odd way. The principle is easy

Save the millis() value at the time that the start action happens. Then, each time through loop(), check whether the required wait period has elapsed by subtracting the start time from the millis() value now. If the period has elapsed then act accordingly If not, then go round loop() again, perhaps taking other actions and/or reading inputs, but don't block the free running of loop().

Have you looked at Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.