Help needed for using millis and PWM to decrement DC motor speed over time.

Hi there,

A brief overview of my project and what I'm trying to achieve.
I have a 12v DC wiper motor which I'm using as part of 'baby rocker design' and I plan to control the motor functions via an IR Remote.
I plan to have an auto sequence whereby when an IR signal is sent, the motor will run for a certain period of time at a certain speed before slowing down and running for some time again before slowing down again and so on but I would like to be able to stop the sequence at given time using an IR signal.
I'm using an Arduino Mega 2560 with a BTS7960 motor driver connected to PWM pins 3,4,6, and 7 with an Ir Receiver connected to pin 11, 5v and ground.
I'm aware that using a delay function to decrement the speed of the motor over time will block all other functions thus not allowing me to stop the sequence at any point via an IR signal.
Included is my code so far, with the delay function added to show timescales I would like to slow the motor down over.
If anyone could let me know if its possible to achieve this using the millis function and if so could perhaps show me an example of the coding as I've tried to implement it following the 'Blink without delay' tutorial but to no avail.
Thanks, Andrew.

#include <IRremote.h>

int IRpin = 11;  // Pin for the IR sensor

int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable 


#define Button2        0xFF18E7 // Start Motor Auto Mode
#define PowerButton    0xFFA25D // Stop Motor 


IRrecv irrecv(IRpin);

decode_results results;

void(* resetFunc) (void) = 0;  // Declare reset fuction at address 0




void setup() {
  
Serial.begin(9600);

pinMode(RPWM, OUTPUT);
pinMode(R_EN, OUTPUT);
  
pinMode(LPWM, OUTPUT);
pinMode(L_EN, OUTPUT);
 

digitalWrite (R_EN, HIGH); 
digitalWrite (L_EN, HIGH);

irrecv.enableIRIn();  // Start the receiver
}

void loop() {

while(!(irrecv.decode(&results))); //Wait until button on IR remote is pressed
 
if (irrecv.decode(&results)) // When button is pressed & code is received
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

{     

if(results.value==Button2)  // if code is 0xFF18E7 start auto mode

{      
          analogWrite(LPWM,102); // runs motor at 40%
          delay (60000); // for 1 minute
          analogWrite(LPWM,90); // runs motor at 35%
          delay (60000); // for 1 minute
          analogWrite(LPWM,77); // runs motor at 30%
          delay (60000); // for 1 minute

}

else if(results.value==PowerButton)  // if code is 0xFFA25D

{
   
         digitalWrite (RPWM, LOW);
         analogWrite  (LPWM, 0);  // stop motor and reset
         resetFunc(); //call reset
}


}}

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

In your case you need to save the value of millis() when the first speed reduction is required and keep checking if the time has expired. When it has save the new value of millis(), reduce the speed and repeat.

As well as checking if the time has expired your program can check for input from the IR.

...R

Thanks for your advice Robin I've tried to follow the examples you provided but still cannot get the speed reductions required. Any advice based on my sketch?

Thanks Andrew

#include <IRremote.h>

unsigned long CurrentMillis = 0;
unsigned long PrevMillis = 0;

const int Interval1 = 10000;


int IRpin = 11;  // Pin for the IR sensor

int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable 



#define Button2        0x20DF48B7 // Start Motor Auto Mode
#define PowerButton    0x20DF10EF // Stop Motor 


IRrecv irrecv(IRpin);

decode_results results;

void(* resetFunc) (void) = 0;  // Declare reset fuction at address 0


void setup() {
  
Serial.begin(9600);


pinMode(RPWM, OUTPUT);
pinMode(R_EN, OUTPUT);
  
pinMode(LPWM, OUTPUT);
pinMode(L_EN, OUTPUT);
 

digitalWrite (R_EN, HIGH); 
digitalWrite (L_EN, HIGH);

irrecv.enableIRIn();  // Start the receiver
}

void loop() {

CurrentMillis = millis(); // snapshots time,


while(!(irrecv.decode(&results))); //Wait until button on IR remote is pressed
 
if (irrecv.decode(&results)) // When button is pressed & code is received
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

    

if(results.value==Button2)  // if code is 0xFF18E7 start auto mode

{
  {
     analogWrite(LPWM,102); // runs motor at 40%
    
  }



if((CurrentMillis - PrevMillis) >= Interval1)
  
  {  
    analogWrite(LPWM,90); // runs motor at 35%
    PrevMillis = CurrentMillis;
     
  }



if((CurrentMillis - PrevMillis) >= Interval1)
  
  {  
     analogWrite(LPWM,77); // runs motor at 30%
     PrevMillis = CurrentMillis;
  
  }
}


if(results.value==PowerButton)  // if code is 0xFFA25D

{
   
         digitalWrite (RPWM, LOW);
         analogWrite  (LPWM, 0);  // stop motor and reset
         resetFunc(); //call reset
}


}

AndrewC1988:
Thanks for your advice Robin I've tried to follow the examples you provided but still cannot get the speed reductions required. Any advice based on my sketch?

Your program is very badly formatted so I can't tell what parts go together. I tried to fix that but I got stuck. Use the Auto Format tool in the IDE to indent the code consistently. I suspect that will make some issues obvious to you.

This looks inappropriate

while(!(irrecv.decode(&results))); //Wait until button on IR remote is pressed

nothing can be checking millis() while the program is stuck in that WHILE loop - replace WHILE with IF

These lines look strange

if((CurrentMillis - PrevMillis) >= Interval1)
  
  {  
    analogWrite(LPWM,90); // runs motor at 35%
    PrevMillis = CurrentMillis;
     
  }



if((CurrentMillis - PrevMillis) >= Interval1)
  
  {  
     analogWrite(LPWM,77); // runs motor at 30%
     PrevMillis = CurrentMillis;
  
  }
}

I think the first IF statement will always be checked and never the second

I wonder if you have the wrong understanding of the role of loop() - it should be allowed to repeat as fast as possible and nothing waits for anything else.

...R

Thanks again Robin for your input and I'm sure you can tell I'm a complete novice hence my seeking advice. I've tried to follow your advice on the formatting and things are starting to click and I can see you're right when it comes to the first IF statement, it is always checked and never the second so the motor remains at a constant speed.
Attached is my loop, maybe you can suggest a way of sorting my issue.

Thanks, Andrew

void loop() {

  CurrentMillis = millis(); // snapshots time,



  if (!(irrecv.decode(&results))); { //Wait until button is pressed



    if (results.value == Button2) { // if code is 0xFF18E7 start auto mode

      analogWrite(LPWM, 102); // runs motor at 40%
    }


    else if   ((CurrentMillis - PrevMillis) >= Interval1) {

      analogWrite(LPWM, 90); // runs motor at 35%
      PrevMillis = CurrentMillis;
    }



    else if  ((CurrentMillis - PrevMillis) >= Interval1) {

      analogWrite(LPWM, 77); // runs motor at 30%
      PrevMillis = CurrentMillis;
    }



    else if  (results.value == PowerButton) { // if code is 0xFFA25D

      digitalWrite (RPWM, LOW);
      analogWrite  (LPWM, 0);  // stop motor and reset
      resetFunc(); //call reset
    }



  }

Ok, theres clearly something I'm missing here. I tried to follow Delta_G advice and to a degree I can say that that solution does work, however the speed is decreased in a fraction of a second and no matter what I try nothing seems to alter the fact that the first IF statement is the only one satisfied (I think).
I have the first interval at 10 secs, the second at 20 secs, third at 40 secs and the fourth at 60 secs.

I have x= 102 and cannot go below 77.

The serial monitor shows the initial speed which I presume follows that of the first interval (10 secs) and then the reduction takes place in a fraction of a second.

11:27:25.907 -> 102

11:27:35.996 -> 102
11:27:35.996 -> 97
11:27:35.996 -> 92
11:27:36.031 -> 87
11:27:36.031 -> 82
11:27:36.031 -> 77

Any ideas???

void loop() {

  CurrentMillis = millis(); // snapshots time,


  if (CurrentMillis - PrevMillis >= Interval) {
    x = x - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (x < 77) {
      x = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval1) {
    x = x - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (x < 77) {
      x = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval2) {
    x = x - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (x < 77) {
      x = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval3) {
    x = x - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (x < 77) {
      x = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  analogWrite(LPWM, x);   // set the speed on the motor
  Serial.println (LPWM = x);
}

AndrewC1988:
Ok, theres clearly something I'm missing here

Please always post a complete program.

Also, please use meaningful names for variables and not things like 'x'. Using single-character variable names makes it almost impossible to find instances of a variable with Search. And using meaningful variable names often brings logical problems into view.

...R

x = x - 5;   // reduce the speed setting by 5 (or whatever number you want)
 ...
    x = x - 5;   // reduce the speed setting by 5 (or whatever number you want)
    }

If instead of "x" you had used a variable called, say, "motorSpeed", you could have writtenmotorSpeed -= speedIncrement; and the comment wouldn't be needed because the intent would be obvious.

Ok thanks again. Here is the updated sketch but I've removed any IR functions to simplify as I would primarily like to get the speed reduction loop working first.
Robin, you seem to be very knowledgeable and I'm grateful for your input so far but as I stated before I'm a novice, therefore I find it hard to decipher exactly what you mean sometimes so bare with me if my sketches are complete nonsense. Perhaps you could provide an example sketch of what you would expect my loop to look like based on my requirements.

Thanks, Andrew

unsigned long CurrentMillis = 0;
unsigned long PrevMillis    = 0;


const int Interval =  10000;
const int Interval1 = 20000;
const int Interval2 = 40000;
const int Interval3 = 60000;

int motorSpeed = 102;


int IRpin = 11;  // Pin for the IR sensor

int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable



void setup() {

  Serial.begin(9600);

  pinMode(RPWM, OUTPUT);
  pinMode(R_EN, OUTPUT);

  pinMode(LPWM, OUTPUT);
  pinMode(L_EN, OUTPUT);


  digitalWrite (R_EN, HIGH);
  digitalWrite (L_EN, HIGH);

}

void loop() {

  CurrentMillis = millis(); // snapshots time,


  if (CurrentMillis - PrevMillis >= Interval) {
    motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (motorSpeed < 77) {
      motorSpeed = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval1) {
    motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (motorSpeed < 77) {
      motorSpeed = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval2) {
    motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (motorSpeed < 77) {
      motorSpeed = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval3) {
    motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (motorSpeed < 77) {
      motorSpeed = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }

  }

  analogWrite(LPWM, motorSpeed);   // set the speed on the motor
  Serial.println (LPWM = motorSpeed);
}
  Serial.println (LPWM = motorSpeed);

Really bad idea.
Just print the motorSpeed variable.

From Reply #9

if (CurrentMillis - PrevMillis >= Interval) {
    motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (motorSpeed < 77) {
      motorSpeed = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

  else if (CurrentMillis - PrevMillis >= Interval1) {
    motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
    if (motorSpeed < 77) {
      motorSpeed = 77;     // make sure we don't go out of bounds
      PrevMillis = CurrentMillis;
    }
  }

You have two different "states" in your system and your code does not distinguish between them. There are different intervals and there are different speeds within an interval

Something like this might work
  if (interval == 0) {
    if (CurrentMillis - startTimeInterval0 >= Interval) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 77) {
         motorSpeed = 77;     // make sure we don't go out of bounds
         interval = 1; // we are finished with this stage so move on to the next one
      }
      PrevMillis = CurrentMillis; // this should update even though min has not been reached
     }
   }

  else if (interval == 1) {
    if (CurrentMillis - PrevMillis >= Interval1) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 77) {
         motorSpeed = 77;     // make sure we don't go out of bounds
         interval = 2;
      }
      PrevMillis = CurrentMillis;
   }
  }

...R

Many thanks for your input guys but I can't get this to work. Going by your idea Robin I still get the same results. The speed stays constant for 10 secs then drops down drastically in a fraction of a second.

I fear I'll have give up on this as my lack of knowledge is really hindering my progress.

Thanks, Andrew

My code

unsigned long CurrentMillis = 0;
unsigned long PrevMillis    = 0;
unsigned long startTimeInterval0 = 0;

const int Interval =  10000;
const int Interval1 = 20000;
const int Interval2 = 40000;
const int Interval3 = 60000;

int motorSpeed = 102;
int interval;



int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable



void setup() {

  Serial.begin(9600);

  pinMode(RPWM, OUTPUT);
  pinMode(R_EN, OUTPUT);

  pinMode(LPWM, OUTPUT);
  pinMode(L_EN, OUTPUT);


  digitalWrite (R_EN, HIGH);
  digitalWrite (L_EN, HIGH);

}

void loop() {

  CurrentMillis = millis(); // snapshots time,


  if (interval == 0) {
    if (CurrentMillis - startTimeInterval0 >= Interval) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 77) {
        motorSpeed = 77;     // make sure we don't go out of bounds
        interval = 1; // we are finished with this stage so move on to the next one
      }
      PrevMillis = CurrentMillis; // this should update even though min has not been reached
    }
  }

  else if (interval == 1) {
    if (CurrentMillis - PrevMillis >= Interval1) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 77) {
        motorSpeed = 77;     // make sure we don't go out of bounds
        interval = 2;
      }
      PrevMillis = CurrentMillis;
    }
  }


  // set the speed on the motor
  analogWrite (LPWM, motorSpeed);
  Serial.println (motorSpeed);
}

First, I should not have had startTimeInterval0. It should just be PrevMillis. I had been thinking of a different approach and forgot to change back to PrevMillis. I know it was my mistake but the fact that there was a variable in splendid isolation that was not used anywhere else should have raised a big question in your mind.

I was assuming you would apply a little logic - for example why have interval = 2; when you don't have any code for interval 2.

And at the end of interval 0 shouldn't this

if (motorSpeed < 77) {
        motorSpeed = 77;

be

if (motorSpeed < 77) {
        motorSpeed = 102;

so as to get the whole started again?

Or maybe in interval 1 the speed should be increasing from 77 to 102?

When you get stuck with a programming problem a very good approach is to get a pencil and a note pad and go through the code line by line writing down the values from each line using your brain as the computer.

...R

I was assuming you would apply a little logic

You assumed wrong.

I did initially wonder what 'startTimeInterval0' meant and assumed it was in fact 'PrevMillis' but after trying that and seeing no change I inserted startTimeInterval0 before uploading the code again incase my judgement was wrong.
When I asked for an example I obviously took your reply too literally. Like I keep saying, I'm a complete novice and find it hard to decipher your hints or pointers.

So this time the loop does in fact reduce the speed accordingly but only following the first IF statement i.e. it updates every 10 secs.

I'm unsure if the motor speed for each interval should be 102 or the speed at which the motor should be running for that interval but changing between this provides no change. Perhaps its my incorrect use of braces that does not allow the other ELSE IF statements to be run.

unsigned long CurrentMillis = 0;
unsigned long PrevMillis    = 0;


const int Interval  =  10000;
const int Interval1 =  20000;
const int Interval2 =  30000;

int motorSpeed = 102;
int interval;



int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable



void setup() {

  Serial.begin(9600);

  pinMode(RPWM, OUTPUT);
  pinMode(R_EN, OUTPUT);

  pinMode(LPWM, OUTPUT);
  pinMode(L_EN, OUTPUT);


  digitalWrite (R_EN, HIGH);
  digitalWrite (L_EN, HIGH);

}

void loop() {

  CurrentMillis = millis(); // snapshots time,

  if (interval == 0) {
    if (CurrentMillis - PrevMillis >= Interval) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 77) {
        motorSpeed = 102;     // make sure we don't go out of bounds
        interval = 1; // we are finished with this stage so move on to the next one
      }
      
      PrevMillis = CurrentMillis; // this should update even though min has not been reached
    }


    else if  (interval == 1 )
      if (CurrentMillis - PrevMillis >= Interval1) {
        motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
        if (motorSpeed < 77) {
          motorSpeed = 102;     // make sure we don't go out of bounds
          interval = 2;
        }
        
        PrevMillis = CurrentMillis;
      }


      else if (interval == 2 )
        if (CurrentMillis - PrevMillis >= Interval2) {
          motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
          if (motorSpeed < 77) {
            motorSpeed = 102;     // make sure we don't go out of bounds
          }
          
          PrevMillis = CurrentMillis;
        }



    analogWrite (LPWM, motorSpeed); // set the speed on the motor
    Serial.println (motorSpeed);
  }
}

Why have you complicated things by introducing a third interval before you get the first two working?

Have you worked through the code manually like I suggested?

And now seems like a good time to add Serial.print() statements into your program so you can monitor what it is actually doing.

...R

OK sorry, you're right keep it simple. I did do exactly that and from what I can see the first IF statement will always be satisfied when updating the PrevMillis because of the shortest interval time (10secs). This is what led me to believe theres an issue with the braces in the loop. It seems no matter what angle I approach it from the first IF statement will always be satisfied and never the others.

Thanks, Andrew

This is a problem that can be solved by careful debugging.

And the first thing that occurs to me is how do you know that the second interval is not being used - have you put any telltale Serial.print() statements in it?

I presume you have tidied up the program subsequent to Reply #14. Post the latest version of the program and post a sample of the output in the Serial monitor when it runs.

...R

OK thats great, you're the man Robin!

Well, it seems that drinking beer has given me some sort of abstract outlook and my following code now seems to work based on the interval periods set. I have included 3 separate intervals just to make sure it wasn't luck and the loop is in fact following the code.

It does seem however that you knew all along what each outcome would be based on the hints you provided, or maybe I'm reading too much into it..

Again, down to my lack of experience and knowledge I'm still struggling to debug appropriately to show each stage in the serial monitor. I recorded the times at which the speed change takes place instead.

21:15:33.017 -> 102
21:15:43.975 -> 97
21:16:03.994 -> 92
21:16:34.042 -> 87

How would you suggest I debug properly and incorporate the IR statement from my original requirements into the loop?

Thanks for your help, Andrew

unsigned long CurrentMillis = 0;
unsigned long PrevMillis    = 0;


const int Interval  =  10000;
const int Interval1 =  20000;
const int Interval2 =  30000;

int motorSpeed = 102;
int interval;

int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable



void setup() {

  Serial.begin(9600);

  pinMode(RPWM, OUTPUT);
  pinMode(R_EN, OUTPUT);

  pinMode(LPWM, OUTPUT);
  pinMode(L_EN, OUTPUT);


  digitalWrite (R_EN, HIGH);
  digitalWrite (L_EN, HIGH);

}

void loop() {

  CurrentMillis = millis(); // snapshots time,

  if (interval == 0) {

    if (CurrentMillis - PrevMillis >= Interval) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 102) {
        motorSpeed = 97;     // make sure we don't go out of bounds
        interval = 1; // we are finished with this stage so move on to the next one
      }
      PrevMillis = CurrentMillis; // this should update even though min has not been reached
    }
  }

  else if  (interval == 1 ) {

    if (CurrentMillis - PrevMillis >= Interval1) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 97) {
        motorSpeed = 92;     // make sure we don't go out of bounds
        interval = 2;
      }
      PrevMillis = CurrentMillis;
    }
  }

  else if  (interval == 2 ) {

    if (CurrentMillis - PrevMillis >= Interval2) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 92) {
        motorSpeed = 87;     // make sure we don't go out of bounds
      }
      PrevMillis = CurrentMillis;
    }
  }

  analogWrite (LPWM, motorSpeed); // set the speed on the motor
  Serial.println (motorSpeed);

}

AndrewC1988:
I recorded the times at which the speed change takes place instead.

21:15:33.017 -> 102

I don't see any Serial.print() commands in your code that produce that data.

Oftentimes I just add statements to my code that are as simple as Serial.println("In interval1"); and Serial.println("In interval2").

Sometimes they are as simple as Serial.println("here") and Serial.println("here2").

The purpose is to get the program to report what it is doing. And you need to think about what sort of information would help you to decide what changes might be necessary. No doubt one gets better at this with experience, but debugging is as much an essential skill for a programmer as the ability to type with one finger.

Another useful feature would be to slow the program down - maybe put (temporarily) delay(500) at the bottom of loop() and make the time intervals significantly longer so it is easier to observe changes, and to be able to keep up with the print() statements.

...R

OK, thanks for your advice. Ive now added in the delay, the Serial.print and extended the interval periods. But by extending the intervals it seems that the loop never advances the first interval now (interval0).

11:04:13.433 -> In interval0
11:04:13.433 -> 102

11:05:26.455 -> 102
11:05:26.933 -> In interval0

unsigned long CurrentMillis = 0;
unsigned long PrevMillis    = 0;


const int Interval  =  60000;
const int Interval1 =  120000;
const int Interval2 =  180000;

int motorSpeed = 102;
int interval;

int RPWM = 3; // Right PWM
int R_EN = 4; // Right PWM Enable


int LPWM = 6; // Left PWM
int L_EN = 7; // Left PWM Enable


void setup() {

  Serial.begin(9600);

  pinMode(RPWM, OUTPUT);
  pinMode(R_EN, OUTPUT);

  pinMode(LPWM, OUTPUT);
  pinMode(L_EN, OUTPUT);


  digitalWrite (R_EN, HIGH);
  digitalWrite (L_EN, HIGH);

}

void loop() {

  CurrentMillis = millis(); // snapshots time,

  if (interval == 0) {
    Serial.println("In interval0");

    if (CurrentMillis - PrevMillis >= Interval) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 102) {
        motorSpeed = 97;     // make sure we don't go out of bounds
        interval = 1; // we are finished with this stage so move on to the next one
      }
      PrevMillis = CurrentMillis; // this should update even though min has not been reached
    }
  }

  else if  (interval == 1 ) {
    Serial.println("In interval1");

    if (CurrentMillis - PrevMillis >= Interval1) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 97) {
        motorSpeed = 92;     // make sure we don't go out of bounds
        interval = 2;
      }
      PrevMillis = CurrentMillis;
    }
  }

  else if  (interval == 2 ) {
    Serial.println("In interval2");

    if (CurrentMillis - PrevMillis >= Interval2) {
      motorSpeed = motorSpeed - 5;   // reduce the speed setting by 5 (or whatever number you want)
      if (motorSpeed < 92) {
        motorSpeed = 87;     // make sure we don't go out of bounds
      }
      PrevMillis = CurrentMillis;
    }
  }

  analogWrite (LPWM, motorSpeed); // set the speed on the motor
  Serial.println (motorSpeed);
  delay (500);

}