0

My intent with this sketch is to have motors run for one minute, then stand by for 18 minutes. In practice, the sketch starts the motor state at "low" for the OffTime interval, then goes to the OnTime interval and loops. The desired result is exactly the opposite: the "high" interval first, followed by the "low". I have tried setting the motorState to "HIGH" in the constructor and played with the order of the IF statements to no avail.

I would appreciate any insight into this problem, as well as an intuition for the practical use of millis(). I need a solution which doesn't use delay but am having trouble wrapping my head around the logic of millis() as used. (I adapted this code from a tutorial.)

class LifeTest
{
  // Class member variables initialized at startup
  int motorPin;                                 
  long OnTime;                                  
  long OffTime;                                 
  // These maintain the current state
  int motorState;                               // Used to set the motor.
  unsigned long previousMillis;                 // Stores last time motor was updated. 


  public:
  LifeTest(int pin, long on, long off)
  {
    motorPin = pin;
    pinMode(motorPin, OUTPUT);

    OnTime = on;
    OffTime = off;

    motorState = LOW;
    previousMillis = 0;
  }

  void Update()
  {
    unsigned long currentMillis = millis();     // Check to see if it's time to change the motor state.
    if((motorState == HIGH) && (currentMillis - previousMillis >= OnTime))
    { 
    motorState = LOW;                         // Turn off motor.
    previousMillis = currentMillis;           // Remember the time.
    digitalWrite(motorPin, motorState);       // Update the motors.
    }
    else if((motorState == LOW) && (currentMillis - previousMillis >= OffTime))
    { 
    motorState = HIGH;                        // Turn on motor.
    previousMillis = currentMillis;           // Remember the time.
    digitalWrite(motorPin, motorState);       // Update the motors.
    }
  }
};

LifeTest motor1(50, 60000, 1080000);
LifeTest motor2(51, 60000, 1080000);
LifeTest motor3(52, 60000, 1080000);
LifeTest motor4(53, 60000, 1080000);

void setup()
{
}

void loop()
{
  motor1.Update();
  motor2.Update();
  motor3.Update();
  motor4.Update();
}
1

I would appreciate any insight into this problem, as well as an intuition for the practical use of millis().

I have a lengthy tutorial about this at How to do multiple things at once ... like cook bacon and eggs.

However as this site frowns upon link-only answers (the link might go down) I'll try to explain as well, here.

millis() is like having a wristwatch. You glance at it from time to time to see if it is time to do something, like catch a bus to work, put the dinner on, take the cake out of the oven, that sort of thing.

If you delay() all the time, you can only do one thing at a time. For example, if your cake takes 30 minutes to cook, and you do this:

PutCakeInOven ();
delay (30UL * 60 * 1000);  // delay 30 minutes
TakeCakeOutOfOven ();

This is fine, but you aren't also cooking some eggs at the same time, or doing the dishes, right?

With millis() you can do lots of things! Win-win! The basic technique is to note the time when you started, and then when time is up, you do whatever-it-is you need to do. Like this:

unsigned long BakeStartTime;
const unsigned long CookingTime = 30UL * 60 * 1000;  // 30 minutes
bool CakeInOven = false;

void setup ()
  {
  PutCakeInOven ();
  BakeStartTime = millis ();  // when the cake went into the oven
  CakeInOven = true;
  }

void loop ()
  {
  if (CakeInOven && (millis () - BakeStartTime >= CookingTime))
    {
    TakeCakeOutOfOven ();
    CakeInOven = false;
    }

  // do a whole lot of other stuff, like cooking some eggs

  }

You can expand this technique to do dozens of things "at once".

0

just change the constructor to

  LifeTest(int pin, long on, long off)
  {
    motorPin = pin;
    OnTime = on;
    OffTime = off;

    previousMillis = 0;

    motorState = HIGH;
    pinMode(motorPin, OUTPUT);
    digitalWrite(motorPin, motorState);
  }

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.