Intermittently working interrupt

Hi All, I am trying to work on the logic for an emergency stop for a stopper motor loop. The idea is, it stops the motor and also it sends notification of the stop to a PC via serial. The first stop will work. Then it won't work again.

The idea is also only to send the stop notice ONCE.. hence the b_sendStop variable.

const byte SW_pin = 2; // digital pin connected to switch output

volatile bool b_emergencyStop = false;
volatile bool b_sendStop = false;

void setup() {
// put your setup code here, to run once:
pinMode(SW_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(SW_pin), EmergencyStop, FALLING);
Serial.begin(9600);
Serial.println ("READY L");
}

void loop() {

if (b_emergencyStop == true)
{
if (b_sendStop) {
Serial.println("Send to other places");
b_sendStop = false;
Serial.println ("STOP "); //only stop on emergency stop
Serial.print (b_emergencyStop);
Serial.println (b_sendStop);
//delayMicroseconds (1000);
}

goto EmergencyEscape;
}

Serial.print ("GO ");
Serial.print (b_emergencyStop);
Serial.println (b_sendStop);
//delayMicroseconds (1000);

EmergencyEscape:;

}

void EmergencyStop ()
{
b_emergencyStop = !b_emergencyStop;//pressed down
b_sendStop = !b_sendStop;
} //end Function

maybe simplify like this:

const byte SW_pin = 2; // digital pin connected to switch output

volatile bool b_emergencyStop = false;
volatile bool b_sendStop = false;


void setup() 
{
  pinMode(SW_pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(SW_pin), EmergencyStop, CHANGE);
  Serial.begin(9600);
  Serial.println ("READY L");
}

void loop() 
{
  while (b_emergencyStop)
  {
    Serial.print(F("."));
    delay(1000);
  }
  Serial.print ("GO ");
  Serial.print (b_emergencyStop);
  Serial.println (b_sendStop);
  delay(1000);
}

void EmergencyStop ()
{
  static unsigned long lastPollTime = 0;
  if (millis() - lastPollTime > 30)
  {
    if(digitalRead(SW_pin) == LOW)
    {
      b_emergencyStop = true;//pressed down
    }
    else
    {
      b_emergencyStop = false;
    }
    lastPollTime = millis();
  }
}

The button will probably bounce, so

 b_emergencyStop = !b_emergencyStop;//pressed down

toggles your flag back and forth. Better use

 b_emergencyStop = true; //pressed down

I think your ISR should not mess with the b_sendStop at all.

You should ditch that goto as well. Put that bit at the end in an else block so it will only run when b_emergencyStop is false.

Hi Guys,

I can confirm none of the above suggestions worked any better. The goto is a red herring. The code example worked once and not again, just printed dots no matter how often I pressed the jostick in or out or held it.

I did not really understand Whandall's message really, sorry. But thanks for trying

Maybe a latching switch will do the job.

An emergency stop-button should work only once, shouldn't it?

This is a version that sends once, but reenables the button after 5 seconds.

const byte SW_pin = 2; // digital pin connected to switch output

volatile bool b_emergencyStop = false;
volatile bool b_sendStop = false;

void setup() {
  Serial.begin(115200);
  pinMode(SW_pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(SW_pin), EmergencyStop, FALLING);
  Serial.println(F("READY L"));
}
void EmergencyStop ()
{
  b_emergencyStop = true;
}
void loop() {
  static unsigned long lastPrint;
  static unsigned long lastStop;
  static bool b_isStopped = false;
  unsigned long topLoop = millis();

  if (b_emergencyStop) {
    if (!b_isStopped) {
      b_isStopped = true;
      if (!b_sendStop) {
        Serial.println(F("Send the message"));
        b_sendStop = true;
      }
      lastStop = topLoop;
      Serial.print (F("STOP "));
      Serial.print (b_emergencyStop);
      Serial.print (F(", "));
      Serial.println (b_sendStop);
    } else if (topLoop - lastStop >= 5000) {
      b_isStopped = false;
      b_emergencyStop = false;
      Serial.print (F("REARMED "));
      Serial.print (b_emergencyStop);
      Serial.print (F(", "));
      Serial.println (b_sendStop);
    }
  } else if (topLoop - lastPrint >= 1000) {
    lastPrint = topLoop;
    Serial.print (F("GO "));
    Serial.print (b_emergencyStop);
    Serial.print (F(", "));
    Serial.println (b_sendStop);
  }
}
READY L
GO 0, 0
GO 0, 0
Send the message
STOP 1, 1
REARMED 0, 1
GO 0, 1
GO 0, 1
STOP 1, 1
REARMED 0, 1
GO 0, 1
GO 0, 1
GO 0, 1
GO 0, 1
GO 0, 1

Let's get back to solid ground.

Why do you need an interrupt to stop your stepper motor?

If the program is properly designed it will be completely unnecessary. Just poll the button between steps.

If it really is an emergency button it should just turn off the power without asking permission from the Arduino.

...R

Robin2:
If it really is an emergency button it should just turn off the power without asking permission from the Arduino.

...R

+1

... alternatively, if the code can detect an emergency situation on any input(s), then it can respond to this much more quickly than any human.

An emergency stop button is normally closed. When pressed, it latches open. Perhaps the OP requires something similar in software (not enough information to know).

dlloyd:
... alternatively, if the code can detect an emergency situation on any input(s), then it can respond to this much more quickly than any human.

An emergency stop button is normally closed. When pressed, it latches open. Perhaps the OP requires something similar in software (not enough information to know).

That's a watchdog.

aarg:
That's a watchdog.

Yes, could be a timeout condition ... or any out of range condition (too high or too low voltage, current, frequency, rpm, power, loss of phase voltage, gas leak, any alarm, flag, etc.)

A quick reply to various questions. I have twin NEMA 23of high spec (from Zapp Automotive - SY60 3000B I think) on two pulley wheels operating two ball screws side by side, lowering and raising a press that can crash into my glass projection surface (its a very large DLP 3D printer that I have designed). I am waiting for my limit switches from China. However in the meantime, until they come I want to test with a manual stop. A manual stop is also a legal requirement on all power machinery. In this case the prototype is using a standard little cheap joystick mouse which I will upgrade when working.

I suspect the issue is hardware related, I am testing Whandall's code right now and will report back any success.

I DID try just polling the switch. However that does not always work.. especially since I want a REMOTE switch to work too. I am using USB to connect to a Visual C+++ windows program.

Whandall's code worked PERFECTLY thanks.. it must have been software that is the problem.