Delay Coding Problem

hi guys, i want to ask what is suitable coding for my motor and push button.
i want to make the motor is run only for 3 seconds when the push button is pressed as long as it is.
this is my coding..

if(button_state == HIGH)
{
analogWrite(motorSpeed,255);
digitalWrite(pin2, HIGH); //set the forward pin of L293D driver to high
digitalWrite(pin7, LOW); //set the reverse pin of L293D driver to low
delay(3000);
}

im trying this coding but the motor is still run and when the push button released, the delay start counting to make the motor stop.
i want to make the delay is start counting when the push button is start pressed at the first time

Add a test to make sure the button has gone low before accepting the next high to start the motor drive again.
if(button_state == HIGH && buttonTest == LOW)
{
analogWrite(motorSpeed,255);
digitalWrite(pin2, HIGH); //set the forward pin of L293D driver to high
digitalWrite(pin7, LOW); //set the reverse pin of L293D driver to low
delay(3000);
buttonTest = HIGH;
}
if (digitalRead(button) == LOW){
buttonTest = LOW;
}

Hello,

your code is correct. If you hold the button for less than three seconds, it will run only for a total of three seconds.

Your Problem Comes in when you hold the button longer than three seconds. The Problem is, it turns the Motor on and then waits three seconds. If the button were not pressed, it would turn it off but in the case where the button is still pressed at the end of the Initial three seconds, it 1) leaves it on and 2) turns it back on anyway.

You should replace the if(digitalRead/(button) == LOW with a Loop which runs until it is low.

That way, if you press the button only for one second, it will be immediately turned off after the three seconds. If you hold it down longer, it will be turned off as soon as you release the button.

You need to look at the state change example in the Arduino IDE.

You need to make the period start when the button becomes pressed - not while it is pressed.

And you should not use the delay() function because nothing can happen during a delay(). Have a look at how millis() is used to manage timing without blocking in several things at a time

I am assuming that you only want the motor to run for 3 seconds no matter how long the button is pressed. If that is wrong, tell us.

...R

if(button_state == HIGH) 
  {
  analogWrite(motorSpeed,255);
  digitalWrite(pin7, HIGH); 
  delay(3000);
  digitalWrite(pin7, LOW);
  }

I dont remember how Motor Driver works. The above code is based on a relay/transistor driving a motor. When the button is pressed, send a HIGH and after 3000ms delay send LOW.

As @Robin suggested try to move away from delay(), if you are dealing with multiple inputs.

CrossRoads:
Add a test to make sure the button has gone low before accepting the next high to start the motor drive again.
if(button_state == HIGH && buttonTest == LOW)
{
analogWrite(motorSpeed,255);
digitalWrite(pin2, HIGH); //set the forward pin of L293D driver to high
digitalWrite(pin7, LOW); //set the reverse pin of L293D driver to low
delay(3000);
buttonTest = HIGH;
}
if (digitalRead(button) == LOW){
buttonTest = LOW;
}

Shouldn't moderators be using code tags, and better formatting?
You're setting a bad example. :frowning:

So every time the loop() executes, the system might be in 3 possible states

button up,
button down < 3 seconds
button down >= 3 seconds

enum State { UP, DN_LT3, DN_GE3 } state;

loop() {
  select(state) {
  case UP:
    // TODO: write thi bit of the sketch
    break;
  case DN_LT3:
    // TODO: write thi bit of the sketch
    break;
  case DN_GE3:
    // TODO: write thi bit of the sketch
    break;
  }
}

CrossRoads:
Add a test to make sure the button has gone low before accepting the next high to start the motor drive again.
if(button_state == HIGH && buttonTest == LOW)
{
analogWrite(motorSpeed,255);
digitalWrite(pin2, HIGH); //set the forward pin of L293D driver to high
digitalWrite(pin7, LOW); //set the reverse pin of L293D driver to low
delay(3000);
buttonTest = HIGH;
}
if (digitalRead(button) == LOW){
buttonTest = LOW;
}

int pin7 = 9;          //pin 7 of L293D is connected to pin 9 Arduino
int pin2 = 8;          //pin 2 of L393D is connected to pin 8 Arduino
int motorSpeed = 3;       //pin 1 of L293D is connected to pin 3 (pwm pin) of arduino
int sensor = 4;   //button forward is connected to pin 0 Arduino
int reverse = 5;   //button reverse is connected to pin 1 Arduino
int EMPTY = 2;
int RED = 13;
int GREEN = 12;
int sensor_test;
int reverse_test;

void setup()
{
  pinMode(RED,OUTPUT);
  pinMode(GREEN,OUTPUT);
  pinMode(pin7, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(sensor,INPUT);
  pinMode(reverse, INPUT);
  pinMode(EMPTY, INPUT);
}

void loop()
{
  int sensor_state = digitalRead(sensor); //read the button condition
  int reverse_state = digitalRead(reverse); //read the button condition
  int EMPTY_state = digitalRead (EMPTY);
  
  if(sensor_state == HIGH && sensor_test == LOW)  
  {
  analogWrite(motorSpeed,255); 
  digitalWrite(pin2, HIGH);   //set the forward pin of L293D driver to high
  digitalWrite(pin7, LOW);    //set the reverse pin of L293D driver to low
  digitalWrite(GREEN,HIGH);
  digitalWrite(RED,LOW); 
  delay(1000);
  digitalWrite(GREEN,LOW);
  digitalWrite(pin2, LOW);
  sensor_test = HIGH;
  }

  else if(sensor_state == LOW)
  {
    sensor_test = LOW;
  }
  
  
  else if(reverse_state == HIGH && reverse_test == LOW)
  {
  analogWrite(motorSpeed,255);   //set the DC motor speed to 150 (not rpm)
  digitalWrite(pin2, LOW);    //set the forward pin of L293D driver to low
  digitalWrite(pin7, HIGH);   //set the reverse pin of L293D driver to high
  digitalWrite(GREEN,HIGH);
  digitalWrite(RED,LOW); 
  delay(1000);
  digitalWrite(GREEN,LOW);
  digitalWrite(pin7, LOW);
  reverse_test = HIGH;
  }

  else if(reverse_state == LOW)
  {
    reverse_test = LOW;
  }

  else if(EMPTY_state == HIGH)
  {
    digitalWrite(RED,HIGH);
    digitalWrite(GREEN,LOW);
  }

  else
  {
  analogWrite(motorSpeed,0);
  digitalWrite(pin2, LOW);
  digitalWrite(pin7, LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(RED,LOW);
  }
}

this is my code and schematic diagram.. i want to make it like DIFU functions and it's done but only one button can use but others two not functions. hope u guys can help me. i got no idea. :frowning:

int pin7 = 9;          //pin 7 of L293D is connected to pin 9 Arduino
int pin2 = 8;          //pin 2 of L393D is connected to pin 8 Arduino
int motorSpeed = 3;       //pin 1 of L293D is connected to pin 3 (pwm pin) of arduino
int sensor = 4;   //button forward is connected to pin 0 Arduino
int reverse = 5;   //button reverse is connected to pin 1 Arduino
int EMPTY = 2;
int RED = 13;
int GREEN = 12;
int sensor_test;
int reverse_test;

void setup()
{
  pinMode(RED,OUTPUT);
  pinMode(GREEN,OUTPUT);
  pinMode(pin7, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(sensor,INPUT);
  pinMode(reverse, INPUT);
  pinMode(EMPTY, INPUT);
}

void loop()
{
  int sensor_state = digitalRead(sensor); //read the button condition
  int reverse_state = digitalRead(reverse); //read the button condition
  int EMPTY_state = digitalRead (EMPTY);
  
  if(sensor_state == HIGH && sensor_test == LOW)  
  {
  analogWrite(motorSpeed,255); 
  digitalWrite(pin2, HIGH);   //set the forward pin of L293D driver to high
  digitalWrite(pin7, LOW);    //set the reverse pin of L293D driver to low
  digitalWrite(GREEN,HIGH);
  digitalWrite(RED,LOW); 
  delay(1000);
  digitalWrite(GREEN,LOW);
  digitalWrite(pin2, LOW);
  sensor_test = HIGH;
  }

  else if(sensor_state == LOW)
  {
    sensor_test = LOW;
  }
  
  
  else if(reverse_state == HIGH && reverse_test == LOW)
  {
  analogWrite(motorSpeed,255);   //set the DC motor speed to 150 (not rpm)
  digitalWrite(pin2, LOW);    //set the forward pin of L293D driver to low
  digitalWrite(pin7, HIGH);   //set the reverse pin of L293D driver to high
  digitalWrite(GREEN,HIGH);
  digitalWrite(RED,LOW); 
  delay(1000);
  digitalWrite(GREEN,LOW);
  digitalWrite(pin7, LOW);
  reverse_test = HIGH;
  }

  else if(reverse_state == LOW)
  {
    reverse_test = LOW;
  }

  else if(EMPTY_state == HIGH)
  {
    digitalWrite(RED,HIGH);
    digitalWrite(GREEN,LOW);
  }

  else
  {
  analogWrite(motorSpeed,0);
  digitalWrite(pin2, LOW);
  digitalWrite(pin7, LOW);
  digitalWrite(GREEN,LOW);
  digitalWrite(RED,LOW);
  }
}

anyone can help me?? :cry:

I suspect your succession of IF and ELSE IFs is poorly conceived.

Why is there an ELSE on this line (for example) as it seems to bear no relation to the earlier tests

else if(reverse_state == HIGH && reverse_test == LOW)

Can you describe in English (not code) what you want to happen.

...R

i want to make the motor is rotated foward for 1second when the sensor button is pressed and it have to press again to make the motor rotate again. you know like DIFU function in PLC. yes i get it by using this coding.

if(sensor_state == HIGH && sensor_test == LOW )  
  {
  analogWrite(motorSpeed,255); 
  digitalWrite(pin2, HIGH);   //set the forward pin of L293D driver to high
  digitalWrite(pin7, LOW);    //set the reverse pin of L293D driver to low
  digitalWrite(GREEN,HIGH);
  digitalWrite(RED,LOW); 
  delay(1000);
  digitalWrite(GREEN,LOW);
  digitalWrite(pin2, LOW);
  sensor_test = HIGH;
  }

  else if(sensor_state == LOW)
  {
    sensor_test = LOW;
  }

but when i pressed reverse and empty button, the led and motor reverse is not function.

Robin2:
I suspect your succession of IF and ELSE IFs is poorly conceived.

Why is there an ELSE on this line (for example) as it seems to bear no relation to the earlier tests

else if(reverse_state == HIGH && reverse_test == LOW)

Can you describe in English (not code) what you want to happen.

...R

Your code has a succession of IF and ELSE clauses.

Can you please describe in English how you want that to work?

This is the sequence from Reply #8 without the confusion of the action code

  if(sensor_state == HIGH && sensor_test == LOW)  {
     sensor_test = HIGH;
  }
  else if(sensor_state == LOW)  {
    sensor_test = LOW;
  }
  else if(reverse_state == HIGH && reverse_test == LOW)  {
  reverse_test = HIGH;
  }
  else if(reverse_state == LOW)  {
    reverse_test = LOW;
  }
  else if(EMPTY_state == HIGH)  {
  }
  else  {

  }

...R

like this, i want to make the motor rotated when the pushbutton is pressed.
but what i have got is the motor start delay after the push button is released and its stop.
i have a time graph with this. i hope you can help me and i don't this my "if" instruction is false

Robin2:
Your code has a succession of IF and ELSE clauses.

Can you please describe in English how you want that to work?

This is the sequence from Reply #8 without the confusion of the action code

  if(sensor_state == HIGH && sensor_test == LOW)  {

sensor_test = HIGH;
 }
 else if(sensor_state == LOW)  {
   sensor_test = LOW;
 }
 else if(reverse_state == HIGH && reverse_test == LOW)  {
 reverse_test = HIGH;
 }
 else if(reverse_state == LOW)  {
   reverse_test = LOW;
 }
 else if(EMPTY_state == HIGH)  {
 }
 else  {

}




...R

delay.jpg

Image from Reply #13 so we don't have to download it. See this Image Guide

7abcbbe55eeda340ddc999b464e8b6b9f060041f.jpg

...R

That diagram suggests that you want the LED and the motor to turn on with the rising edge of the sensor and then to stay on for some length of time. Is that correct?

...R