Blink with millis (no delay) at different speeds depending on button count

I am having trouble implementing a millis() into a state change code.(or even how to implement millis in general). I want to press my button 5 times and for each time its pressed it changes the rate of the blink or flash.

So far my code is the following -- I know it is rough I am trying to implement it into an old state change code since I am new to this.

int greenPin = 9;   // green color at pin 9
int buttonPin = 2;  //  button at pin 2
int counter = 0;    // counter starts at 0
int buttonc = 1;
int buttonState = 0;  
int lastbuttonState = 0;

void setup(){
  pinMode(buttonPin, INPUT); // Button Pin is an Input
  pinMode(greenPin, OUTPUT); // greenpin is an output
  Serial.begin(9600);
}

void loop(){

  buttonState = digitalRead(buttonPin);
 
  if (buttonState != lastbuttonState) {
    
    if (buttonState == HIGH) {
    counter++;
    buttonc++;
    Serial.print("count is");
    Serial.println(buttonc);

    }
  }
  lastbuttonState = buttonState;
  
    if(counter==0){
      
      digitalWrite(greenPin, LOW); // no color shown
      millis(0);
    }
    if(counter==1){
     
      digitalWrite(greenPin, HIGH); // green color shown
    }
    if(counter==2){

      digitalWrite(greenPin, HIGH); // no color shown
      millis(1000);
    }
    if(counter==3){
  
      digitalWrite(greenPin, HIGH); // no color shown
      millis(2000);
   }
  if(counter==4){
 
      digitalWrite(greenPin, HIGH); // no color shown
      millis(5000);
    
 }
     }
    millis(0);

millis() does not work like that. Rather it returns the number of milliseconds that have passed since the Arduino was powered up or reset so that you can determine how much time has passed since the last time that you looked at the value

Take a look at Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

So do you believe millis is the correct route to go for this type of problem?

wilsonc34:
So do you believe millis is the correct route to go for this type of problem?

Definitely

...R

I prefer this version to use a millis()-based timers for the following reasons:

  • you just define one variable that is used for the timing instead of two variables

  • the function itself delivers a boolean value

  • the functions name is selfexplaining

of course there are reasons why the "other" version is used. And there are cases where the "other" version has advantages
but in most cases it is easier to use.

recently I found this tutorial about how to use millis()
and it has a paragraph that nails it down to the point how millis() work in opposite to delay()

(The millis(): function is one of the most powerful functions of the Arduino library. This function returns the number of milliseconds the current sketch has been running since the last reset. At first, you might be thinking, well that’s not every useful! But consider how you tell time during the day. Effectively, you look at how many minutes have elapsed since midnight. That’s the idea behind millis()!)

baldengineers: millis() Tutorial: Arduino Multitasking

this tutorial shows the "other" version hwo to use millis()

here is mine

boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();  

  if ( currentMillis - expireTime >= TimePeriod )
  {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}

      unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long
const unsigned long MyIntervalInMilliSeconds = 1000;

loop() {
  if (TimePeriodIsOver (MyTestTimer, MyIntervalInMilliSeconds) ) {

    //doThings only after specified in TimePeriodIsOver   is over
}

best regards Stefan

  1. Load up sketch...
    File => Examples => 02. Digital => Blink Without Delay
    Study it, understand how it works.

  2. Load up sketch...
    File => Examples => 02. Digital => Debounce
    Study it, understand how it works.

  3. Combine both sketches...
    When the button is pressed (2nd sketch code) also update the value of variable "interval" (1st sketch code - you will need to remove the "const" qualifier)
    Cycle "interval" through a range of values to suit your flash schedule
    Edit:
    Probably easiest to store the values in an array, and then step through the array elements 0...n with an index variable on each button press.

you just define one variable that is used for the timing instead of two variables

Which one variable are you referring to ?

I see currentMillis, expireTime and TimePeriod to say nothing of MyTestTimer and MyIntervalInMilliSeconds

What I do like is the sensible function name that lets you write an almost English sentence

 if (TimePeriodIsOver (MyTestTimer, MyIntervalInMilliSeconds) )

This would be even better if global variables were used because it could become

  if (TimePeriodIsOver())

but that would enrage the purists who never use global variables

The function itself has mutliple variables. But the function ist that part that you just copy&paste into a new sketch without touching it.

What has to be added is the Timervariable ( variable MyTestTimer in the example)
for each Timing-"Thing" you want do do

In the "other" version you have to put

CurrenMillis = millis(); on top of loop()

go down to where inside loop you want to add the timing-thing
and add a previousMillis = currentMillis; at the end of the "timed" code

As soon as you want to have multiple timers in most cases you have to add

multiple previousMillis like this

previousMillisPurposeA
previousMillisPurposeB

previousMillisPurposeC etc.

best regards Stefan

I have some sympathy for what you are suggesting but you need two variables to pass to the function

As soon as you want to have multiple timers in most cases you have to add

multiple previousMillis like this

previousMillisPurposeA
previousMillisPurposeB

previousMillisPurposeC etc.

or you use an array or even a struct of variables