Hey! I am trying to understand how to use millis through @UKHeliBob 's Using millis() for timing. A beginners guide - Introductory Tutorials - Arduino Forum
I am trying to implement the part 2 in part 4. So I am trying to get one led to blink and one to fade when a button is pressed and go off when pressed again. I have added a flashFlag, however the code is not working for me and I could really use some help!
unsigned long periodStartMillis;
unsigned long currentMillis;
unsigned long blinkStartMillis;
unsigned long fadeStartMillis;
const unsigned long period = 50; //checking button every 50ms
const byte buttonPin1 = 2; //button on pin 2
byte currentButtonState;
byte previousButtonState;
const unsigned long blinkPeriod = 1000; //blink period
const unsigned long fadePeriod = 10; //fade period
const byte blinkLedPin = 9; //this LED will blink
const byte fadeLedPin = 10; //this LED will fade
byte brightness = 0; //initial brightness of LED
byte increment = 1; //amount to change PWM value at each change
unsigned long debounceStartMillis;
unsigned long debouncePeriod = 20;
boolean debouncing = false;
bool flashFlag = false;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(blinkLedPin, OUTPUT);
pinMode(fadeLedPin, OUTPUT);
blinkStartMillis = millis(); //start time of blinking LED
fadeStartMillis = millis(); //start time of fading LED
periodStartMillis = millis();
}
void loop()
{
currentMillis = millis();
if (currentMillis - periodStartMillis <= period) //true until the period elapses
{
previousButtonState = currentButtonState; //save the previous button state
currentButtonState = digitalRead(buttonPin1); //read the current state of the input
if (currentButtonState != previousButtonState) //if the button state has changed
{
debounceStartMillis = currentMillis; //save the time that the state change occured
debouncing = true; //flag that debouncing in progress
} //end state change check
if (currentMillis - debounceStartMillis >= debouncePeriod) //if the debounce period has elapsed
{
if (debouncing == true) //debouncing taking place
{
if (currentButtonState == LOW && flashFlag == false) //if the button is currently pressed
{
debouncing = false; //debouncing is finished
blink();
fade();
Serial.println("Led on!");
flashFlag = true;
} //end count increment
} //end debouncing in progress check
} //end debounce time elapsed check
} //end timing period check
//*****************************************************************************************
currentMillis = millis();
if (currentMillis - periodStartMillis <= period) //true until the period elapses
{
previousButtonState = currentButtonState; //save the previous button state
currentButtonState = digitalRead(buttonPin1); //read the current state of the input
if (currentButtonState != previousButtonState) //if the button state has changed
{
debounceStartMillis = currentMillis; //save the time that the state change occured
debouncing = true; //flag that debouncing in progress
} //end state change check
if (currentMillis - debounceStartMillis >= debouncePeriod) //if the debounce period has elapsed
{
if (debouncing == true) //debouncing taking place
{
if (currentButtonState == LOW && flashFlag == true) //if the button is currently pressed
{
debouncing = false; //debouncing is finished
digitalWrite(blinkLedPin, LOW);
digitalWrite(fadeLedPin, LOW);
Serial.println("Led off!");
flashFlag = false;
} //end count increment
} //end debouncing in progress check
} //end debounce time elapsed check
} //end timing period check
}
//****************************************************************************************
void blink() //function to blink an LED if the blink period has ended
{
if (currentMillis - blinkStartMillis >= blinkPeriod) //test whether the period has elapsed
{
digitalWrite(blinkLedPin, !digitalRead(blinkLedPin)); //if so, change the state of the LED
blinkStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
void fade() //function to fade an LED
{
if (currentMillis - fadeStartMillis >= fadePeriod) //test whether the period has elapsed
{
analogWrite(fadeLedPin, brightness); //set the brightness of the LED
brightness += increment; //will wrap round because brightness is an unsigned data type
fadeStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
Thanks!
There seems to be a large section of code repeated in loop(). Did you do that deliberately ?
UKHeliBob:
There seems to be a large section of code repeated in loop(). Did you do that deliberately ?
Yes, I am just following the tutorial.
Hm, Is that a problem and can that cause the problem?
You only need to detect the change of button input state in one place in the code in order to turn the fading and blinking on and off. Each of the examples does the detection, but you seem to have copied the button press detection code from both examples into your code and used the same variable names in both code sections
UKHeliBob:
You only need to detect the change of button input state in one place in the code in order to turn the fading and blinking on and off. Each of the examples does the detection, but you seem to have copied the button press detection code from both examples into your code and used the same variable names in both code sections
Okey, so I have shorted it down now, still does not work but it is less code!
unsigned long startMillis;
unsigned long periodStartMillis;
unsigned long currentMillis;
unsigned long blinkStartMillis;
unsigned long fadeStartMillis;
const unsigned long period = 50; //checking button every 50ms
const byte buttonPin1 = 2; //button on pin 2
byte currentButtonState;
byte previousButtonState;
const unsigned long blinkPeriod = 1000; //blink period
const unsigned long fadePeriod = 10; //fade period
const byte blinkLedPin = 9; //this LED will blink
const byte fadeLedPin = 10; //this LED will fade
byte brightness = 0; //initial brightness of LED
byte increment = 1; //amount to change PWM value at each change
unsigned long debounceStartMillis;
unsigned long debouncePeriod = 20;
boolean debouncing = false;
bool flashFlag = false;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(blinkLedPin, OUTPUT);
pinMode(fadeLedPin, OUTPUT);
blinkStartMillis = millis(); //start time of blinking LED
fadeStartMillis = millis(); //start time of fading LED
periodStartMillis = millis();
startMillis = millis();
}
void loop()
{
currentMillis = millis();
previousButtonState = currentButtonState;
if (currentMillis - startMillis <= period) //true until the period elapses. Note that this is the reverse of BWOD
{
currentButtonState = digitalRead(buttonPin1);
if (currentButtonState == LOW and previousButtonState == HIGH) //the button has become pressed
{
if (flashFlag == false) {
blink();
fade();
Serial.println("Led on");
flashFlag = true;
}
}
}
else {
if (currentButtonState == LOW and previousButtonState == HIGH)
{
if (flashFlag == true){
digitalWrite(blinkLedPin, LOW);
digitalWrite(fadeLedPin, LOW);
Serial.print("Led off");
flashFlag = false;
}
}
}
//*****************************************************************************************
}
//****************************************************************************************
void blink() //function to blink an LED if the blink period has ended
{
if (currentMillis - blinkStartMillis >= blinkPeriod) //test whether the period has elapsed
{
digitalWrite(blinkLedPin, !digitalRead(blinkLedPin)); //if so, change the state of the LED
blinkStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
void fade() //function to fade an LED
{
if (currentMillis - fadeStartMillis >= fadePeriod) //test whether the period has elapsed
{
analogWrite(fadeLedPin, brightness); //set the brightness of the LED
brightness += increment; //will wrap round because brightness is an unsigned data type
fadeStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
UKHeliBob:
What does it do ?
Nothing! Does not even print to serial monitor
Here is an even simpler version of what you are trying to do
unsigned long startMillis;
unsigned long periodStartMillis;
unsigned long currentMillis;
unsigned long blinkStartMillis;
unsigned long fadeStartMillis;
const unsigned long period = 50; //checking button every 50ms
const byte buttonPin1 = A3; //button on pin 2
byte currentButtonState;
byte previousButtonState;
const unsigned long blinkPeriod = 1000; //blink period
const unsigned long fadePeriod = 10; //fade period
const byte blinkLedPin = 3; //this LED will blink
const byte fadeLedPin = 5; //this LED will fade
byte brightness = 0; //initial brightness of LED
byte increment = 1; //amount to change PWM value at each change
bool actionFlag = false;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(blinkLedPin, OUTPUT);
pinMode(fadeLedPin, OUTPUT);
blinkStartMillis = millis(); //start time of blinking LED
fadeStartMillis = millis(); //start time of fading LED
periodStartMillis = millis();
startMillis = millis();
}
void loop()
{
currentMillis = millis();
previousButtonState = currentButtonState;
currentButtonState = digitalRead(buttonPin1);
if (currentButtonState == LOW and previousButtonState == HIGH) //the button has become pressed
{
actionFlag = !actionFlag; //change state of flashing flag
}
if (actionFlag == true) //take actions based on the state of the action flag
{
blink();
fade();
}
else
{
digitalWrite(blinkLedPin, LOW);
digitalWrite(fadeLedPin, LOW);
}
}
void blink() //function to blink an LED if the blink period has ended
{
if (currentMillis - blinkStartMillis >= blinkPeriod) //test whether the period has elapsed
{
digitalWrite(blinkLedPin, !digitalRead(blinkLedPin)); //if so, change the state of the LED
blinkStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
void fade() //function to fade an LED
{
if (currentMillis - fadeStartMillis >= fadePeriod) //test whether the period has elapsed
{
analogWrite(fadeLedPin, brightness); //set the brightness of the LED
brightness += increment; //will wrap round because brightness is an unsigned data type
fadeStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
Pressing the button changes the state of a boolean variable then later in loop() the required functions are called to perform the actions based on its state
Note that as written the button presses are not debounced as I felt that was confusing, but it could be added
Thanks for the help and time! I hope I am alittle more close to fully understand the millis.
Added debouncing
unsigned long startMillis;
unsigned long periodStartMillis;
unsigned long currentMillis;
unsigned long blinkStartMillis;
unsigned long fadeStartMillis;
unsigned long debounceStartMillis;
unsigned long debouncePeriod = 20;
const unsigned long period = 50; //checking button every 50ms
const byte buttonPin1 = 2; //button on pin 2
byte currentButtonState;
byte previousButtonState;
const unsigned long blinkPeriod = 1000; //blink period
const unsigned long fadePeriod = 10; //fade period
const byte blinkLedPin = 9; //this LED will blink
const byte fadeLedPin = 10; //this LED will fade
byte brightness = 0; //initial brightness of LED
byte increment = 1; //amount to change PWM value at each change
bool actionFlag = false;
boolean debouncing = false;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(blinkLedPin, OUTPUT);
pinMode(fadeLedPin, OUTPUT);
blinkStartMillis = millis(); //start time of blinking LED
fadeStartMillis = millis(); //start time of fading LED
periodStartMillis = millis();
startMillis = millis();
}
void loop()
{
currentMillis = millis();
int reading = digitalRead(buttonPin1);
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != currentButtonState) {
currentButtonState = reading;
// only toggle the LED if the new button state is HIGH
if (currentButtonState == LOW) {
actionFlag = !actionFlag;
}
}
}
if (actionFlag == true) //take actions based on the state of the action flag
{
blink();
fade();
}
else
{
digitalWrite(blinkLedPin, LOW);
digitalWrite(fadeLedPin, LOW);
}
// set the LED:
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastButtonState = reading;
}
//**************************************
void blink() //function to blink an LED if the blink period has ended
{
if (currentMillis - blinkStartMillis >= blinkPeriod) //test whether the period has elapsed
{
digitalWrite(blinkLedPin, !digitalRead(blinkLedPin)); //if so, change the state of the LED
blinkStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
void fade() //function to fade an LED
{
if (currentMillis - fadeStartMillis >= fadePeriod) //test whether the period has elapsed
{
analogWrite(fadeLedPin, brightness); //set the brightness of the LED
brightness += increment; //will wrap round because brightness is an unsigned data type
fadeStartMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}