Need to turn an output on for 4 seconds then off

I have an input that when its "on" its always on its not momentary so when i turn the switch on i need to trigger an output for 4 seconds then turn it off - the next step would be when the switch is turned off i need it to trigger 2 outputs for 4.5 seconds. I've completely torn apart my code since i was using the delay and i cannot seem to get this to work properly. so i've isolated it to just when switch is "on" trigger output for 4 seconds - but something is wrong b/c it doesnt work ... there is some other GPS logic in here i'm not using but will be needed for the final product.

Thanks in advance

// NeoGPS - Version: Latest 
#include <NMEAGPS.h>

// NeoSWSerial - Version: Latest 
#include <NeoSWSerial.h>
NeoSWSerial gpsSerial(2,3);
NMEAGPS gps;

////variable declaration

// selection pins on which are connected to the Selector
//int pinsSelectorPosAuto = 28;
//int pinsSelectorPosManu = 29;
const int pinSurfRight = 4;
const int pinSurfLeft = 5;
const int RelayGateRight = 6;
const int RelayGateRetRight = 7;
const int RelayGateLeft = 8;
const int RelayGateRetLeft = 9;
const int AutoPin = 10;
//int relayAlimFeuStar = 33;
//int relayAlimFiresUnderMarin = 34;
//int pinsremotecontrolLight = 35;
//int pinsMaliviewLightTour = 36;
//int pinsMaliviewLightUnderMarin = 37;
//int pinsremotecontrolSurfgate = 39;  // probably a wiring error when the 2 inputs are inverted so that it matches the good buttons on the remotecontrol.
//int pinsremotecontrolCoteSurfgate = 38;  // probably a wiring error when the 2 inputs are inverted so that it matches the good buttons on the remotecontrol.
int SurfRight = 0;
int SurfLeft = 0;
int SurfLeftOn = 0;
int SurfRigthOn = 0;
int SurfLeftDeploy = 0;
int SurfRightDeploy = 0;
bool SurfLeftDeployed = false;
bool SurfRightDeployed = false;
bool speedhigh = false;
bool speedlow = false;
bool Auto = false;
bool LeftDeploying = false;
bool RightDeploying = false;
bool LeftRetracting = false;
bool SetLeftDeploy = false;
bool SetLeftRetract = false; 
unsigned long LeftDeployTime = 0;
unsigned long LeftRetractTime = 0;
unsigned long RightDeployTime = 0;
unsigned long RightRetractTime = 0;
unsigned long time = 0;

void setup() {
  pinMode(pinSurfRight, INPUT_PULLUP);
  pinMode(pinSurfLeft, INPUT_PULLUP);
  pinMode(AutoPin, INPUT_PULLUP);
  gpsSerial.begin(9600);
  delay(1000);
  pinMode(RelayGateRight, OUTPUT);
  pinMode(RelayGateRetRight, OUTPUT);
  pinMode(RelayGateLeft, OUTPUT);
  pinMode(RelayGateRetLeft, OUTPUT);
  

}

void displayGPS( gps_fix & fix )
{
  int mph = 0;
 
  
  // Print speed
  if (fix.valid.speed && (fix.spd.whole > 3)) {
    mph = (fix.spd.whole * 115) / 100;
  }
  Serial.print( mph );
  Serial.print( (" mph      ") );

  if (mph < 15)
    speedhigh = true;
  else
    speedhigh = false;
    
  if (mph > 7)
    speedlow = true;
  else
    speedlow = false;
    

 
} // displayGPS


void loop() 
    {
  SurfRight=digitalRead(pinSurfRight);
  SurfLeft=digitalRead(pinSurfLeft);
  Auto=digitalRead(AutoPin);
  
   if (gps.available( gpsSerial )) {  // if there is data coming from the GPS shield
    gps_fix fix = gps.read();           // get the complete fix structure
    displayGPS( fix );                 // Show pieces of the fix on Serial
  }
  
  //Manual
   if ((LeftDeploying == true) && (SetLeftDeploy == false))
  {
    digitalWrite(RelayGateRight, HIGH);
    LeftDeployTime = time;
    SetLeftDeploy = true;}
    
    
  

  
    if (SurfLeft == LOW)
    {
  if (SurfLeftDeployed == false){
    LeftDeploying = true;
    time = millis();
    if (time-LeftDeployTime >= 4000){
    digitalWrite(RelayGateRight, LOW);  
    SurfLeftDeployed = true;
    LeftDeploying = false; 
    SetLeftDeploy = false;
    }}
    
  }}

"an input". Where is that input in the code, please?

Easy enough. Connect your button to one of the interrupt pins and setup an interrupt when that pin rises to 5V.

The ISR would start a timer along these lines:

uint32_t nTimer = 0;
uint8_t nOutputPin = 0;

void OnButtonPress()
{
    noInterrupts();
    nTimer = millis() + (4 * 1000);
    digitalWrite(nOutputPin, HIGH);
}

void loop()
{
    if (nTimer  > millis())
    {
        nTimer = 0;
        digitalWrite(nOutputPin, LOW);
        interrupts();
    }

}

the input is SurfLeft - there will eventually be an input and GPS speeds that determine if the gate should be deployed so the interrupt wont work

jhartt3:
the input is SurfLeft

Thanks.

jhartt3:

  • there will eventually be an input and GPS speeds that determine if the gate should be deployed so the interrupt wont work

Please use language that someone who is not familiar with your project can understand

  1. "there will eventually be an input"... the same input, a different one? ???
  2. What is a "GPS speed"?
  3. What "gate"?

The final logic will be

If Switch is on && speed is greater than 7mph && speed is less than 15 MPH

If Gate is not deployed

Turn on output for 4 seconds then off

set Gate deployed

If switch is off or speed is less than 7mph or speed is greater than 15mph

If gate is deployed

Turn on same output and additional output for 4.5 seconds.

the problem is somewhere in the time delay not working properly - if i take out the turn output off it will turn the output on and leave it on