When I power on the arduino, the Millis will not let the code run for the first time until after my long interval, in this case it is 10000ms. I need the code to run first then deny it to run until after the long interval.
I was going to go with a simple delay() but Millis seems like it would be a better option.
Im stuck please help!
Here is my code:
#include <Servo.h>
const int button1 = 4; //button pin, connect to ground to move servo
const int switch1 = 10; //switch pin
int ledPin = 13; // the number of the LED pin
int press1 = 0;
int switchon = 0;
Servo servo1;
long previousMillis = 0; //store last time code was ran
long interval = 10000; //interval to run code
void setup()
{
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
pinMode(button1, INPUT);
pinMode(switch1, INPUT);
servo1.attach(7);
digitalWrite(4, HIGH); //enable pullups to make pin high
digitalWrite(10, HIGH); //enable pullups to make pin high
}
void loop()
{
press1 = digitalRead(button1);
switchon = digitalRead(switch1);
if ((switchon == LOW) && (press1 == LOW))
{
digitalWrite(ledPin, HIGH);
servo1.write(10);
delay(800);
servo1.write(170);
delay(3000);
digitalWrite(ledPin, LOW);
}
//3HOUR LIMIT ON BUTTON PRESS
unsigned long currentMillis = millis(); //check to see if it is time to run code
if ((switchon == HIGH) && (press1 == LOW) && (currentMillis - previousMillis > interval))
{
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
previousMillis = currentMillis; //save the last time the LED blinked
}
}
If you want to be able to execute "blink" code immediately, the trick is to set interval to 10000 in the "blink" code. In setup() you should set it to 0.
aarg:
You used quote tags, please use code tags instead. What's this talk of millis()? What I see are a lot of delay() calls. Get rid of them.
Sorry about the quote tags, fixed.
You see the delay(1000) to make the led blink. this led is temporary so i can easily verify
unsigned long currentMillis = millis(); //check to see if it is time to run code
if ((switchon == HIGH) && (press1 == LOW) && (currentMillis - previousMillis > interval))
works before i:
unsigned long currentMillis = millis(); //check to see if it is time to run code
if ((switchon == HIGH) && (press1 == LOW) && (currentMillis - previousMillis > interval))
{
digitalWrite(ledPin, HIGH);
servo1.write(10);
delay(800);
servo1.write(170);
delay(3000);
digitalWrite(ledPin, LOW);
}
THANK YOU so much for you input but no the problem was not solved. i will rephrase my question....
What i want is for the arduino board to power on and allow a button press and run code, THEN check to make sure "long interval = 10000" time has passed BEFORE allowing another button press.......
Currently the board powers on and FIRST checks to make sure "long interval" time has passed then it will allow a button press and code run and that is not the order i want it to go obviously.
once again thank you for you help and please excuse my poor explaining and even worse coding skills.
#include <Servo.h>
const int button1 = 4; //button pin, connect to ground to move servo
const int switch1 = 10; //switch pin
int ledPin = 13; // the number of the LED pin
int press1 = 0;
int switchon = 0;
Servo servo1;
long previousMillis = 0; //store last time code was ran
long interval = 10000; //interval to run code
void setup()
{
pinMode(ledPin, OUTPUT); //initialize the LED pin as an output
pinMode(button1, INPUT); //initialize the button as an input
pinMode(switch1, INPUT); //initialize the switch as an input
servo1.attach(7); //attach servo to pin 7
digitalWrite(4, HIGH); //enable pullups to make pin high
digitalWrite(10, HIGH); //enable pullups to make pin high
}
void loop()
{
press1 = digitalRead(button1); //read button press
switchon = digitalRead(switch1); //read switch
if ((switchon == LOW) && (press1 == LOW)) //if switch is off and button pressed, run code
{
digitalWrite(ledPin, HIGH); //turn on led
servo1.write(10); //move servo to 10 deg
delay(800); //wait for servo to reach angle
servo1.write(170); //move servo to 170 deg
delay(3000); //wait for servo to reach angle
digitalWrite(ledPin, LOW); //turn off led
}
//3HOUR LIMIT ON BUTTON PRESS
unsigned long currentMillis = millis(); //check to see if it is time to run code
if ((switchon == HIGH) && (press1 == LOW) && (currentMillis - previousMillis > interval))
{
digitalWrite(ledPin, HIGH); //turn on led
servo1.write(10); //move servo to 10 deg
delay(800); //wait for servo to reach angle
servo1.write(170); //move servo to 170 deg
delay(3000); //wait for servo to reach angle
digitalWrite(ledPin, LOW); //turn off led
}
previousMillis = currentMillis; //save the last time the code was ran
}
}
That is nonsense. Ignoring switch presses for some interval is NOT the same thing as not ALLOWING them. There is nothing you can do to PREVENT the user from pressing the switch. Whether you do anything about it, or not, is up to you.
Now, perhaps you can look at the blink without delay example, and see that you need to keep track of when the switch was last pressed, and see that you need to compare that time to now, to see if it is again time to care about whether or not the switch is pressed.
PaulS:
Now, perhaps you can look at the blink without delay example, and see that you need to keep track of when the switch was last pressed, and see that you need to compare that time to now, to see if it is again time to care about whether or not the switch is pressed.
+1
You should also see how using any delay()'s at all will completely wreck that method.
+1 constructive criticism, much welcomed and needed
PaulS:
Now, perhaps you can look at the blink without delay example, and see that you need to keep track of when the switch was last pressed, and see that you need to compare that time to now, to see if it is again time to care about whether or not the switch is pressed.
That is where I originally got the idea to do this.
aarg:
+1
You should also see how using any delay()'s at all will completely wreck that method.
I am thinking since i cannot grasp this i will only use delay. Hopefully (im pretty sure it is stored as an int) that it will not be too big of a number.
EXAMPLE:
//recognize button press and run code then delay for 3 hours
if ((switchon == HIGH) && (press1 == LOW))
{
digitalWrite(ledPin, HIGH);
servo1.write(10);
delay(800);
servo1.write(170);
delay(3000);
digitalWrite(ledPin, LOW);
delay(10800000)
}
}
//Blink without Delay skeleton
//4 examples demonstrated
//LarryD
//LED wiring options
//=============================================
//#define PlusEqualsON //uncomment to invert
#ifdef PlusEqualsON
//wired so +5V turns LED ON
#define ledON HIGH
#define ledOFF LOW
//=========================
#else
//wired so +5V turns LED OFF
#define ledON LOW
#define ledOFF HIGH
#endif
//=============================================
unsigned long currentMillis;
unsigned long pin13Millis;
unsigned long pin12Millis;
unsigned long pin11Millis;
unsigned long SwitchMillis;
//if these are not changed in the sketch, they can be const
unsigned long debounceMillis = 100UL; //100ms
unsigned long ledOnTime = 5*1000UL; //5 seconds
byte laststartSwitchState = HIGH;
byte buttonState = HIGH;
byte counter = 0;
//the following are enable/disable flags
//some of these might not be used in this sketch
boolean flag13 = true;
boolean flag12 = true;
boolean flag11 = true;
boolean flag10 = true;
const byte startSwitch = 2; //pushed = LOW
const byte testSwitch = 3; //pushed = LOW
//**********************************************************************
void setup()
{
Serial.begin(9600);
digitalWrite(13,ledOFF);
pinMode(13, OUTPUT);
digitalWrite(12,ledOFF);
pinMode(12, OUTPUT);
digitalWrite(11,ledOFF);
pinMode(11, OUTPUT);
digitalWrite(10,ledOFF);
pinMode(10, OUTPUT);
pinMode(startSwitch, INPUT_PULLUP); //pushed = LOW
pinMode(testSwitch, INPUT_PULLUP); //pushed = LOW
} // >>>>>>>>>>>>>> E N D O F s e t u p ( ) <<<<<<<<<<<<<<<<<
void loop()
{
//save the current time
currentMillis = millis();
//************************************* E x a m p l e 1
//toggle pin 13 every 200mS
//has 200ms or more gone by?
if (currentMillis - pin13Millis >= 200UL)
{
//code here runs every 200ms
//get ready for next iteration
pin13Millis = pin13Millis + 200UL;
//toggle pin 13
digitalWrite(13,!digitalRead(13));
}
//************************************* E x a m p l e 2
//at power up, pin 12 LED goes ON, after 3 seconds goes OFF and stays OFF
//could be used as a powerup reset signal
if (flag12 == true && currentMillis - pin12Millis <= 3000UL)
{
//code here runs for 3 seconds after power up, then stops
digitalWrite(12,ledON);
}
else
{
digitalWrite(12,ledOFF);
//disable further pin 12 control
flag12 = false;
}
//************************************* E x a m p l e 3
//if testSwitch is pushed and released
//pin 11 LED goes ON for 5 seconds, then goes OFF
buttonState = digitalRead(testSwitch);
//are we are allowed to check the switch and is it pressed?
if(flag11 == true && buttonState == LOW)
{
//enable timing of LED on pin 11
flag11 = false; //false --> timing is enabled
//turn LED ON
digitalWrite(11,ledON);
//record the time LED turned ON
pin11Millis = currentMillis;
}
//are we allowed and is it time to control pin 11
if (flag11 == false && currentMillis - pin11Millis >= ledOnTime)
{
//if enabled, code here runs after ledOnTime ms goes by
digitalWrite(11,ledOFF);
//allow switch press detection again
flag11 = true; //true --> switch monitoring is enabled
}
//************************************* E x a m p l e 4
//is it time to check the switches?
//in particular, pushing startSwitch will turn ON/OFF (toggle) an output pin 10
//is it time to check the switches
if (currentMillis - SwitchMillis >= debounceMillis)
{
//code here runs every debounceMillis ms
//get ready for the next iteration
SwitchMillis += debounceMillis;
//go and check the switches
checkSwitches();
}
//*********************************
//put other non-blocking stuff here
//*********************************
} // >>>>>>>>>>>>>> E N D O F l o o p ( ) <<<<<<<<<<<<<<<<<
//======================================================================
// F U N C T I O N S
//======================================================================
//****************** c h e c k S w i t c h e s ( ) *********************
//switches are checked every debounceValue milli seconds
//no minimum switch press time is validated with this code (i.e. No glitch filter)
void checkSwitches()
{
//re-usable for all the switches
boolean thisState;
//************************************* E x a m p l e Push ON push OFF (toggle)
//check if this switch has changed state
thisState = digitalRead(startSwitch);
if (thisState != laststartSwitchState)
{
//update the switch state
laststartSwitchState = thisState;
//this switch position has changed so do some stuff
//"HIGH condition code"
//switch went from LOW to HIGH
if(thisState == HIGH)
{
//Do some HIGH switch stuff here
}
//"LOW condition code"
//switch went from HIGH to LOW
else
{
//Do some LOW switch stuff here
digitalWrite(10, !digitalRead(10));
//print number of pushes
counter++;
Serial.println(counter);
}
} //END of startSwitch code
//*****************************************
//similar code for other switches goes here
//*****************************************
} //END of checkSwitches()
//**********************************************************************
//======================================================================
// E N D O F C O D E
//======================================================================
Well, we can assure you that millis() itself works fine.
You want, in pseudocode:
if button_pressed AND button_pressed_allowed
do something.
disallow_button_presses_for_some_time
else
// continue doing something else, perhaps.
So, you can actually write it that way. Note the code added to buttonAllowed so that it returns TRUE after startup, as well as after an elapsed interval. And the added debugging code. debugging code is very useful!
And code to use the Serial instead of actual buttons.
// Check if the correct buttons are pressed.
bool buttonPressed() {
#if 0
press1 = digitalRead(button1);
switchon = digitalRead(switch1);
if ((switchon == LOW) && (press1 == LOW)) { // not too sure about this. The original code had
// two different "tests"
Serial.println("Button Pressed");
return true;
}
#else
if (Serial.read() == 'p') {
Serial.println("Button Pressed");
return true;
}
#endif
return false;
}
bool pressAllowed() {
// A button press is allowed if it's been "interval" since the last button press action
unsigned long currentmillis = millis();
if (currentmillis - previousMillis > interval) {
previousMillis = currentmillis;
Serial.println("ButtonAllowed because time");
return true;
}
// or if the system has just started. This is actually slightly difficult, since a
// start both millis() and previousmillis will be 0, and it will be "interval" before the time
// based scheme actually allows a press. The easiest way to correct for this is just to
// create another variable to handle the startup condition.
static bool firsttime = true; // start at allowing a buttonpress
if (firsttime) {
previousMillis = currentmillis; // reset the timer.
firsttime = false; // no longer allow the startup excemption of timeout.
Serial.println("ButtonAllowed because startup");
return true;
}
Serial.print("Button disallowed: ");
Serial.print(interval - (currentmillis - previousMillis));
Serial.println("ms remaining");
return false; // otherwise don't allow the button to work yet.
}
void loop() {
if (buttonPressed()) {
if (pressAllowed()) {
// Do stuff. For now, blink the led
pinMode(ledPin, HIGH);
delay(500);
pinMode(ledPin, LOW);
}
}
// Do other stuff.
}
Warning: there's a bug in this code. Finding it is left as an exercise for the reader