Delay() vs Millis()

I have a program I am using to try and replace the delay() fn with millis().
It runs a motor in one direction for a period of time and then in the opposite. If I use the delay() fn in the Pause()fn it works perfectly. If I try and replace it with the Millis() fn (from Blinkwithoutdelay) it does not. I am obviously missing something, but what?

int MotorRun = 11;
int Direction1 = 8;
int Direction2 = 13;
//int Dwell = 3000;
int Speed = 100;
int Millis;
unsigned long currentMillis;
unsigned long previousMillis = 0;
const long Dwell = 3000;

void setup() {
  Serial.begin(9600);
  pinMode(MotorRun, OUTPUT);
  pinMode(Direction1, OUTPUT);
  pinMode(Direction2, OUTPUT);
  Serial.println("In Setup");
  currentMillis = Millis;
}

void FWD() {
  digitalWrite(Direction2, HIGH);  //Establishes forward direction of Channel B
  digitalWrite(Direction1, LOW);   //Disengage the Brake for Channel B
  analogWrite(MotorRun, Speed);    //Spins t // put your main code here, to run repeatedly:
  Pause(Speed, Dwell);
  Stop();
  Pause(Speed, Dwell);
}

void REV() {
  digitalWrite(Direction2, LOW);
  digitalWrite(Direction1, LOW);
  analogWrite(MotorRun, Speed);
  Pause(Speed, Dwell);
  Stop();
  Pause(Speed, Dwell);
}

void Pause(int Speed, int Dwell) {
  //delay(Dwell); // Replace with Millis()
  {
    Serial.println(" In Pause Function ");
    unsigned long currentMillis = millis();
    Serial.println(Speed);
    if (currentMillis - previousMillis >= Dwell) {
      previousMillis = currentMillis;
    }
    analogWrite(MotorRun, Speed);
  }
}

void Stop() {
  analogWrite(MotorRun, 0);
}

void loop() {

  FWD();
  REV();
}

What are you expecting the Pause() function to do ?

Perhaps think of it a flipping a switch according to a schedule, rather then holding a button down for a lengthy period/delay/pause.

The BWoD scheme checks the schedule thousands of times per second, and then quickly flips a switch when appropriate.

Your FWD() routine flips the switch and then stands there at the switch twiddling its thumbs for 3000 milliseconds.

To continue the current FWD, REV, Stop action for the period Dwell. As I say it does exactly that when I use Delay() but not when I try and use Millis().

Oops. I'm sorry, your routine named "Pause()" checks the schedule, immediately finds it isn't yet time, and then flips the switch back.

Either way, your Pause() function blocks until the time has elapsed. Why bother?

I'm trying to learn to use Millis() instead of delay.

void Pause(int Speed, int Dwell) {
  //delay(Dwell); // Replace with Millis()
  {
    Serial.println(" In Pause Function ");
    unsigned long currentMillis = millis();
    Serial.println(Speed);
    while (millis() - previousMillis <= Dwell) {
      // do nothing
    }
    previousMillis = currentMillis;
    analogWrite(MotorRun, Speed);
  }
}

but this is the same as delay()...

Thank you. My understanding, from other fora, is that using While blocks the program. So, in this case, it is impossible not to block the rest of the program?

If you don't want Pause() to block, then you will need to refactor your code into more of a state machine. You can not just call Pause(), Stop(), Pause() if the Pause() function returns before it is done. If you google "Finite State Machine" you will get lots of examples.

Basically, you keep track of what state you are in and when to transition to the next state

1 Like

Thank you very much for your time. I shall look at that.

@t0ny ,

The basics of what you need are in this tutorial:

There are others too that address related things.

1 Like

Thank you. I shall look at that.

It certainly doesn't do what is required but how does it block execution of the sketch ?

2 Likes

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