Go Down

Topic: Without delay(). I know I know. But please help! (Read 1 time) previous topic - next topic

chasingsun

For the last couple of day I've been trying and failed many times just to not use the delay() funtions 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:
Code: [Select]
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);
  }
  esle
  {
    // Move 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.

Paul_KD7HB

Read, understand and try the examples in the sticky post at the top of the project guidance forum:
Demonstration code for several things at the same time.

If you can wrap your mind around that concept, you program to decide WHEN to do something and WHEN to stop that thing. The difference becomes the equivalent to your delay coding. Yes, it's different way of thinking, but after a bit you will learn to appreciate the power! And the rest of your program functions can proceed at normal speed.

Paul

sterretje

#2
Feb 19, 2017, 04:23 am Last Edit: Feb 19, 2017, 04:25 am by sterretje
Quote
Code: [Select]
  }
  esle
  {

?? ;)


Quote
Code: [Select]
  if ( button == LOW)           // if button is pressed
  {

The chances that button equals LOW are extremely slim ;) You have given button the value 6 and LOW is defined as 0. So the condition will always evaluate to false. You will need to read your button first using digitalRead().

Code: [Select]
void loop()
{
  int buttonState = digitalRead(button);
  if ( buttonState == LOW)           // if button is pressed
  {
    ...
    ...
  }
  else
  {
    ...
    ...
  }
}
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

chasingsun

?? ;)

The chances that button equals LOW are extremely slim ;) You have given button the value 6 and LOW is defined as 0. So the condition will always evaluate to false. You will need to read your button first using digitalRead().


Thank you very much for this mistake point out. I have fixed it.

sterretje

The principle is extremely easy once you grasp it.

When the button is pressed, you start a 'timing'.
Code: [Select]
void loop()
{
  // variable to store the time when the button was pressed
  static unsigned long startTime = 0;
}

Next you can set the startTime when the button is pressed; to prevent the startTime from being updated as long is the button is pressed, an additional check needs to be build in (checking if startTime equals zero). The below will also reset the timing if the button is released.
Code: [Select]
void loop()
{
  // variable to store the time when the button was pressed
  static unsigned long startTime = 0;

  // read the button
  int buttonState = digitalRead(button);

  // if pressed
  if (buttonState == LOW)
  {
    // if timing not started
    if(startTime == 0)
    {
      // set the start time
      startTime = millis();
    }
  }
  else
  {
    // set startTime to 0 so the next time you push the button the timing can be started again
    startTime = 0;
  }
}

Now, if startTime is not equal to zero, you can check startTime against the current time. According to your original code, this needs to be done as long as the button is pressed.
Code: [Select]

void loop()
{
  // variable to store the time when the button was pressed
  static unsigned long startTime = 0;

  // read the button
  int buttonState = digitalRead(button);

  // if pressed
  if (buttonState == LOW)
  {
    // if timing not started
    if(startTime == 0)
    {
      // set the start time
      startTime = millis();
    }
    else
    {
      // check time
      if(millis() - startTime >= 1000)
      {
        // 1 second passed
      }
    }
  }
  else
  {

    // set startTime to 0 so the next time you push the button the timing can be started again
    startTime = 0;
  }
}

Now the only thing that needs to be done is starting, uodating and stopping the motors at the right place in the code. Try to find where to do it in the above framework; if you fail to do it, it means that I did not explain properly ;)
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

chasingsun

The principle is extremely easy once you grasp it.

When the button is pressed, you start a 'timing'.
Code: [Select]
void loop()
{
  // variable to store the time when the button was pressed
  static unsigned long startTime = 0;
}

Next you can set the startTime when the button is pressed; to prevent the startTime from being updated as long is the button is pressed, an additional check needs to be build in (checking if startTime equals zero). The below will also reset the timing if the button is released.
Code: [Select]
void loop()
{
  // variable to store the time when the button was pressed
  static unsigned long startTime = 0;

  // read the button
  int buttonState = digitalRead(button);

  // if pressed
  if (buttonState == LOW)
  {
    // if timing not started
    if(startTime == 0)
    {
      // set the start time
      startTime = millis();
    }
  }
  else
  {
    // set startTime to 0 so the next time you push the button the timing can be started again
    startTime = 0;
  }
}

Now, if startTime is not equal to zero, you can check startTime against the current time. According to your original code, this needs to be done as long as the button is pressed.
Code: [Select]

void loop()
{
  // variable to store the time when the button was pressed
  static unsigned long startTime = 0;

  // read the button
  int buttonState = digitalRead(button);

  // if pressed
  if (buttonState == LOW)
  {
    // if timing not started
    if(startTime == 0)
    {
      // set the start time
      startTime = millis();
    }
    else
    {
      // check time
      if(millis() - startTime >= 1000)
      {
        // 1 second passed
      }
    }
  }
  else
  {

    // set startTime to 0 so the next time you push the button the timing can be started again
    startTime = 0;
  }
}

Now the only thing that needs to be done is starting, uodating and stopping the motors at the right place in the code. Try to find where to do it in the above framework; if you fail to do it, it means that I did not explain properly ;)
Thank you very much. I got the concept of what you are trying to explain. Ill give it ago and let you know the result. Once again thanks. :)

chasingsun

@sterretje: Thanks you so much. It's working like a charm. I managed to put a second timer within the first timer.

Problem sloved.

However, there is a thing called rollover with millis() funtion. Can anyone give me a clue how to avoid this??? :o  :o  :o

nickgammon

Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

nickgammon

However, there is a thing called rollover with millis() funtion. Can anyone give me a clue how to avoid this??? :o  :o  :o
Has Google crashed? That's unfortunate.

Try Googling "millis rollover arduino".


http://www.gammon.com.au/millis
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

chasingsun

Cross-posted here.
Thanks. Ill have a look on that one.

Has Google crashed? That's unfortunate.

Try Googling "millis rollover arduino".


http://www.gammon.com.au/millis
Google hasnt but Youtube have crashed number amount of views on Gangnam style video :)

Robin2

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up