Main millis within a function !

The subject topic of this post maybe wrong, best I could think of Sorry.... :o

I need to run a dc motor every 30secs run forward 2 secs and then backward 2 secs.
Using a servo or a relay is not an option for this test project.
This is my objective using an arduino and it works as a stand alone program

const int outA = 11;
const int outB = 12 ;

void setup() {
	pinMode(outA,OUTPUT);
	pinMode(outB,OUTPUT);
	digitalWrite(outA,LOW);  // Motor Stop 0
	digitalWrite(outB,LOW);  // Motor Stop 0
	delay (10000);   // Arduino settle down on Power ON !
}

void loop() {
	
	digitalWrite(outA,HIGH);  // Motor Forward +
	digitalWrite(outB,LOW);  // Motor Forward -
	delay(2000); // 2 seconds go forward
	digitalWrite(outA,LOW);  // Motor Backward -
	digitalWrite(outB,HIGH);  // Motor Backward +
	delay (2000); // 2 seconds go backward 
	digitalWrite(outA,LOW);  // Motor Stop 0
	digitalWrite(outB,LOW);  // Motor Stop 0
	delay(30000);  // 30 seconds wait
}

But I needed it to work as a function when called, so using millis I have managed it to get it working with the 2 second on/off

const int outA = 11;
const int outB = 12 ;

//ON and OFF Times 2 seconds
const unsigned int onTime = 2000;  
const unsigned int offTime = 2000;
 //Do Nothing Time
const unsigned int OverallTime = 30000; 

// Store the last time we used 
unsigned long previousMillis=0;

// Action wait period could be onTime or offTime
int interval = onTime;

// we keep track of the Output state on or off
 boolean AOutstate = true;  // ON
 boolean BOutstate = false;  // OFF


 void setup() {
  pinMode(outA, OUTPUT);
  pinMode(outB,OUTPUT);
}

void loop(){
  
  Motor_Action();
  
  }

void Motor_Action() {
  // Set the Outputs according to the loop state !
  digitalWrite(outA, AOutstate);
  digitalWrite(outB, BOutstate);
 
  // capture and keep track of the time/clock!
    unsigned long currentMillis = millis();
 
  // Check the time against the main time/clock!
  if ((unsigned long)(currentMillis - previousMillis) >= interval) {
    //Change the Output state 
      if (AOutstate) {
      // If Motor is currently Forward, set time to go Backward
      /*
	digitalWrite(outA,LOW);  // Motor Backward -
	digitalWrite(outB,HIGH);  // Motor Backward +
	delay(2000);
      */
      interval = offTime;

      
    }  
    else  if (BOutstate) {
      // If Motors is currently Backward, set time to go Forward
      /*
	digitalWrite(outA,HIGH);  // Motor Forward +
	digitalWrite(outB,LOW);  // Motor Forward -
	delay(2000);
      */

      interval = onTime;

    } 
       /*
      //#############  This Section ##################
        {                                                                      //####
        interval = OverallTime;                                         //####
        digitalWrite(outA,LOW);  // Motor Stop 0                //####
        digitalWrite(outB,LOW);  // Motor Stop 0                //####
         }                                                                    //####
      //#############                  ############ //####
*/
    // Toggle the Output pins state 
    AOutstate = !(AOutstate);
    BOutstate = !(BOutstate);
 

    // Save the current time to compare and check later
    previousMillis = currentMillis;
  }
}

Where I would like help is getting an overall time of 30 secs when the function waits with the digital out's LOW

any and all help is appreciated :slight_smile:

So you want it not to take any action for 30 seconds and not have the motor running?
Simply have the thing check if millis() is greater than 30000. Then it can handle the turning the motor on/off after millis exceeds 30000.
so

(if millis() > 30000){
domotorcontrol()
}

The suggestion in Reply #1 would just prevent the motor from working during the first 30 seconds after the Arduino is powered up or reset. I don't think that is what the OP wants.

@RajFM, post your millis() program without any irrelevant commented out pieces and I will have a look at it. I don't know what I should be looking at in the code in your Original Post.

I think what you need to do to have different times is to put different values in the variable interval depending on what stage your program is at.

...R

Yes you are correct, it waits for 30" first and then runs the loop without a break.

I have attached the file if it will be easier and also below , I have removed the extra comments,
what I don't have in this revised code is the 30" section when the program pulls down the outputs LOW and waits.

Thanks

const int outA = 11;
const int outB = 12 ;

//ON and OFF Times 2 seconds
const unsigned int onTime = 2000;  
const unsigned int offTime = 2000;
 //Do Nothing Time
const unsigned int OverallTime = 30000; 

// Store the last time we used 
unsigned long previousMillis=0;
unsigned long previousOverall_Millis = 0;

// Action wait period
int interval = onTime;

// we keep track of the Output state on or off
 boolean AOutstate = true;
 boolean BOutstate = false;



 void setup() {
  Serial.begin(115200);
  pinMode(outA, OUTPUT);
  pinMode(outB,OUTPUT);
}

void loop(){

  Motor_Action();

}



void Motor_Action() {
  // Set the Outputs according to the loop state !
  digitalWrite(outA, AOutstate);
  digitalWrite(outB, BOutstate);
  
    // capture and keep track of the time/clock!
    unsigned long currentMillis = millis();
 
  // Check the time against the main time/clock!
  if ((unsigned long)(currentMillis - previousMillis) >= interval) {
    //Change the Output state 
    if (AOutstate) {
 
      interval = offTime;
        Serial.println("Pump BACKWARD");   
    }
      
    else  if (BOutstate) {

      interval = onTime;
     Serial.println("Pump FORWARD");
    } 
  

    // Toggle the Output pins state 
    AOutstate = !(AOutstate);
    BOutstate = !(BOutstate);
   
    
    // Save the current time to compare and check later
    previousMillis = currentMillis;
  }
}

millis_pump.ino (1.36 KB)

RajFM:

  if ((unsigned long)(currentMillis - previousMillis) >= interval) {

the result of subtracting an unsigned long from an unsigned long is an unsigned long... no need to again cast it to an unsigned long

I need to run a dc motor every 30secs run forward 2 secs and then backward 2 secs.

That sounds like a state machine to me.

3 states

State 0 : wait 30 seconds then start the motor forward and change to state 1
State 1 : stay in this state for 2 seconds then change motor direction and change to state 2
State 2 : stay in this state for 2 seconds then turn off the motor and change to state 0

Pseudo code

switch (state)
{
  case 0:
    if 30 seconds has passed (use millis() for this)
      {
         start motor forward
         state = 1
         save millis() value
      }
   break

  case 1:
    if 2 seconds has passed
      {
         reverse motor direction 
         state = 2
         save millis() value
       } 
    break

  case 2:
    if 2 seconds has passed
      {
        stop motor 
         state = 0
         save millis() value
       } 
    break
}

Here is a starting point:

const int outA = 11;
const int outB = 12;

//ON and OFF Times 2 seconds
const unsigned int onTime = 2000;
const unsigned int offTime = 2000;
//Do Nothing Time
const unsigned int OverallTime = 30000;

byte counter;

// Store the last time we used
unsigned long previousMillis = 0;
unsigned long previousOverall_Millis = 0;
unsigned long currentMillis;

unsigned long operateMillis;

// Action wait period
int interval = onTime;

// we keep track of the Output state on or off
boolean AOutstate = true;
boolean BOutstate = false;



void setup()
{
  Serial.begin(115200);
  pinMode(outA, OUTPUT);
  pinMode(outB, OUTPUT);
}

void loop()
{
  // capture and keep track of the time/clock!
  currentMillis = millis();

  Motor_Action();

}

//***************************************************************
void Motor_Action()
{
  //***********************
  if (millis() - operateMillis < OverallTime)
  {
    //not time yet
    return;
  }

  //***********************
  // Set the Outputs according to the loop state !
  digitalWrite(outA, AOutstate);
  digitalWrite(outB, BOutstate);

  // Check the time against the main time/clock!
  if (currentMillis - previousMillis >= interval)
  {
    //Change the Output state
    if (AOutstate)
    {
      interval = offTime;
      Serial.println("Pump BACKWARD");
    }

    else  if (BOutstate)
    {
      interval = onTime;
      Serial.println("Pump FORWARD");
    }

    // Toggle the Output pins state
    AOutstate = !(AOutstate);
    BOutstate = !(BOutstate);

    // Save the current time to compare and check later
    previousMillis = currentMillis;

    //***********************
    counter++;
    if (counter > 2)
    {
      //initialize
      digitalWrite(outA, LOW);
      digitalWrite(outB, LOW);
      AOutstate = true;
      BOutstate = false;

      //set up next iteration
      operateMillis = millis();
      counter = 0;
    }
  }
}

Edit:
cosmetic changes.

RajFM:
Yes you are correct, it waits for 30" first and then runs the loop without a break.

Who is correct?

I thought you wanted the code to

  • do something
  • wait 30 secs
  • do the something again
  • wait 30 secs
  • do the something again
  • etc etc

...R

Robin2:
Who is correct?

I thought you wanted the code to

  • do something
  • wait 30 secs
  • do the something again
  • wait 30 secs
  • do the something again
  • etc etc

...R

Sorry should have clarified, it was for your reply for the suggestion in reply 1.

Thanks

I need to run a dc motor every 30secs

it was for your reply for the suggestion in reply 1

Yes you are correct, it waits for 30" first and then runs the loop without a break.

:o :confused: :-\ :cry:

BulldogLowell:
the result of subtracting an unsigned long from an unsigned long is an unsigned long... no need to again cast it to an unsigned long

Good catch, thank you for pointing out how I could/should streamline the code better, I have replaced it

if (currentMillis - previousMillis >= interval)

I need to run a dc motor every 30secs

See example in post #6

@larryd reply#6

Thank you for the revised code , I will test and play with it.

@ UKHeliBob

Thank you, I did read your sticky post on " Using millis() for timing. A beginners guide" before posting this post just to check if I missed anything and did learn a few tricks .

const int outA = 11;
const int outB = 12;

//ON and OFF Times 2 seconds
const unsigned int onTime  = 2000;
const unsigned int offTime = 2000;
//Do Nothing Time
const unsigned int OverallTime = 30000;

// Store the last time we used
unsigned long previousMillis = 0;
unsigned long previousOverall_Millis = 0;
unsigned long operateMillis;

// Action wait period
int interval = onTime;

// we keep track of the Output state on or off
byte AOutstate = HIGH;
byte BOutstate = LOW;

byte counter;


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

  pinMode(outA, OUTPUT);
  digitalWrite(outA, LOW);

  pinMode(outB, OUTPUT);
  digitalWrite(outB, LOW);

}

void loop()
{
  Motor_Action();

}

//***************************************************************
void Motor_Action()
{
  //***********************
  if (millis() - operateMillis < OverallTime)
  {
    //not time yet
    return;
  }

  //***********************
  // Check the time against the main time/clock!
  if (millis() - previousMillis >= interval)
  {
    // Save the current time to compare and check later
    previousMillis = millis();

    Serial.println (previousMillis);

    //***********************
    // Set the Outputs according to the loop state !
    digitalWrite(outA, AOutstate);
    digitalWrite(outB, BOutstate);

    //***********************
    if (counter > 1)
    {
      //initialize for next cycle
      counter = 0;
      digitalWrite(outA, LOW);
      digitalWrite(outB, LOW);
      Serial.println("Pump OFF \n");
      AOutstate = true;
      BOutstate = false;

      operateMillis = millis();

      return;
    }

    counter++;

    //***********************
    //Change the Output state
    if (AOutstate == HIGH)
    {
      interval = offTime;
      Serial.println("Pump BACKWARD");
    }

    else  if (BOutstate == HIGH)
    {
      interval = onTime;
      Serial.println("Pump FORWARD");
    }

    // Toggle the Output pins state
    AOutstate = !AOutstate;
    BOutstate = !BOutstate;
  }
}

@larryd Thank you for taking the time and solving my code , totally awesome!

Thanks

larryd:

const int outA = 11;

const int outB = 12;

//ON and OFF Times 2 seconds
const unsigned int onTime  = 2000;
const unsigned int offTime = 2000;
//Do Nothing Time
const unsigned int OverallTime = 30000;

// Store the last time we used
unsigned long previousMillis = 0;
unsigned long previousOverall_Millis = 0;
unsigned long operateMillis;

// Action wait period
int interval = onTime;

// we keep track of the Output state on or off
byte AOutstate = HIGH;
byte BOutstate = LOW;

byte counter;

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

pinMode(outA, OUTPUT);
  digitalWrite(outA, LOW);

pinMode(outB, OUTPUT);
  digitalWrite(outB, LOW);

}

void loop()
{
  Motor_Action();

}

//***************************************************************
void Motor_Action()
{
  //***********************
  if (millis() - operateMillis < OverallTime)
  {
    //not time yet
    return;
  }

//***********************
  // Check the time against the main time/clock!
  if (millis() - previousMillis >= interval)
  {
    // Save the current time to compare and check later
    previousMillis = millis();

Serial.println (previousMillis);

//***********************
    // Set the Outputs according to the loop state !
    digitalWrite(outA, AOutstate);
    digitalWrite(outB, BOutstate);

//***********************
    if (counter > 1)
    {
      //initialize for next cycle
      counter = 0;
      digitalWrite(outA, LOW);
      digitalWrite(outB, LOW);
      Serial.println("Pump OFF \n");
      AOutstate = true;
      BOutstate = false;

operateMillis = millis();

return;
    }

counter++;

//***********************
    //Change the Output state
    if (AOutstate == HIGH)
    {
      interval = offTime;
      Serial.println("Pump BACKWARD");
    }

else  if (BOutstate == HIGH)
    {
      interval = onTime;
      Serial.println("Pump FORWARD");
    }

// Toggle the Output pins state
    AOutstate = !AOutstate;
    BOutstate = !BOutstate;
  }
}