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?
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
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