Controlling Millis()

I have been searching all day long for there seem a problem in my coding. The thing is, I wanted to control millis in a way that my arduino will only start counting when my pin 3 is HIGH. I've been experimenting different codes but to no avail. My latest code posted below is a code in which my system just never stops. I wanted to create a timer of 10 seconds but I can't seem to control millis for it starts when my arduino gets the power. Please Help me

unsigned long current = millis();
unsigned long timer;
const unsigned long interval = 10000;

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(3, INPUT);
  Serial.begin(9600);

  timer = current - interval;
}
void loop() {

  if(digitalRead(3)==HIGH and current - timer <= interval ){
    digitalWrite(12,HIGH);
    digitalWrite(8,HIGH);
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
    delay(100);
    digitalWrite(13,HIGH);
    
  }
  else{
    digitalWrite(7,HIGH);
    digitalWrite(13,LOW);
    digitalWrite(12,LOW);
    
  }    
}

millis() [..] it starts when my arduino gets the power

That's correct, and there's nothing you can do to change that behaviour. :wink:

So, if you want a 10 second interval, you have to "remember" the value of millis() (in an unsigned long!), and then check if millis() has become 10,000 larger; if it has, your 10 seconds are over.

There's no need to control millis(). The correct technique is to store a the value of millis() (a timestamp) at the time you want to mark and then compare the value of millis() to that timestamp to determine the elapsed time.

You can see a demonstration of that in this tutorial:

So the absolute value of millis() is not important. It's the relative value that matters. This is why there's no point in trying to control the absolute value of millis().

Initialization of “current” at the declaration by millis() does not magically follow it around.

Somewhere you need to make current again equal to millis(), then it will be, er, current.

current = millis();

You look close, keep thinking. I’m too lazy.

a7

I mean, I wanted to make millis() start counting at pin3==HIGH, theres a problem in my code because whenever I use this code, it never stops

In sort-of pseudo code:

void loop()
  bool running=false;

  if pin3 is high and running is false
    unsigned long startTime = millis()
    running=true

  if running
    if millis() - startTime => 10000
      running = false
      // here ends your 10 second period !

What is connected to pin 3?

@Erik_Baas

Based on your reply, This is my code: But it seems when input pin 3 is high the output is always high and it doesn't stop at 10 seconds. I tried testing it out thats why I put 3000 :frowning:

void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(3, INPUT);
  Serial.begin(9600);

}

void loop() {
  bool running = false;

  if (digitalRead(3) == HIGH and running == false) {
    unsigned long startTime = millis();
    running = true;
    if (running = true) {
      digitalWrite(12, HIGH);
      digitalWrite(8, HIGH);
      digitalWrite(13, HIGH);
      delay(100);
      digitalWrite(13, LOW);
      delay(100);
      digitalWrite(13, HIGH);
      if (millis() - startTime >= 3000) {
        running = false;
      }
    }
  }

  else if (digitalRead(3) == LOW); {
    digitalWrite(7, HIGH);
    digitalWrite(13, LOW);
    digitalWrite(12, LOW);
  }


}

karlcorporal7:
@Erik_Baas

Based on your reply, This is my code: But it seems when input pin 3 is high the output is always high and it doesn't stop at 10 seconds. I tried testing it out thats why I put 3000 :frowning:

if (running = true) {

...
}

??

There are some syntax errors in your code and I think logic errors as well. Does this suggestion work and/or help?

uint8_t
    currPin3,
    lastPin3;
    
void setup() 
{
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(3, INPUT);
    lastPin3 = digitalRead( 3 ) ^ HIGH;    //get opposite state of pin 13 now so check in loop works first pass
    
    Serial.begin(9600);

}//setup

void loop() 
{
    uint32_t
        timeNow;
    static uint32_t
        timePin13,
        timeStart;
    static uint8_t
        statePin13 = LOW,
        running = false;

    //read the state of pin 3
    currPin3 = digitalRead( 3 );
    if( currPin3 != lastPin3 )
    {
        //pin 3 has changed since last pass through loop...
        //save current state as last
        lastPin3 = currPin3;
        
        //...did it transition to high?
        if( currPin3 == HIGH )
        {
            //yes            
            //log time of transition
            timeNow = millis();

            //if we're not running now...
            if( running == false )
            {
                //...set the flag and pins
                running = true;
                digitalWrite(12, HIGH);
                digitalWrite(8, HIGH);
                digitalWrite(13, HIGH);

                //log the millis count of the start of the period
                timeStart = timeNow;
                //this is used to time the 100mS delays between toggles for pin 13
                timePin13 = timeNow;
                
            }//if
            
        }//if
        else
        {
            //pin went low; turn everything off
            digitalWrite(7, HIGH);
            digitalWrite(13, LOW);
            digitalWrite(12, LOW);
            statePin13 = LOW;
            
            running = false;
            
        }//if
        
    }//if

    //if we're timing the event now...
    if( running == true )
    {
        //check the millis count...
        timeNow = millis();

        //is it time for a pin toggle on 13?
        if( (timeNow - timePin13) >= 100u )
        {
            //yes; save the time for the next toggle
            timePin13 = timeNow;
            //if the pin is low now...
            if( statePin13 == LOW )
            {
                //...set it high and copy that to the pin state variable
                digitalWrite( 13, HIGH );
                statePin13 = HIGH;
                
            }//if
            else
            {
                //pin is high now, set it low
                digitalWrite( 13, LOW );
                statePin13 = LOW;
                
            }//else
        
        }//if

        //check to see if 10-sec activity time has expired
        if( (timeNow - timeStart) >= 10000u )
        {
            //if here, time expired so set everything off
            digitalWrite(7, HIGH);
            digitalWrite(13, LOW);
            digitalWrite(12, LOW);
            statePin13 = LOW;
            
            running = false;
            
        }//if
        
    }//if

}//loop

As a simple analogon:

Can you stop time? I mean the real time that runs forward in the unsiverse? Of course not.

So how would you cook spaghetti?
fill in water into a pot add some salt
put the pot on cooker and switch on
wait until water boils

That was the preparation no the interesting part starts:

You want to cook the spaghetti for 10 minutes

So how are you gonna do this? Calling god "can you reset time to zero"? Of course not !

It's the same thing with millis() millis() runs up after power-on and never can be stopped (exept power off)
You have a fundamental misunderstanding of how to work with millis().

1: MILLIS() CAN'T BE STOPPED
2: you programm it DIFFERENT!

I apalogise for shouting. here comes the solution:

You put the spaghetti into the pot and
You take a look onto a clock. Let's say it is 1:04 pm.

So you know at 1:14 pm the spaghetti are finsihed al dente
What you have done is calculating the endtime by adding 10 minutes to the actual time.
If you have nothing else than a simple clock you look on the clock until it is 1:14 pm.

What you are doing in principle is looking at the clock pretty often to recognize when is it 1:14 pm.

In programming you do a similar thing. I emphasize a similiar thing not exact the same.

In programming with millis() you calculate time right know - start-time of cooking

so it looks like this
**1:04 ** - 1:04 = 0 minutes
**1:05 ** - 1:04 = 1 minute
**1:06 ** - 1:04 = 2 minutes
**1:07 ** - 1:04 = 3 minutes
**1:08 ** - 1:04 = 4 minutes
**1:09 ** - 1:04 = 5 minutes
**1:10 ** - 1:04 = 6 minutes
**1:11 ** - 1:04 = 7 minutes
**1:12 ** - 1:04 = 8 minutes
**1:13 ** - 1:04 = 9 minutes
**1:14 ** - 1:04 = 10 minutes <== HA! 10 minutes over !! spaghetti ready to eat!

This difference time right know - start-time of cooking is compared to your 10 minutes.

in programming code it looks like this

if (time_right_know - startTime >= MyWaitingTime  ) {
  Do Timed action
}

time right know - start-time of cooking >= MyWaitingTime

usually the variables are named this way

currentTime = millis(); // store actual time for calculating the difference.

if ( currentTime - previousTime >= MyWaitingTime) {
do timed action
}

If the timed action should be repeated like switching an LED ON/OFF all the time

loop()
currentTime = millis(); // store actual time for calculating the difference.

if ( currentTime - previousTime >= MyWaitingTime) {
previousTime = **currentTime **// make actual time the previous time for next cycle actual time the
do timed action
}
} // end of loop

if you need more explanation I recommend watching the video in this tutorial and read this tutorial

arduino-sketch-with-millis-instead-of-delay

blink-without-delay-explained

hm somehow I got hungry - gonna cook some spaghetti right know :wink:
best regards Stefan

@Blackfin

Holy ***t mate, I think you've got it. Thank you very much. Why are there few people like you in this community. Straight to the point answer that will help newbies like me. This community is a lesser toxic with you. Thank you again, I know what to do now.

@Erik_Baas

what do you mean "??" ? You forgot that you posted a "pseudo code" here that I followed and tried and didn't worked?

@StefanL38

No offense dude, but do you think I don't know that? Isn't the rules here is read first before you post a forum? I have read that multiple times and should I be sorry if I still don't fully understand and needed the help of seniors in programming? Isn't this the programming section? Why are you lecturing me about the principles of millis??? Why can't you just look into my code and tell me what is wrong?? Will that stain your pride if you just answer straight to the point?

Anyways enjoy your spagetti.

@karlcorporal7

The "??" in question was a very vague way of pointing out that you used the assignment operator (=) rather than the comparison operator (==) in your conditional.

You can learn about the difference by reading these references:

karlcorporal7:
Why are there few people like you in this community.

Some here feel that if we write your code for you, it robs you of the chance to learn. For example, the process of working through your bug with the assignment operator (which I'm sure all of us have done at some time) would surely have been a learning experience. On the other hand, if I just provided you with fixed code to copy/paste, then you would likely make the same mistake the next time you wrote a sketch.

I don't want you to write the code for me, I just wanted you to tell what's wrong with my code, and what's lacking with my code. I understand that feeling but for me, as a student, with 0% background in arduino, Watched multiple videos for arduino, for just a single project, It is very hard for me and the least the seniors can do is to be engaging in some way here at the forum. Not answering "??" or lecturing about things that you already know. I just wanted the seniors to tell me whats wrong. They can just say, Hey you're lacking the uint or hey I think you have a wrong if statement loop, maybe add this, maybe don't do this. That is what I'm saying. Not the "I want copy/paste scenario.".

karlcorporal7:
what do you mean "??" ? You forgot that you posted a "pseudo code" here that I followed and tried and didn't worked?

That's not what you wrote on the forum in the first place. This is:

what do you mean "??" ? Are you on drugs mate? You forgot that you posted a "pseudo code" here that I followed and tried and didn't worked? Thank you for your toxicity. #stopusingdrugs

Copied from an email at 08:02. Not nice. To say the least.

I aplogise:

I have misunderstood your headline "controlling millis()" and your text

I wanted to create a timer of 10 seconds but I can't seem to control millis for it starts when my arduino gets the power. Please Help me

This really sounds like of you would like to reset millis() to zero.
some time ago there was a forum-posting trying exactly this (resetting millis().

So taking too less time on both sides.
Me: not reading your code.

you: lazy formulated headline and misunderstanables description.

I wanted to create a timer of 10 seconds but I can't seem to control millis for it starts when my arduino gets the power. Please Help me

best regards Stefan

Yeah, same here. The query about controlling the value of millis() or resetting it to 0 comes up here on the forum regularly.

@Erik_Baas

There is a reason why I removed that because @pert explained what you wrote and I understood that I've gone too far with my statement. But hey! You still pointed it out. This is my point here. This is why there is so much toxicity here because of @Erik_Baas. So much shame, knowledge < attitude.