The objective is for the user to push a button and have an LED come on and blink for 30 seconds. After the 30 seconds are up, no more blinking until the button is pushed again. When I upload the code and push the button the LED starts blinking but it will not stop. I'm still quite new at coding.
const int alarmOnButton = 2;
const int buzzPin = 5;
const int buzzInterval = 500;
unsigned long previousBuzzMillis = 0;
unsigned long currentBuzzMillis;
unsigned long alarmDuration = 30000;
unsigned long previousDurationMillis;
unsigned long currentDurationMillis;
int buzzState = HIGH;
int buttonState;
void setup()
{
pinMode(alarmOnButton, INPUT_PULLUP);
pinMode(buzzPin, OUTPUT);
}
void loop()
{
currentDurationMillis = millis;
buttonState = digitalRead(alarmOnButton);
if (buttonState == LOW)
{
previousDurationMillis = currentDurationMillis;
while (currentDurationMillis - previousDurationMillis <= alarmDuration)
{
currentBuzzMillis = millis();
if (currentBuzzMillis - previousBuzzMillis >= buzzInterval)
{
previousBuzzMillis = currentBuzzMillis;
if (buzzState == LOW)
{
buzzState = HIGH;
}
else
{
buzzState = LOW;
}
digitalWrite(buzzPin, buzzState);
}
}
}
}
/Users/john/Documents/Arduino/sketch_dec26a/sketch_dec26a.ino: In function 'void loop()':
/Users/john/Documents/Arduino/sketch_dec26a/sketch_dec26a.ino:28:27: warning: invalid conversion from 'long unsigned int (*)()' to 'long unsigned int' [-fpermissive]
currentDurationMillis = millis;
^~~~~~
You meant to write: currentDurationMillis = millis();
If you are ok with using libraries.. (Some people seem to feel like they are cheating when using libraries.. )
A different approach.
#include <mechButton.h>
#include <blinker.h>
#define BUTTON_PIN 2 // Pin we'll hook the button to. The other side hooks to ground.
#define LED_PIN 13 // Usual pin number for built in LED.
#define BLINK_MS 30000 // 30 second blink time.
mechButton button(BUTTON_PIN); // Create a debouncing button.
blinker aBlinker; // Default is for pin 13. Go with that.
timeObj blinkTimer(BLINK_MS); // Setup a timer for 30 seconds.
bool blinking; // A bool to save our blinking state.
// Your standard sketch setup()
void setup() {
button.setCallback(myCallback); // Set up our callback. (Also calls hookup() for idling.)
aBlinker.setOnOff(false); // Make sure we're not already doing the blink thing.
blinking = false; // Note that we're not blinking.
}
// This is the guy that's called when the button changes state.
void myCallback(void) {
if (!button.trueFalse()) { // If the button was mashed to ground.. (Pressed)
if (blinking) { // If we ARE already blinking..
aBlinker.setOnOff(false); // Stop this silly blinking.
blinking = false; // Save our state.
} else { // Else, we are NOT blinking..
blinkTimer.start(); // Fire up the timer.
aBlinker.setOnOff(true); // Start blinking.
blinking = true; // Save our state.
}
}
}
// Your standard sketch loop()
void loop() {
idle(); // Let all the idlers have time to do their thing.
if (blinking && blinkTimer.ding()) { // If we are blinking and our time has expired..
aBlinker.setOnOff(false); // Stop blinking.
blinking = false; // Save our state.
}
}
If you'd like to try this, install LC_baseTools from the IDE's library manager.
Again another library approach, my millisDelay class available in the SafeString library (available from the library manager)
see the tutorial How to write Timers and Delays in Arduino for the details
One of the advantages of the millisDelay class is that you can test if your delay timer is running and stop it early if you need to.
it is good to do both:
using libraries and doing things "by hand". libraries are good for things with a lot of details like the bitbanging
to send data to a display ore onewrire-bus etc.
Though a library can not offer all logic variations all the different applications of users need.
That's where "knowing how to code" comes into play.
the functionality you describe can be called a "oneshot-timer"
This goes beyond standard blinking.
more functionality means needing more code
blink only after button-press and stop after 30 seconds can be done with a boolean flag-variable
you can imagine boolean variables as internal switches ON/OFF but the states where true / false
press a button enables that something starts to happend for a period of time. When period has elapsed then stop.
you could define a function "blink_LED" which does the blinking
here is a "sketchy" sketch that shows the principle.
This code needs additional the function "blink_LED()" and closing curly brackets etc. to compile
unsigned long currentTime;
unsigned long previousTime;
unsigned long Blinking_Time = 30000;
boolean runBlinking;
void setup() {
runBlinking = false;
....
}
void loop() {
currentTime = millis();
if digitalRead(myButton == HIGH) { // if button is pressed
runBlinking = true; // set flag to true
previousTime = currentTime; // make snapshot of time when button is pressed
}
if (runBlinking) { // only if flag is true
blink_LED();
if (currentTime - previousTime >= Blinking_Time) {
runBlinking = false;
}
}
....
I took a look inside the milliDelay-tutorial of user drmpf
this is a very practical approach. Supported by a library with short demo-codes that are quite easy to understand.
This tutorial will reach all people that don't want to read pages long explanations that go deepest into programming-techniques. So IMHO just a different approach from the "standard" millis()-tutorial.
It is very clear: the short explanantions in this tutorial means a smaller understanding that the reader develops.
Anyway as all this is for free and done in free-time everybody is free to choose.
@larryd Thanks Larryd. Everything is running perfectly. One day I will see the solutions easier. And I promise to avoid the temptation to use while() for a while - post 300!
@jimlee Jim, thanks again. You've helped me out in the past. In the near future, I'm going to try your approach too.