Safety relay cutoff

Hi,

I would like to create a program which senses an input signal and if another input signal does not come within one millisecond, sends an output to a relay. I'm unsure how to implement this but I was thinking of using interrupts. I'm having problems reading if the second signal comes within this millisecond time period.

Thank you

Refer to the blink without delay example in the IDE examples. Record the time that the first signal occurs using the micros() function. Each time through loop() check state of the second signal. When the second signal arrives check the current time versus the recorded time. If the difference is less than 1000 microseconds do nothing. If greater than 1000 microseconds fire the relay. If your loop() code does not block, interrupts are not necessary.

A millisecond is relatively long in Arduino terms. Even the slowest 8MHz Arduino can do 8000 instructions in a millisecond.

How accurately do you need to measure the interval? If you don't need to measure down to less than 10 milliseconds, then a simple program without interrupts will work.

Your specification is a bit vague. Does the initial input stay 'active' for the entire millisecond? Is it high or low when it's active? My program below assumes that input "A" will go low (like a normal pushbutton) and stay low. If it goes high, the relay switches off and the timing resets. If it has been low for more than a millisecond and "B" hasn't gone low too, then the relay switches on. Once B has gone active once, it doesn't matter if it goes off again while A is still active. Short glitches on B within the millisecond will also be recorded as a sucessful event and the relay doesn't switch on.

const int InputAPin = 2;          //assign pin numbers as appropriate for your hardware
const int InputBPin = 3;          //and give them better names than just A and B
const int RelayOutputPin = 4;
const int RelayON = LOW;          //many common relay boards use active-LOW
const int DesiredInterval = 1000; //microseconds
void setup() {
  pinMode(InputAPin, INPUT_PULLUP); //with the pullup, the inputs will be HIGH until the button is pressed
  pinMode(InputBPin, INPUT_PULLUP);
  digitalWrite(RelayOutputPin, !RelayON); //make the relay output 'off' before we enable it as an output
  pinMode(RelayOutputPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("Millisecond Input Trigger Version 1.0 ready");
  Serial.print("Desired interval ");
  Serial.print(DesiredInterval);
  Serial.println(" microseconds.");
}
void checkAandBandTurnRelayOn() {
  static unsigned long LastTimeItWasOff;
  static boolean CameOnInTime;
  if (HIGH == digitalRead(InputAPin)) {
    //button has been released - turn the relay off, reset for the next event
    digitalWrite(RelayOutputPin, !RelayON);
    LastTimeItWasOff = micros();
    CameOnInTime = false;
  } else {
    //button A is pushed - has it been pushed for longer than the desired interval?
    if(micros() - LastTimeItWasOff > DesiredInterval) {
      //ok, time has expired, did B come on?
      if(CameOnInTime) {
        digitalWrite(RelayOutputPin, !RelayON);
      } else {
        digitalWrite(RelayOutputPin, RelayON);
      }
    } else {
      //still within the time interval - see if B came on in time
      if(LOW == digitalRead(InputBPin)) CameOnInTime = true;
    }
  }
}
void loop() {
  checkAandBandTurnRelayOn();
  //any other code can be put here, but keep it short if you want accurate timing on the millisecond interval
}

Thank you for responding.

The first input signal does not stay active for the entire millisecond. Also, it is uncertain if the second signal will come at all. I do not want to wait for the second input to come and then compare the time from the first to the second. I would rather constantly check if the second input has come within the millisecond and if a millisecond has passed and the signal still hasn't come, I will send an output signal to the relay.
I have written some code based off of your suggestions:

int inPin = 3;
int outPin = 4;
int t0;
int tf;
boolean goodRun = true;

void setup() {
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
}

void loop()
{
  pulseIn(inPin, HIGH);
  while (goodRun) {
    t0 = micros();
    while (digitalRead(inPin) == LOW) { //if pulse has not came, enter loop
      tf = micros();
      if (tf - t0 > 1000) { //time limit has expired
        goodRun = false;
        break;
      }
    }
  }
  digitalWrite(outPin, HIGH); //Send output signal to relay
}

I can see problems happening when micros() resets after 70 minutes. Do you see any other glaring issues?

If you make the variables that deal with micros() unsigned long data type and use subtraction in the calculations, micros() overflow will not be an issue.

pulseIn(inPin, HIGH);

This does not do what you think it does. It does not wait forever for a pulse. It will time out and return zero. By default, this is at 1 second.

Additionally, while the input pulse is high, you can't do anything else. You can't detect if the second input changes during the first pulse.

Change this to:

  while(LOW == digitalRead(inPin)) {
    //wait forever for the pin to become high
  }

How does goodRun ever get set back to true? What condition of the inputs or times reset it back to its initial value?