soft estop problems

Hi all, I’m a complete noob and I’m struggling to get a soft estop to work on a code i’ve been creating.
I have taken the code from a video that philo mech uploaded on you tube but I am getting the error ‘e_stop_ISR’ was not declared in this code. I know it should be declared at the top but I’m not sure how to, as if I just take the code he has written it does not bring up the same error.
Here is my code (apologies this is my very first attempt at coding)

/* put running code that is currently under loop into a setup sub folder then ref just sub name in loop
  added estop interrupt
*/

const int Startswitch = 3;
const int WinRelay = 4;
const int WasteRelay = 5;
const int FlushRelay = 6;
const int FillRelay = 7;
const int PowerLED = 8;
const int FinishLED = 9;
const int FlushLED = 10;
const int PurgeLED = 11;
const int ResetLED = 12;
int Flushvar = 0;
int Purgevar = 0;
int Fillvar = 0;
boolean start = true;
volatile boolean e_stop = false;


void setup() {

  Serial.begin(9600);         //start serial connection
  delay(100);
  attachInterrupt(digitalPinToInterrupt(2), e_stop_ISR , RISING);
  pinMode(Startswitch, INPUT_PULLUP);   //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(WinRelay, OUTPUT);              //mains water in solinoid
  pinMode(WasteRelay, OUTPUT);
  pinMode(FlushRelay, OUTPUT);
  pinMode(FillRelay, OUTPUT);
  pinMode(PowerLED, OUTPUT);
  pinMode(FinishLED, OUTPUT);
  pinMode(FlushLED, OUTPUT);
  pinMode(PurgeLED, OUTPUT);
  pinMode(ResetLED, OUTPUT);

}

void Flush() {

  digitalWrite (WasteRelay, LOW);             //waste relay on, solenoid open
  digitalWrite (FlushRelay, LOW);            //flush relay on, solenoid open
  Flushvar = 0;
  while (Flushvar < 10) { // do something repetitive 200 times
    digitalWrite (FlushLED, HIGH);
    delay (500);
    digitalWrite (FlushLED, LOW);
    delay (500);
    Flushvar++;
  }
  digitalWrite (FlushRelay, HIGH);
  digitalWrite (WasteRelay, HIGH);


  void Purge() {
    digitalWrite (WasteRelay, LOW);
    Purgevar = 0;
    while (Purgevar < 10) { // do something repetitive 10 times
      digitalWrite (PurgeLED, HIGH);
      delay (500);
      digitalWrite (PurgeLED, LOW);
      delay (500);
      Purgevar++;
    }

    digitalWrite (WasteRelay, HIGH);
  }
}

void Fill() {
  digitalWrite (WasteRelay, HIGH);
  digitalWrite (FillRelay, LOW);
  Fillvar = 0;                                     // reset var to 0
  while (Fillvar < 10) { // check to see if var = 10, if not run loop, if greater then exit addition loop
    digitalWrite (FinishLED, HIGH);              // turn on led
    delay (500);                                 // wait .5s
    digitalWrite (FinishLED, LOW);               // turn off led
    delay (500);                                 // wait 0.5s
    Fillvar++;                                       // add 1 to var
  }
  digitalWrite (FinishLED, HIGH);
  digitalWrite (FillRelay, HIGH);
  digitalWrite (WasteRelay, LOW);
}
}
}

void loop() {
  if (start == true) {
    if (e_stop == false) {
      digitalWrite (PowerLED, HIGH);

      int buttonstate = digitalRead(Startswitch);       //read the pushbutton value into a variable
      Serial.println(buttonstate);                      //print out the value of the pushbutton

      if (buttonstate == LOW) {
        digitalWrite(FinishLED, LOW);                //turn finish led off
        digitalWrite (WinRelay, LOW);               //water in relay on, solenoid open
        Flush();                                    //run flush sub program
        Purge();                                    //run purge sub program
        Fill();                                     //run fill sub program
        digitalWrite (WinRelay, HIGH);              //close water in solenoid
        delay (5000);
        digitalWrite(FinishLED, HIGH);              //display fill finished/ready


      } else {
        digitalWrite(FinishLED, HIGH);
        digitalWrite(WinRelay, HIGH);
        digitalWrite(WasteRelay, LOW);
        digitalWrite(FlushRelay, HIGH);
        digitalWrite(FillRelay, HIGH);
        digitalWrite(FlushLED, LOW);
        digitalWrite(PurgeLED, LOW);
      } else {
        digitalWrite(ResetLED, HIGH);
        start = false
      }
    }
  }

  /***** interrupt service routine *****/

  void e_stop_ISR() {
    detachInterrupt(0);
    e_stop = !e_stop;
  }

Ill include the code that I copied just for reference

boolean start = true;
volatile boolean e_stop = false;

void setup() {  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(100);

  attachInterrupt(0, e_stop_ISR , RISING);

}

void loop() {   // put your main code here, to run repeatedly:

  if (start == true){
    if(e_stop == false){
      Serial.println("all is well in the world...");
      delay(300);
    }
    else{
      Serial.println("Emergancy Stop!!! Must press reset button to retart program!!");
      start = false;
    
    }
  }
}

/* interrupt service routine*/

void e_stop_ISR(void){
  detachInterrupt(0);
  e_stop = !e_stop;
}

I would like to use an interrupt to stop the program as this will be used to fill a water container from an Reverse osmosis machine with leak detection.

Thanks in advance for any help or advice

You have a function called e_stop_ISR(). You are trying to attach a function called e_stop_isr() as the interrupt handler.

Case matters!

Thanks for the reply. I was messing with the case before i copied. In the orignal script the case is the same. However even if I change the case it still returns the same.

I have now attached the original script

So, you modified the code in your original post, to correct errors that were pointed out, making people that pointed out errors look like idiots. That is NOT a good idea, and you will NOT do that again.

You have the Purge() function defined inside the Flush() function. You know damned well that that is not allowed. The compiler told you that, and yet you ignored a bunch of other messages to focus on that one particular issue. Why?

You fix errors starting with the first one reported, not the last one, not one in the middle.

If you put every { on a line BY ITSELF and every } on a line BY ITSELF ALL THE TIME, you would not be making such stupid mistakes as defining a function inside another function.

  while (Flushvar < 10) { // do something repetitive 200 times

Useless comments should at least match the code. A for loop is more commonly used when you know how many times to iterate. A while statement is usually used when you don’t know how many times you will iterate.

If you do put every { and every } on lines by themselves, you’ll see that your ISR function is inside of loop().

Thank you for your constructive criticism

PaulS:
So, you modified the code in your original post, to correct errors that were pointed out, making people that pointed out errors look like idiots. That is NOT a good idea, and you will NOT do that again.

If you read my response to your first reply you will see that I said that I have copied the original code in. I thought I was doing the right thing by replacing the code that was there rather then adding the code again to confuse people. Hence I was not trying to make people look like idiots as you have put it.

PaulS:
You have the Purge() function defined inside the Flush() function. You know damned well that that is not allowed. The compiler told you that, and yet you ignored a bunch of other messages to focus on that one particular issue. Why?

You fix errors starting with the first one reported, not the last one, not one in the middle.

If you put every { on a line BY ITSELF and every } on a line BY ITSELF ALL THE TIME, you would not be making such stupid mistakes as defining a function inside another function.

I have been working on this on UnoArduSim and this is the point that it flags up first, and yes in hindsight now scrolling up through the compiler it does show other errors that I will now address. So I did not know damned well that it is not allowed and that compiler told me that, neither did I ignore a bunch of other messages. I simply did not no that they were there.

Yes I may be making 'stupid mistakes' as you have put it but as I have said I am COMPLETLY NEW to any form of coding and I am making every effort to get things correct. Hence why I have asked for help!!!

I will go away and work through the things you have pointed out that need to be changed and learn from this.

I do not appreciate the way in which you have responded as if to belittle my ability. If this is the way in which members on this forum help and encourage people how to learn then I'm shocked.

It is much better to add new code in a new post as it preserves the flow of the discussion for other readers and it also leaves open the opportunity to compare the old and new versions.

And there are now two programs in the Original Post - which one should I look at?

If this ESTOP has any role in safety it should not be part of an Arduino program at all. Safety emergency stops should be completely independent of all software. If appropriate the ESTOP switch might have a second contact that allows the software to know that the ESTOP has been pushed.

...R

Your E-Stop should be a maintained, normally closed pushbutton in the power supply wire to the relays, can you post a wiring diagram?

Thanks for your replies.
I wasn't aware that I should put the code in another post. I will take that on-board in future.
The ESTOP as I refer to it is only incase the bucket I am filling with water overflows or leaks. There is no danger to life

My thinking was if there was a leak of water or an overflow that was picked up by a moisture detector on pin 2, then it could act as an estop with using the interrupt and return the code back to the start of the void loop.

I will try and draw up a circuit diagram

My thinking was if there was a leak of water or an overflow that was picked up by a moisture detector on pin 2, then it could act as an estop with using the interrupt and return the code back to the start of the void loop.

That's not the way an interrupt works.

Suppose that you are home, cooking dinner. The door bell rings - that's an interrupt. You go answer the door. It's the neighbor, wanting to borrow a tool. You tell him/her to buzz off (or lend the tool). The interrupt handler/handling is over. So, what do you do? Return to cooking dinner, or go watch TV.

The Arduino returns to cooking dinner.

You still need to deal with the interrupt having happened. Unless the interrupt handler turned the water off, you are still pumping water all over the place, while doing whatever you were doing that was preventing you from polling the pin often enough.

elmo2002:
My thinking was if there was a leak of water or an overflow that was picked up by a moisture detector on pin 2,

Nothing about water overflowing or leaking or moisture detection happens fast enough to need to use an interrupt. Just regularly polling the detector will be plenty fast enough. Indeed you probably don't need to poll more than once per second and the Arduino could do it a hundred times faster than that.

The trick is to write non-blocking code. Have a look at Several Things at a Time. Note how each function runs very briefly and returns to loop() so the next one can be called. Long running processes are achieved a tiny piece at a time. And there may be dozens of calls to some functions before it is actually time for anything to happen.

...R