2

For the last couple of day I've been trying and failed many times just to not use the delay() funtion in Arduino. I have to admitted that my coding skill are extremely bad.

What i trying to do is: If button is pressed: Motor A and B move for 1 second at slow speed == > Motor A keep moving but at fast speed and motor B stop. else: Motor A and B both stop.

I managed to wrote the code by using delay function for that 1 second. However i got no idea how to do it WITHOUT DELAY() there will be sensor reading as well at the same time, i cant afford that 1 second delay of sensor reading).

Here is my code:

int dir1PinA = 2;
int dir2PinA = 3;
int speedPinA = 9; // Needs to be a PWM pin to be able to control motor speed

// Motor 2
int dir1PinB = 4;
int dir2PinB = 5;
int speedPinB = 10; // Needs to be a PWM pin to be able to control motor speed

int button = 6;

void setup() {  // Setup runs once per reset
// initialize serial communication @ 9600 baud:
Serial.begin(9600);

//Define L298N Dual H-Bridge Motor Controller Pins

pinMode(dir1PinA,OUTPUT);
pinMode(dir2PinA,OUTPUT);
pinMode(speedPinA,OUTPUT);
pinMode(dir1PinB,OUTPUT);
pinMode(dir2PinB,OUTPUT);
pinMode(speedPinB,OUTPUT);

// Define button pin
pinMode(button,INPUT);

}

void loop() {
  if( button == LOW){           // if button is pressed
    // Motor A (move slow) and B  moving
    analogWrite(speedPinA, 100);//Sets speed variable via PWM 
    digitalWrite(dir1PinA, LOW);
    digitalWrite(dir2PinA, HIGH);
    analogWrite(speedPinB, 255);
    digitalWrite(dir1PinB, LOW);
    digitalWrite(dir2PinB, HIGH);
    delay(1000);

    // After 1 second Motr A (move fast)and B stop every time button pressed
    analogWrite(speedPinA, 255);//Sets speed variable via PWM 
    digitalWrite(dir1PinA, LOW);
    digitalWrite(dir2PinA, HIGH);
    analogWrite(speedPinB, 0);
    digitalWrite(dir1PinB, LOW);
    digitalWrite(dir2PinB, LOW);
  }
  else
  {
    // Both motor not moving
    analogWrite(speedPinA, 0);//Sets speed variable via PWM 
    digitalWrite(dir1PinA, LOW);
    digitalWrite(dir2PinA, LOW);
    analogWrite(speedPinB, 0);
    digitalWrite(dir1PinB, LOW);
    digitalWrite(dir2PinB, LOW);
  }
}

Please point me out the direction or give me an example of code. And I have already try the Blinkwithoutdelay Arduino example but it does not work for this case.

Very much appreciated.

  • Did... you... just misspell else as esle!? – Bradman175 Feb 19 '17 at 3:03
  • 3
    This has been asked many times, both here and on the Arduino Forum. For one treatment (by me) see this. – Nick Gammon Feb 19 '17 at 4:03
  • Thanks for the link. Ill have a look and will try my best. Ha:) – zuzu Feb 19 '17 at 4:20
  • Also posted on Arduino Forum – Nick Gammon Feb 19 '17 at 6:59
  • you need a state machine with two states (unpressed, pressing). You also save a timestamp each time the state changes. You can compare the last change's timestamp with the system time to determine if it's time to move to the next state. "unpressed" changes to "pressing" upon a button press (if state is unpressed). "pressing" changes to "unpressed" if it's been 1000ms since the last change AND the button is not pressed. – dandavis Feb 19 '17 at 8:46
1

Assuming the button isn't held down for 50 days straight, you can use the millis() function and basically set a marker of the current time when the user pushes the button down. To do this, you need to detect when the user switches from off to on, not when while the button is pushed or you'll be resetting the marker every time.

Then you record the time every loop while the button is pushed down. If the current time is more than one second after the time recorded by the marker, you switch motor B off and make motor A as fast speed like you said. When the button is off, like you said set both motors to off.

  • The 49.71-day millis() rollover is relevant only if button presses longer than that are allowed. For any shorter interval, unsigned long arithmetic works ok, even if a rollover occurs during the interval. – James Waldby - jwpat7 Feb 19 '17 at 9:29
  • Well i said that just incase he's pressing the button down for 50 days straight ^.^ – Bradman175 Feb 19 '17 at 10:26
  • I got the thing working. So thanks. The things is gonna run 3650 day. But the button only pressed for maximum 1 min. So it should be fine i guess. Anyway thanks for the advise guys – zuzu Feb 19 '17 at 10:57
1

You might want to use a timer. There are some libraries available for Arduino that precisely do that.

You can either use a library that implements a software timer (something similar to comparing millis(), but with powerful additional built-in features such as button debouncing, timed pulses, etc.) or use a library that deals with the hardware interrupts of the MCU.

As an example take a look at this particular library: Timer. I think you'll love it!

  • Thank youn I got the code working. Using millis() and a bunch of if. But i definitely have a look at the timer library. – zuzu Feb 19 '17 at 20:29
1

If button is pressed: Motor A and B move for 1 second at slow speed == > Motor A keep moving but at fast speed and motor B stop. else: Motor A and B both stop.

I would do a quick state machine:

STATE / button released: do nothing;
STATE / button pressed: run motors a+b;
STATE / run motor a+b: run motor a+b; if 1 second has passed, advance to just run motor a;
STATE / run motor a: run motor a at fast speed and stop motor b.

fairly easy to code as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.