When I press the button, the relay works but does not stop

When I click the start button, the code starts, but when I click the stop button, it does not stop. I am using Arduino nano, I am using a 4 relay module, there is no problem in my connections.

int relay1Pin = 2;
int relay2Pin = 3;
int relay3Pin = 4;
int relay4Pin = 5;

int stopButton = 8;
int startButton = 9;

bool isRunning = false;  // Başlangıçta çalışmıyoruz

void setup() {
  pinMode(stopButton, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(relay1Pin, OUTPUT);
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  digitalWrite(relay1Pin, HIGH);
  digitalWrite(relay2Pin, HIGH);
  digitalWrite(relay3Pin, HIGH);
  digitalWrite(relay4Pin, HIGH);

  Serial.begin(9600);  // Seri portu başlat
}

void loop() {
  // Start düğmesine basıldığında röleleri çalıştır
  if (digitalRead(startButton) == LOW) {
    isRunning = true;
    Serial.println("Röleler çalıştırılıyor...");
  }
  
  
  // Stop düğmesine basıldığında röleleri durdur
  if (digitalRead(stopButton) == LOW) {
    if (isRunning) {
      isRunning = false;
      digitalWrite(relay1Pin, HIGH);
      digitalWrite(relay2Pin, HIGH);
      digitalWrite(relay3Pin, HIGH);
      digitalWrite(relay4Pin, HIGH);
      Serial.println("Röleler durduruldu.");
    } 
  }
  
  
  // Röleleri çalıştırma durumunda
  if (isRunning) {
    digitalWrite(relay1Pin, LOW);
    digitalWrite(relay2Pin, LOW);
    delay(10000);
    digitalWrite(relay1Pin, HIGH);
    digitalWrite(relay2Pin, HIGH);
    delay(5000);

    digitalWrite(relay3Pin, LOW);
    digitalWrite(relay4Pin, LOW);
    delay(10000);

    digitalWrite(relay3Pin, HIGH);
    digitalWrite(relay4Pin, HIGH);
    delay(5000);
  }
}

The delay() functions are making it seem not to work. You have about 1 ms to press a button. : )

  if (isRunning) {
    digitalWrite(relay1Pin, LOW);
    digitalWrite(relay2Pin, LOW);
    delay(10000); // <--- 10 seconds of the processor not listening to buttons
    digitalWrite(relay1Pin, HIGH);
    digitalWrite(relay2Pin, HIGH);
    delay(5000); // <--- 5 seconds of the processor not listening to buttons

    digitalWrite(relay3Pin, LOW);
    digitalWrite(relay4Pin, LOW);
    delay(10000); // <--- 10 seconds of the processor not listening to buttons

    digitalWrite(relay3Pin, HIGH);
    digitalWrite(relay4Pin, HIGH);
    delay(5000); // <--- 5 seconds of the processor not listening to buttons
  }

The best advice is to use millis() for timing events. Here is a link to Blink Without delay() to help you. millis() will make your button responses accurate.

After using millis(), you can do some more reading about attachinterrupt() for a hardware solution to reading buttons.

I dont know how can i use millis(). Can u replace this code?

More non-blocking timing tutorials:

Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

can anyone replace this code i dont understand millis()

Hello kaandagci

In general - Arrays and structs are your friends.
Don't duplicate code in your sketch. Write code once - use it multiple times.

Have a nice day and enjoy coding in C++.

I'm only reading the code and through a tiny window, but it looks more like one might have to hold down the button for a very long time to get the reaction @kaandagci wants.

So I agree in either case. A solution based on the concepts seen in examples in the IDE

 blink without delay

And

State change detection

would allow much more responsive action.

a7

Give this a spin..

Your project simmed..

have fun.. ~q

Hello qubits-us

Please provide the sketch in code tags for our mobil members.

Thank you so much.

1 Like

I hijacked @qubits-us's simulation and used most of it but changed the state machine out for a simple sequencer.

I am all for state machines, ask anyone. In this case, parallel arrays holding the relay states and times they should be held makes tinkering with the exact output a bit easier, like adding more to the sequence or changing the times in the steps, viz:


  if (isRunning) {
    if (now - lastChange > dwellTime) {
      for (byte ii = 0; ii < 4; ii++)
        digitalWrite(relayPin[ii], relayState[ii][cIndex] ? REALY_ON : REALY_OFF);

      lastChange = now;
      dwellTime = timer[cIndex];
      cIndex++; if (cIndex >= NSTEPS) cIndex = 0;
    }
  }

Play with it now:


Wokwi_badge Simple Sequencer Take


And the full code, for @paulpaulson to see on the small screen. I'm sure it can be C++ed a bit also. :wink:


// https://wokwi.com/projects/367601689146084353
// https://forum.arduino.cc/t/when-i-press-the-button-the-relay-works-but-does-not-stop/1138057

int relay1Pin = 2;
int relay2Pin = 3;
int relay3Pin = 4;
int relay4Pin = 5;

int stopButton = 8;
int startButton = 9;

bool isRunning = false;  // Başlangıçta çalışmıyoruz
//state machine var
byte runState = 0;
//millis timer for states..
unsigned long lastChange = 0;
unsigned int intervalChange = 10000;
//millis timer for button debouncing..
unsigned long lastDebounce = 0;
int intervalDebounce = 50;

// active high or low?
# define REALY_ON     HIGH
# define REALY_OFF    LOW

void setup() {
  pinMode(stopButton, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(relay1Pin, OUTPUT);
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  digitalWrite(relay1Pin, REALY_OFF);
  digitalWrite(relay2Pin, REALY_OFF);
  digitalWrite(relay3Pin, REALY_OFF);
  digitalWrite(relay4Pin, REALY_OFF);

  Serial.begin(9600);  // Seri portu başlat
}

# define NSTEPS 4

// 1s for realy energixed during
const byte relayState[4][NSTEPS] = {
  {0, 1, 0, 0,},
  {0, 1, 0, 0,},
  {0, 0, 0, 1,},
  {0, 0, 0, 1,},
};

// time to spend in each step
unsigned long timer[NSTEPS] = {
  1000, 500, 1500, 2000,
};

const byte relayPin[4] = {
  relay1Pin,
  relay2Pin,
  relay3Pin,
  relay4Pin,
};

byte cIndex;
unsigned long dwellTime;

void loop() {

  unsigned long now = millis();  // time for entire loop

  // Start düğmesine basıldığında röleleri çalıştır
  if (digitalRead(startButton) == LOW) {
    if (now - lastDebounce >= intervalDebounce) {
      lastDebounce = now;
      if (!isRunning) {
        isRunning = true;
        //reset state machine
        cIndex = 0;
        dwellTime = 0;    // right away!
        Serial.println("Röleler çalıştırılıyor...");
      }
    }
  }

  // Stop düğmesine basıldığında röleleri durdur
  if (digitalRead(stopButton) == LOW) {
    if (now - lastDebounce >= intervalDebounce) {
      lastDebounce = now;
      if (isRunning) {
        isRunning = false;
        digitalWrite(relay1Pin, REALY_OFF);
        digitalWrite(relay2Pin, REALY_OFF);
        digitalWrite(relay3Pin, REALY_OFF);
        digitalWrite(relay4Pin, REALY_OFF);
        Serial.println("Röleler durduruldu.");
      }
    }
  }

  if (isRunning) {
    if (now - lastChange > dwellTime) {
      for (byte ii = 0; ii < 4; ii++)
        digitalWrite(relayPin[ii], relayState[ii][cIndex] ? REALY_ON : REALY_OFF);

      lastChange = now;
      dwellTime = timer[cIndex];
      cIndex++; if (cIndex >= NSTEPS) cIndex = 0;
    }
  }
}

The pins array could be used in setup() and there's a few other changes that will have to go undone - my beach buddy (she who must not be kept waiting!) is rolling towards me now. Cloudy but warm and some sun is forecasted.

HTH

a7

1 Like

sorry, i sleep..

as requested..

int relay1Pin = 2;
int relay2Pin = 3;
int relay3Pin = 4;
int relay4Pin = 5;

int stopButton = 8;
int startButton = 9;

bool isRunning = false;  // Başlangıçta çalışmıyoruz
//state machine var
byte runState = 0;
//millis timer for states..
unsigned long lastChange = 0;
unsigned int intervalChange = 10000;
//millis timer for button debouncing..
unsigned long lastDebounce = 0;
int intervalDebounce = 50;

void setup() {
  pinMode(stopButton, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(relay1Pin, OUTPUT);
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  digitalWrite(relay1Pin, HIGH);
  digitalWrite(relay2Pin, HIGH);
  digitalWrite(relay3Pin, HIGH);
  digitalWrite(relay4Pin, HIGH);

  Serial.begin(9600);  // Seri portu başlat
}

void loop() {
  // Start düğmesine basıldığında röleleri çalıştır
  if (digitalRead(startButton) == LOW) {
    if (millis() - lastDebounce >= intervalDebounce) {
      lastDebounce = millis();
      if (!isRunning) {
        isRunning = true;
        //reset state machine
        runState = 0;
        Serial.println("Röleler çalıştırılıyor...");
      }
    }
  }


  // Stop düğmesine basıldığında röleleri durdur
  if (digitalRead(stopButton) == LOW) {
    if (millis() - lastDebounce >= intervalDebounce) {
      lastDebounce = millis();
      if (isRunning) {
        isRunning = false;
        digitalWrite(relay1Pin, HIGH);
        digitalWrite(relay2Pin, HIGH);
        digitalWrite(relay3Pin, HIGH);
        digitalWrite(relay4Pin, HIGH);
        Serial.println("Röleler durduruldu.");
      }
    }
  }

  if (isRunning) {

    switch (runState) {
      case 0:   digitalWrite(relay1Pin, LOW);
        digitalWrite(relay2Pin, LOW);
        runState = 1;
        //set the timer interval
        intervalChange = 10000;
        //set the timer millis
        lastChange = millis();
        break;

      case 1: if (millis() - lastChange >= intervalChange) {
          runState = 2;
        }
        break;
      case 2:    digitalWrite(relay1Pin, HIGH);
        digitalWrite(relay2Pin, HIGH);
        runState = 3;
        //set the timer interval
        intervalChange = 5000;
        //set the timer millis
        lastChange = millis();
        break;
      case 3: if (millis() - lastChange >= intervalChange) {
          runState = 4;
        }
        break;
      case 4:    digitalWrite(relay3Pin, LOW);
        digitalWrite(relay4Pin, LOW);
        runState = 5;
        //set the timer interval
        intervalChange = 10000;
        //set the timer millis
        lastChange = millis();
        break;
      case 5: if (millis() - lastChange >= intervalChange) {
          runState = 6;
        }
        break;
      case 6:    digitalWrite(relay3Pin, HIGH);
        digitalWrite(relay4Pin, HIGH);
        runState = 7;
        //set the timer interval
        intervalChange = 5000;
        //set the timer millis
        lastChange = millis();
        break;
      case 7: if (millis() - lastChange >= intervalChange) {
          //start over??
          runState = 0;
        }
        break;
    }
  }
  /*
    // Röleleri çalıştırma durumunda
    if (isRunning) {
    digitalWrite(relay1Pin, LOW);
    digitalWrite(relay2Pin, LOW);
    delay(10000);
    digitalWrite(relay1Pin, HIGH);
    digitalWrite(relay2Pin, HIGH);
    delay(5000);

    digitalWrite(relay3Pin, LOW);
    digitalWrite(relay4Pin, LOW);
    delay(10000);

    digitalWrite(relay3Pin, HIGH);
    digitalWrite(relay4Pin, HIGH);
    delay(5000);
    }
  */

}

happy trails.. ~q

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.