adding an emergency stop function into sketch

hi everyone. I'm having a bit of a problem adding a function to my sketch that cancels everything that my relay board is doing as an emergency stop. here is the pertinent code.

void loop() { if (digitalRead(prog2) == HIGH) {program2();} }

void program2() { while (digitalRead(xLimit) != HIGH) xPass1();

while (digitalRead(yPos2) != HIGH) yMove1();

while (digitalRead(xHome) != HIGH) xPass2();

while (digitalRead(xHome) != LOW) allStop(); }

void xPass1() { digitalWrite(4, LOW); delay(50); digitalWrite(2,HIGH); }

void xPass2() { digitalWrite(4,LOW); delay(50); digitalWrite(3,HIGH); }

void yMove2() { digitalWrite(3,LOW); delay(50); digitalWrite(4,HIGH); }

void allStop() { digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); digitalWrite(8,LOW); }

I want to be able to call the allStop() function at any time. it works a little bit when I add the following:

void xPass1() { if (digitalRead(emergencyStop) == LOW) { digitalWrite(4, LOW); delay(50); digitalWrite(2,HIGH); } else if (digitalRead(emergencyStop) == HIGH) allStop(); }

but it only calls the allStop() function as long as I am pressing the button. Any suggestions?

One direct way might be to add the "goto" function.

where in the sketch would I add the "goto" function?

i just don't understand why my if else structure isn't just sending the program to allStop() and staying there. the prog1 button hasn't been pressed again so why is the program attempting to do pass1() ???

Goto is a terrible solution =) (obligatory note).

In regards to your issue, you probably want to make allStop() a blocking function - right now it needs to be called repeatedly, and you have no flag for (isStopped) which would keep it running when you let go of the button.

A possible solution:

void allStop() {
  // wait for exit condition to be true
  while (!exitCondition) {
    // set everything low
    for (uint8_t i = 2; i < 9; i++) {
      digitalWrite(i, LOW);
   }
  }
}

exitCondition should be replaced by something such as digitalRead(resetButton).

This will execute an infinite loop (and thus halt the program) until resetButton is HIGH, which is probably the desired behavior.

hmm good idea. I'll give it a shot. Thanks

You're the man. Works like a charm!!

Save yourself a lot of grief... use an interrupt.

Look in the reference on using interrupt service routines, it's straightforward and exactly what you are looking for... and you don't need to be looking for the state change.. an ISR is called automatically when the condition is detected.

http://arduino.cc/en/Reference/AttachInterrupt

as usual I can’t make heads or tails from the interrupt example in the reference. could you just tell me how to use it to point to my allStop() function please? I’ve been working on this for hours now.

in setup(), you'll want to have:

AttachInterrupt(0,allStop,LOW);

that's it (assuming the interrupt pin is pin 2). Interrupts are done with pin2 (int0) and pin3 (int1)... so choose that value accordingly.

Your allStop routine will be called automatically when the pin goes low. Interrupts can be extremely useful and are designed for just this kind of application.

okay so I have a mega and the emergency stop button is connected to digi pin 21 which will be interrupt 2. I have the switch set up to go HIGH when pushed so I'll give it a try.

so it would be:

AttachInterrupt(2,allStop,HIGH);

That will trigger allStop when the pin is high. If you only want to trigger on the change, use RISING instead.

it's not working. I understand the attachInterrupt now but nothing changes when I hit the button. could the way my "while" statements are arranged?

I added this to void setup:() attachInterrupt(3, allStop, RISING);

because the emergency stop button is connected to pin 20 on my 1280 mega board.

Nah, the interrupt routine call shouldn't care about the while statements. All it cares about is the interrupt.

Stick a

Serial.println("ISR Called!");

or some other kind of tracing output.. try a HIGH instead of RISING also, possibly.. but it ought to work as it is. Make sure that you are actually taking the pin HIGH.. interrupt service calls are pretty foolproof, usually.

I'm getting a constant 2.6 vdc from that pin without the button being pressed. I tried HIGH too instead of RISING.

yeah man this is crazy. I'm getting a serial output when the allStop is called normally during the course of the sketch but I get nothing from the emergency stop button which is set up just fine. I'm confused.

ok I got it to work tentatively by moving the interrupt to digital pin2 and rewriting the sketch to attachInterrupt(0,allStop,RISING);

i guess pins 18 19 20 on the mega may need to be set up another way first]

Silly question... pinMode set?

no, no pinmode set. I think there must be a jumper or something for pin 20 to be used the way we want it to. I have plenty of open pins for this project. I wrote this real quick and it works fine.

void setup() { Serial.begin(9600);

attachInterrupt(0,shit,RISING); }

void loop() { } void shit() { Serial.println("booo"); }