Project 1.06 Blink a Little Faster Now
It’s simple to stop the sketch and wait for user input, but what if we want to check for it while the sketch is doing other things? In this project, we change the rate that LED1 blinks each time SW1 is pressed. We can’t use delay to set the blink rate since we need to keep checking to see if SW1 is pressed. We’ll look at the code first and then see how it works.
Concepts: sketch control, millis(), debounce
Circuits:
Concepts: sketch control, millis(), debounce
Circuits:
We use several variables to keep track of what’s happening in this sketch. The variable isPress holds the value returned by digitalRead of SW1 and lastPressed holds the time that SW1 was last pressed:
int isPress = HIGH;
long lastPressed = 0;
The variable lastBlink holds the time that LED1 was last switched on or off, blinkSpeed holds the elapse time between blinks, and isOn holds whether LED1 is set to HIGH or LOW:
long lastBlink = 0;
int blinkSpeed = 1000;
int isOn = HIGH;
Our first challenge is setting the blink rate without using delay. We do this by measuring how much time has passed since we last switched LED1 on or off. At the top of the loop() block wee use the conditional statement:
if(millis() > (lastBlink + blinkSpeed)){
Where lastBlink is the value of millis() when we last switched LED1 on or off and blinkSpeed is the number of milliseconds that we want to elapse between blinks. It’s time to switch LED1 on or off when the sum of lastBlink + blinkSpeed is greater than the current time, millis().
If the conditional statement is true, it’s time to switch LED1 on or off:
isOn = 1 - isOn;
This switches the variable isOn from 1 to 0 or vice-versa. We then take advantage of the fact that we can replace HIGH or LOW in the digitalWrite statement with 1 (equivelant to HIGH) or 0 (equivelant to LOW):
digitalWrite(LED1,isOn);
Finally, we record the time with lastBlink so we know when to switch LED1 next:
lastBlink = millis();
}
This finishes up the block for the if statement. If the conditional statement in the if statement is false, the entire block is skipped and the Arno goes on to the next part of the code.
Our next challenge is checking to see if SW1 is pressed:
isPress = digitalRead(SW1);
We now use the conditional statement:
if(isPress == LOW && millis() > (lastPressed + 1000)){
The first part of the conditional statement tests to see if SW1 was pressed. The second part debounces SW1. Remember that the sketch runs very fast; it might process this statement almost 1 million times per second! So even if you press SW1 as fast as you can, the sketch could read SW1 in a LOW state thousands of times. We use lastPressed to record the value of millis() the last time SW1 was pressed and we don’t read SW1 again until at least 1 second has passed. You can even hold SW1 down and the sketch will not change the blink rate any more than once per second.
If the conditional statement is true, we change the value of blinkSpeed which decreases the delay between state changes:
blinkSpeed = blinkSpeed - 200;
We make sure it doesn’t go too low:
if(blinkSpeed < 10) blinkSpeed = 1000;
And we record the time to avoid changing the blink rate too often:
lastPressed = millis();
Finally, we close the if block with a bracket and the loop() block with a second bracket:
}
}
int isPress = HIGH;
long lastPressed = 0;
The variable lastBlink holds the time that LED1 was last switched on or off, blinkSpeed holds the elapse time between blinks, and isOn holds whether LED1 is set to HIGH or LOW:
long lastBlink = 0;
int blinkSpeed = 1000;
int isOn = HIGH;
Our first challenge is setting the blink rate without using delay. We do this by measuring how much time has passed since we last switched LED1 on or off. At the top of the loop() block wee use the conditional statement:
if(millis() > (lastBlink + blinkSpeed)){
Where lastBlink is the value of millis() when we last switched LED1 on or off and blinkSpeed is the number of milliseconds that we want to elapse between blinks. It’s time to switch LED1 on or off when the sum of lastBlink + blinkSpeed is greater than the current time, millis().
If the conditional statement is true, it’s time to switch LED1 on or off:
isOn = 1 - isOn;
This switches the variable isOn from 1 to 0 or vice-versa. We then take advantage of the fact that we can replace HIGH or LOW in the digitalWrite statement with 1 (equivelant to HIGH) or 0 (equivelant to LOW):
digitalWrite(LED1,isOn);
Finally, we record the time with lastBlink so we know when to switch LED1 next:
lastBlink = millis();
}
This finishes up the block for the if statement. If the conditional statement in the if statement is false, the entire block is skipped and the Arno goes on to the next part of the code.
Our next challenge is checking to see if SW1 is pressed:
isPress = digitalRead(SW1);
We now use the conditional statement:
if(isPress == LOW && millis() > (lastPressed + 1000)){
The first part of the conditional statement tests to see if SW1 was pressed. The second part debounces SW1. Remember that the sketch runs very fast; it might process this statement almost 1 million times per second! So even if you press SW1 as fast as you can, the sketch could read SW1 in a LOW state thousands of times. We use lastPressed to record the value of millis() the last time SW1 was pressed and we don’t read SW1 again until at least 1 second has passed. You can even hold SW1 down and the sketch will not change the blink rate any more than once per second.
If the conditional statement is true, we change the value of blinkSpeed which decreases the delay between state changes:
blinkSpeed = blinkSpeed - 200;
We make sure it doesn’t go too low:
if(blinkSpeed < 10) blinkSpeed = 1000;
And we record the time to avoid changing the blink rate too often:
lastPressed = millis();
Finally, we close the if block with a bracket and the loop() block with a second bracket:
}
}