Arduino reset - on pin change of state

Hello All,
Arduino UNO - My code has two modes (Auto/Manual)
Mode (Pin 2)
I would like the board to reset using the software reset function after its see's a change of state on Pin 2 (reset will occur, when changed from HIGH to LOW or LOW to HIGH)


#define Mode_Pin 2                  //Auto or manual mode Switch 
#define System_Start 3              //RF trigger output pin
#define Gate_Limit_Switch 4         //Gate Limit Switch output pin
#define Gate_Open_Valve 5           //Gate Open Valve Ralay pin
#define Gate_Close_Valve 6          //Gate Close Valve Ralay pin 
#define Main_Motor_Contactor 7      //Main Motor Contactor Ralay pin 
#define Fluid_Allow_Valve 8         //On Valve Relay allowing fluid Ralay pin
#define Motor_AUX_Switch 9          //Detect motor is running
#define Obstruction_Sensor_Pin 10   //Detect obstruction in gate path
#define Manual_Open_Pin 11          //Gate Open Manual Swtich
#define Manual_Close_Pin 12         //Gate Close Manual Swtich
#define Emergency_Button_Pin 13     //Stop all functions when pressed
#define Gate_Open_Indicator A5      //Indicates Gate Opened Status
#define Gate_Close_Indicator A4     //Indicates Gate Closed Status


#define TimeOut 3000

boolean Gate_open = true;
boolean Manual_Open;
boolean Manual_Close;

unsigned long Time;

void setup() {
  Serial.begin(9600);
  pinMode(Mode_Pin, INPUT_PULLUP);
  pinMode(System_Start, INPUT_PULLUP);
  pinMode(Gate_Limit_Switch, INPUT_PULLUP);
  pinMode(Motor_AUX_Switch, INPUT_PULLUP);
  pinMode(Manual_Open_Pin, INPUT_PULLUP);
  pinMode(Manual_Close_Pin, INPUT_PULLUP);
  pinMode(Obstruction_Sensor_Pin, INPUT_PULLUP);
  pinMode(Emergency_Button_Pin, INPUT_PULLUP);

  pinMode(Gate_Open_Valve, OUTPUT);
  pinMode(Gate_Close_Valve, OUTPUT);
  pinMode(Main_Motor_Contactor, OUTPUT);
  pinMode(Fluid_Allow_Valve, OUTPUT);
  pinMode(Gate_Open_Indicator, OUTPUT);
  pinMode(Gate_Close_Indicator, OUTPUT);

  digitalWrite(Gate_Open_Valve, LOW);
  digitalWrite(Gate_Close_Valve, LOW);
  digitalWrite(Fluid_Allow_Valve, LOW);
  digitalWrite(Main_Motor_Contactor, LOW);

  pinMode(3, OUTPUT);

  Time = millis();

}

void loop() {
  if ((millis() - Time) > TimeOut) {
    //Serial.println("ff");
    EStop();
  }
  if (Gate_open) {
    digitalWrite(Gate_Open_Indicator, LOW);
    digitalWrite(Gate_Close_Indicator, HIGH);
  } else {
    digitalWrite(Gate_Open_Indicator, HIGH);
    digitalWrite(Gate_Close_Indicator, LOW);
  }
  emergency();
  if (Mode()) {
    if (!digitalRead(System_Start)) {
      delay(200);
      emergency();
      Serial.println("System_Start");
      if (Gate_open) {
        Close_Valve();
        Gate_open = false;
        Serial.println("Gate_Closing");
      } else {
        Open_Valve();
        Gate_open = true;
        Serial.println("Gate_opening");
      }

      while (digitalRead(Gate_Limit_Switch)) {
        emergency();
        if (digitalRead(Obstruction_Sensor_Pin)) {
          Allow_Fluid();
        } else {
          Stop_Fluid();
        }
        Main_Motor();
        if (digitalRead(Motor_AUX_Switch)) {
          digitalWrite(Main_Motor_Contactor, HIGH);
        } else {
          digitalWrite(Main_Motor_Contactor, LOW);
        }
        if (!digitalRead(System_Start)) {
          delay(200);
          if (Gate_open) {
            digitalWrite(Main_Motor_Contactor, HIGH);
            delay(500);
            Close_Valve();
            Gate_open = false;
            Serial.println("Gate_Closing");
          } else {
            digitalWrite(Main_Motor_Contactor, HIGH);
            delay(500);
            Open_Valve();
            Gate_open = true;
            Serial.println("Gate_Opening");
          }
        }
      }
      Stop_Fluid();
      Stop();
      Time = millis();
    }
  } else {
    if ((!digitalRead(Manual_Open_Pin)) || (!digitalRead(Manual_Close_Pin))) {
      emergency();
      Serial.println("System_Start");
      while (!digitalRead(Gate_Limit_Switch)) {
        emergency();
        if (!digitalRead(Manual_Open_Pin)) {
          digitalWrite(Gate_Open_Valve, LOW);
          digitalWrite(Gate_Close_Valve, HIGH);
          digitalWrite(Main_Motor_Contactor, LOW);

        } if (!digitalRead(Manual_Close_Pin)) {
          digitalWrite(Gate_Open_Valve, HIGH);
          digitalWrite(Gate_Close_Valve, LOW);
          digitalWrite(Main_Motor_Contactor, LOW);
        }
      }
      if (!digitalRead(Manual_Open_Pin)) {
        Gate_open = true;
        Open_Valve();
        Serial.println("Open_Switch");
      }
      if (!digitalRead(Manual_Close_Pin)) {
        Gate_open = false;
        Close_Valve();
        Serial.println("Close_Switch");
      }

      while (digitalRead(Gate_Limit_Switch)) {
        emergency();
        if (digitalRead(Obstruction_Sensor_Pin)) {
          Allow_Fluid();
        } else {
          Stop_Fluid();
        }
        Main_Motor();
        if (digitalRead(Motor_AUX_Switch)) {
          digitalWrite(Main_Motor_Contactor, HIGH);
          Serial.println("AUX_Switch");
        } else {
          digitalWrite(Main_Motor_Contactor, LOW);
          
        }
        if (!digitalRead(System_Start)) {
          delay(200);
          if (Gate_open) {
            Close_Valve();
            Gate_open = false;
            Serial.println("Gate_Closing");
          } else {
            Open_Valve();
            Gate_open = true;
            Serial.println("Gate_Opening");
          }
        }
        if (Gate_open) {
          if ((digitalRead(Manual_Open_Pin)) && (!digitalRead(Manual_Close_Pin))) {
            digitalWrite(Main_Motor_Contactor, HIGH);
            delay(2000);
            Stop_Fluid();
            Gate_open = false;
            Close_Valve();
            Allow_Fluid();
            digitalWrite(Main_Motor_Contactor, LOW);
            Serial.println("Gate_Closing");
          }
        } else {
          if ((!digitalRead(Manual_Open_Pin)) && (digitalRead(Manual_Close_Pin))) {
            digitalWrite(Main_Motor_Contactor, HIGH);
            delay(2000);
            Stop_Fluid();
            Gate_open = true;
            Open_Valve();
            Allow_Fluid();
            digitalWrite(Main_Motor_Contactor, LOW);
            Serial.println("Gate_Opening");
          }
        }
      }
      Stop_Fluid();
      Stop();
      Time = millis();
    }
  }

}

boolean Mode() {
  if (digitalRead(Mode_Pin)) {
    Serial.println("Auto");
    return 1;
  } else {
    Serial.println("Manual");
    return 0;
  }
}

void Close_Valve() {
  Serial.println("Close Valve Powered");
  digitalWrite(Gate_Close_Valve, LOW);
  delay(100);
  digitalWrite(Gate_Open_Valve, HIGH);
  delay(100);
}

void Open_Valve() {
  Serial.println("Open Valve Powered");
  digitalWrite(Gate_Open_Valve, LOW);
  delay(100);
  digitalWrite(Gate_Close_Valve, HIGH);
  delay(100);
}

void Main_Motor() {
  Serial.println("Main Motor Powered");
  digitalWrite(Main_Motor_Contactor, LOW);
  delay(100);
}

void Allow_Fluid() {
  Serial.println("Fluid Allowed");
  digitalWrite(Fluid_Allow_Valve, LOW);
  delay(100);
  digitalWrite(Main_Motor_Contactor, LOW);
}

void Stop_Fluid() {
  Serial.println("Fluid Blocked");
    digitalWrite(Main_Motor_Contactor, HIGH);
    delay(100);
    digitalWrite(Fluid_Allow_Valve, HIGH);
}

void Stop() {
  if (Gate_open) {
    while (!digitalRead(Gate_Limit_Switch)) {
      digitalWrite(Gate_Close_Valve, HIGH);
      delay(100);
    }
    digitalWrite(Gate_Close_Valve, LOW);
    delay(100);
  } else {
    while (!digitalRead(Gate_Limit_Switch)) {
      digitalWrite(Gate_Open_Valve, HIGH);
      delay(100);
    }
    digitalWrite(Gate_Open_Valve, LOW);
    delay(100);
  }
}

void EStop() {
  digitalWrite(Gate_Close_Valve, HIGH);
  digitalWrite(Gate_Open_Valve, HIGH);
  digitalWrite(Main_Motor_Contactor, HIGH);
  digitalWrite(Fluid_Allow_Valve, HIGH);
}

void emergency() {
  if (!digitalRead(Emergency_Button_Pin)) {
    EStop();
    Serial.print("Emergency Button Pressed... Reset The Device to Continue");
    while (1);
  }
}

open someone has the skills

see Two ways to reset Arduino

void(* resetFunc) (void) = 0;//declare reset function at address 0

Thanks for responding so quick.

The link you supplied i had already looked at as well as many others.

  • Lets say pin 2 has two states it is either held HIGH or LOW depending on the position of the input switch (not momentary)
  • Every time pin 2 changes state, i want the RESET pin on the UNO to go low (momentary) thereby doing a reset..

At no other time is a reset performed

hope this clarifies better

sounds like you don't understand how to detect a change in state?

consider the code below. i used a but to change the state of a pin. it's state is initialized by reading the pin in setup().

when i press it there is a reset. And because is reads that state in setup() it resets when I release the pin.

are you sure you want to reset anytime the pin changes state?

void(* resetFunc) (void) = 0;//declare reset function at address 0

#define rstPin  A1

byte rstLst;

// -----------------------------------------------------------------------------
void loop (void) {
    byte rst = digitalRead (rstPin);

    if (rstLst != rst)
        resetFunc ();
}

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

    rstLst = digitalRead (rstPin;

    Serial.println ();
    Serial.println (__func__);
}

maybe i mis-read this. do you want a software reset, or a mechanism to make the reset pin LOW using software?

Thanks for your response yet again,
your are indeed correct, i tried to find information on how to detect the change of state on a pin and apply it to my reset function. Until now with little luck..

As for do i really need to reset each time the mode is changed? ...
Truly if i was as skilled as most here i would not need to too.
The code i have posted was written with the help of another, trouble is that is seems to lock up (freeze) just after changing states from Manual to Auto.
The only way to reset is a complete power down.
The on board reset is also locked out.

If left in either mode 99.5% of the time it runs without glitch.
Change mode then it is likely t lock up after the third or fourth open, close or limit function.
My theory is if i am able to reset on a mode change i can minimise and further issues.
Maybe you can see something wrong with my code i can not that is causing and issue.
everytime i run a serial monitor it wont play up..!

If serial makes the problem go away, perhaps it is slowing things down - try a much higher baud rate and add your debugging stuff back in.

Loop is so huge it's very hard to see what's going on. Consider breaking some of it out into separate functions just for readability.

Put a wire from a digital pin to the reset pin, keep it high and when you want it to reset pull it to low.

i believe the code I posted is almost exactly what you want. rslLst is your mode

presumably you only need to read the mode at startup, but the code needs to monitor the mode pin to force a reset when it changes.

1 Like