I'm currently working on a school project. I have a servo motor which start every time I press a button. That part works but I need a delay so when I press the button once I can't press the button the next 2 minutes.
I hope you guys understand my question otherwise I will be more than happy to explain it again.
Here's my code:
#include <Servo.h>
const int buttonPin = 2; //The number for the pushbutton in
Servo myservo;
int pos = 0; //variable to store the servo position
int buttonState = 0;
int lastButtonState = 0;
void setup(){
pinMode(buttonPin, INPUT);
myservo.attach(9); //attaches the servoon pin 9 to the servo object
}
void loop(){
//Read the state of the pushbutton value:
buttonState= digitalRead(buttonPin);
if (buttonState != lastButtonState) {
if (buttonState == HIGH){
for (pos = 0; pos < 180; pos += 1){
myservo.write(pos);
delay(15);
}
for (pos = 180; pos >=1; pos -=1){
myservo.write(pos);
delay(15);
}
}
}
lastButtonState = buttonState;
}
You don't need a delay. You need to make note of the time when the button is pressed by saving millis() in an unsigned long variable. Then when the button is pushed again, you need to check the difference between the current time and the saved time and see if enough time has passed to allow the button push to proceed.
Delay sounds perfect for your stated requirements, although I suspect you'll quickly want to change to billroy's method as your sketch evolves. In what way did it not work?
Well I just need this "delay" to work and I'm done with my project. I tried to implement the milli() but now the servo motor runs the half way and stops waits the seconds I have defined and then run the whole way.
My problem was before that I couldn't get the delay I wanted even though I tried the delay()
Here's what it should do:
I press the button
The servo motor runs 180 degrees and back again.
The delay should prevent me to press the button for the next ten seconds
After the ten seconds I should be able to press the button again.
I hope you understand. If I can do this with a single delay please tell me where to implement it since the things I have tried didn't work.
I am sorry to inform you that you are a little further from your objective than you may have thought. This happens often in this game. You'll be finished faster if you lose the denial and get on with the work.
It is not possible to run the servo while inside your new hypothetical button lockout if the lockout is implemented as a delay. Delay blocks everything else. This is why it is necessary to use a method that keeps track of time.
You don't want a delay. You want a lockout. Think of it in those terms and you might get somewhere.
Well I tried with the milli() and it does almost... work. The servo motor runs 180 degrees and then return. Now, when I press the button it runs 90 degrees and waits the ten seconds I have told it to and then runs as it should. And that's not what I want it to. I want it to follow the steps I wrote in my previous post.
#include <Servo.h>
const int buttonPin = 2; //The number for the pushbutton in
Servo myservo;
int pos = 0; //variable to store the servo position
int buttonState = 0;
int lastButtonState = 0;
long previousMillis = 0;
long interval = 10000; // interval at which to blink (milliseconds)
void setup(){
pinMode(buttonPin, INPUT);
myservo.attach(9); //attaches the servoon pin 9 to the servo object
}
void loop(){
//Read the state of the pushbutton value:
unsigned long currentMillis = millis();
buttonState= digitalRead(buttonPin);
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
if (buttonState != lastButtonState) {
if (buttonState == HIGH){
for (pos = 0; pos < 180; pos += 1){
myservo.write(pos);
delay(15);
}
for (pos = 180; pos >=1; pos -=1){
myservo.write(pos);
delay(15);
}
}
}
lastButtonState = buttonState;
}
}
long interval = 10000; // interval at which to blink (milliseconds)
At which to blink what? 10 seconds is not two minutes.
//Read the state of the pushbutton value:
unsigned long currentMillis = millis();
buttonState= digitalRead(buttonPin);
if(currentMillis - previousMillis > interval) {
If it isn't time, why bother to read the switch state?
Putting each { on a new line, and using Tools + Auto Format will greatly improve your ability to see the structure of the code.
Whilst using millis() may be the preferred way to do this as the technique will be needed eventually in a program, the objective of locking out use of the button is easily achieved by using delay()
start of loop
if button press detected
sweep the servo once each way
delay for 2 minutes (minus the time taken for the servo sweep if you want to be precise)
end of if
end of loop
Yes, I know that the delay will block the code for 2 minutes, but if it meets the stated requirement, so what ?
I have no idea how to solve this problem at the moment. I have tried "fizzling" around with the milli() and the delay() but none of the things I tried worked out.
As to the layout of my code. I originally learned to program with K&R style and I have sticked to that since. I have never programming in this before only web dev and Python.
UKHeliBob:
Whilst using millis() may be the preferred way to do this as the technique will be needed eventually in a program, the objective of locking out use of the button is easily achieved by using delay()
start of loop
if button press detected
sweep the servo once each way
delay for 2 minutes (minus the time taken for the servo sweep if you want to be precise)
end of if
end of loop
Yes, I know that the delay will block the code for 2 minutes, but if it meets the stated requirement, so what ?
I could get that to work, here's my code as it as atm.
#include <Servo.h>
const int buttonPin = 2; //The number for the pushbutton in
Servo myservo;
int pos = 0; //variable to store the servo position
int buttonState = 0;
int lastButtonState = 0;
long previousMillis = 0;
long interval = 10000; // interval at which to blink (milliseconds)
void setup()
{
pinMode(buttonPin, INPUT);
myservo.attach(9); //attaches the servoon pin 9 to the servo object
}
void loop()
{
//Read the state of the pushbutton value:
buttonState= digitalRead(buttonPin);
if (buttonState != lastButtonState)
{
if (buttonState == HIGH){
for (pos = 0; pos < 180; pos += 1)
{
myservo.write(pos);
delay(15);
}
for (pos = 180; pos >=1; pos -=1)
{
myservo.write(pos);
delay(15);
}
}
delay(120000);
}
lastButtonState = buttonState;
}
set unsigned long variable interval to milliseconds delay required
set boolean variable timing to false
start of loop
if timing is false
if button press detected
set start time to millis()
sweep the servo once each way
set timing to true
end of if
end of if
if millis() minus start time greater than interval
set timing to false
end of if
//because the code is non blocking you could do other stuff here whilst waiting
//as long as it is non blocking
end of loop