Hello everyone,
in my code below I have a button that initiates several actions. Initially it is set to LOW and when the button is HIGH several actions occur. I would like to add a time limit of 3 seconds so if the button stays LOW after that a different set of actions will occur. I tried using the if/else functions. Any suggestions will be appreciated!
Thanks!
Thomas.
#include <Servo.h>
Servo s2;
int BUTTON = 2;
int COUNT = 1;
int buzzerPin = 8;
int counter;
void setup() {
Serial.begin(9600);
pinMode(10, INPUT);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
s2.attach(5);
}
void loop() {
unsigned long start_time;
unsigned long stop_time;
s2.write(6);
if (Serial.available() > 0) {
char data = Serial.read(); // reading the data received from the bluetooth module
switch (data)
{
{
case '1':
start_time = millis();
Serial.println(" ");
Serial.println(" Go...Go.. ");
for (counter = 0; counter < 3; ++counter) {
switch (COUNT);
int servo = random(5);
while (digitalRead(BUTTON) == LOW) {
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
s2.write(90);
delay(10);
}
if (digitalRead(BUTTON) == HIGH) {
Serial.write ("*S");
tone(buzzerPin, 600);
delay(50);
noTone(buzzerPin);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
s2.write(6);
delay(600);
COUNT ++;
Serial.print("You hit ");
Serial.println(COUNT);
}
}
}
Serial.println(" ");
Serial.println(" Finished: ");
Serial.println("Your result is: ");
Serial.print(COUNT);
Serial.print(" Target in ");
stop_time = millis();
Serial.print(stop_time - start_time);
Serial.println(" Time");
Serial.println(" ");
if (COUNT > 0) {
COUNT = 0;
}
}
}
}
Pin 2 is the output for the button and it's connected to 10K resistance.
You should probably call pinMode(BUTTON, INPUT); in setup().
Why are you setting Pin 10 to INPUT and not reading it? Was that 10 supposed to be BUTTON?
So you want to do something if the button has not been pushed (gone HIGH) within three seconds?
void setup()
{
pinMode(BUTTON, INPUT);
LastTimeButtonHigh = 0;
}
void loop()
{
if (digitalRead(BUTTON))
LastTimeButtonHigh = millis();
if (millis() - LastTimeButtonHigh >= 3000)
{
// Button has been LOW for three seconds. Do the thing here
LastTimeButtonHigh = millis(); // Reset the timer so it will go off in another three seconds if the button still isn't pressed
}
}
Thanks for the advice!
You are right about pin 10 initially the button was there and I changed its position later on. I tried LastTimeButtonHigh = 0; in setup but it brings up an error that it was not declared in this scope.
What I want is the following:
- If the button is pressed within 3 sec perform action 1
- If the button is NOT pressed after 3 sec perform action 2
Thanks again,
Thomas
tomstell:
I tried LastTimeButtonHigh = 0; in setup but it brings up an error that it was not declared in this scope.
Declare it as a global unsigned long variable.
I tried this but it did not work. If you have the time please let me know exactly how to do it as I have been working on this project for a few months now.
What I want to do exactly is this:
When Case 1 starts:
- If the button is Low then it will perform a specific set of actions.
- If the button in High within 3 seconds then it will perform a different set of actions.
- If the button is still Low after 3 secs then it will perform yet another set of actions.
Many thanks for all your help. I would appreciate it if you could help me solve this problem.
Thomas.
- If the button is Low then it will perform a specific set of actions.
- If the button in High within 3 seconds then it will perform a different set of actions.
- If the button is still Low after 3 secs then it will perform yet another set of actions.
Is that 2 sets of actions if the button is LOW and remains LOW ?
One immediately and a second after 3 seconds if it is still LOW ?
Some code for you to play with
const byte buttonPin = A1;
byte currentButtonState;
byte previousButtonState = HIGH;
unsigned long buttonPressTime;
unsigned long currentTime;
unsigned long waitPeriod = 3000;
boolean timing = false;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop()
{
currentTime = millis();
previousButtonState = currentButtonState;
currentButtonState = digitalRead(buttonPin);
if (!timing)
{
if (currentButtonState != previousButtonState && currentButtonState == LOW) //input gone LOW
{
Serial.println("\nTiming started");
buttonPressTime = currentTime;
timing = true;
actions1();
}
}
else if (currentButtonState != previousButtonState && currentButtonState == HIGH) //input gone HIGH
{
timing = false;
actions2();
}
if ((currentTime - buttonPressTime >= waitPeriod) && timing && currentButtonState == LOW)
{
timing = false;
actions3();
}
}
void actions1()
{
Serial.println("Input went LOW");
}
void actions2()
{
Serial.println("Input went HIGH within 3 seconds");
}
void actions3()
{
Serial.println("Input still LOW after 3 seconds");
}
Note that operation of the program relies on loop() not being blocked
Thank you very much for taking the time to do this! It sort of worked but not perfectly. I will play around with it some more and let you know how it goes.
Was there a reason why you moved the pin for the button from pin2 to pinA1? ALso why did you use Serial.begin(115200) instead of Serial.begin(9600)?
Thanks again,
Thomas.
It sort of worked but not perfectly
What did it do/not do that you want ?
Was there a reason why you moved the pin for the button from pin2 to pinA1? ALso why did you use Serial.begin(115200) instead of Serial.begin(9600)?
My test system has in input button hard wired on A1 and the skeleton program that I start with has the baud rate set to 115200. Beyond that, no reason
Hello,
the code below works well. However, when I input anything else it doesn't work. For example if I try to add bluetooth or SerialPrint or something else it does not work. I have tried inserting the commands in different parts of the code but nothing worked.
#include <Servo.h>
Servo s2;
int COUNT = 1;
int buzzerPin = 8;
int counter;
const byte buttonPin = 2;
byte currentButtonState;
byte previousButtonState = HIGH;
unsigned long buttonPressTime;
unsigned long currentTime;
unsigned long waitPeriod = 3000;
boolean timing = false;
void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
s2.attach(5);
}
void loop()
{
currentTime = millis();
previousButtonState = currentButtonState;
currentButtonState = digitalRead(buttonPin);
if (!timing)
buttonPressTime = currentTime;
timing = true;
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
s2.write(90);
delay(10);
if (currentButtonState != previousButtonState && currentButtonState == HIGH) //input gone HIGH
{
timing = false;
Serial.write ("*S");
tone(buzzerPin, 600);
delay(50);
noTone(buzzerPin);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
s2.write(6);
delay(600);
COUNT ++;
Serial.print("You hit ");
Serial.println(COUNT);
}
if ((currentTime - buttonPressTime >= waitPeriod) && timing && currentButtonState == LOW)
{
timing = false;
Serial.write ("*S");
tone(buzzerPin, 600);
delay(50);
noTone(buzzerPin);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
s2.write(6);
delay(600);
COUNT ++;
Serial.print("You missed ");
Serial.println(COUNT);
}
}
Don't you think that it might help if you posted the code that you tried that did not work with a description of the problems encountered ?
I assume that you noted what I said about not blocking the free running of loop() not being blocked
Thank you UKHeliBob. I have tried different things based on your advice and it worked well when it was very simple. When I tried to add a bluethooth component it worked for a single case but I need it to work as a repeated loop for a specified time interval. To do that I used the function 'for (counter = 0; counter < 3; ++counter)'. 'For' is not recognized in the code below.
#include <Servo.h>
Servo s5;
const byte buttonPin = 2;
byte currentButtonState;
byte previousButtonState = HIGH;
unsigned long buttonPressTime;
unsigned long currentTime;
unsigned long waitPeriod = 2000;
boolean timing = false;
int COUNT = 1;
int buzzerPin = 9;
int counter;
void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);
s5.attach(5);
}
void loop()
{
unsigned long start_time;
unsigned long stop_time;
currentTime = millis();
previousButtonState = currentButtonState;
currentButtonState = digitalRead(buttonPin);
if (Serial.available() > 0) {
char data = Serial.read(); // reading the data received from the bluetooth module
switch (data)
{
case '1':
buttonPressTime = currentTime;
timing = true;
for (counter = 0; counter < 3; ++counter) {
s5.write(90);
delay(10);
}
}
}
if (currentButtonState != previousButtonState && currentButtonState == HIGH) //input gone HIGH
{
timing = false;
Serial.write ("*S");
tone(buzzerPin, 600);
delay(50);
noTone(buzzerPin);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
s5.write(7);
delay(700);
COUNT ++;
Serial.print(" You hit ");
Serial.print(COUNT);
Serial.print(" Target ");
Serial.print(" in ");
Serial.print(millis() / 1000 - start_time );
Serial.println(" Seconds ");
}
if ((currentTime - buttonPressTime >= waitPeriod) && timing && currentButtonState == LOW)
{
timing = false;
Serial.write ("*S");
tone(buzzerPin, 600);
delay(50);
noTone(buzzerPin);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
s5.write(7);
delay(700);
COUNT ++;
Serial.print(" You missed ");
Serial.print(COUNT);
Serial.print(" Target ");
Serial.print(" in ");
Serial.print(millis() / 1000 - start_time );
Serial.println(" Seconds ");
}
delay(10);
}
The code compiles for me.
Can you please post all of the error message
I note that your code is littered with delay()s. This is going to make the program unresponsive at best and may also interfere with the timing of actions within it
Take this section of code, for instance
delay(700);
COUNT ++;
Serial.print(" You hit ");
Serial.print(COUNT);
Serial.print(" Target ");
Serial.print(" in ");
Serial.print(millis() / 1000 - start_time );
Serial.println(" Seconds ");
With the 700 millisecond delay there is a better than even chance you are printing the wrong value for the number of seconds elapsed
It compiles fine for me as well (I use tinkercut as a simulator). Also, there is no problem with printing the right time. The issue is that the counter function (for) is not recognized and as such it only gives one reading. I would like to be able to repeat the hit/miss cycle as many times as I set it (3 repetitions shown in the sketch below).
for (counter = 0; counter < 3; ++counter)
{
s5.write(90);
delay(10);
}
Why are you writing the same value to the servo 3 times in 30 milliseconds ?
What "reading" are you talking about ?
there is no problem with printing the right time.
How sure are you of that ?
You are delaying 750 milliseconds then reporting on the current time after the delay()s. Is that deliberate ?
This sketch moves a target using a servo and a knock/shock sensor. When the sketch starts the servo first moves to 90 degrees: if I miss the target after two seconds it moves back to 7 degrees, and if I hit it this moves the servo to 7 degrees. I would like to re-load after a hit or miss (90 degrees) and count the number of hits and misses.
The time delay is ok as this is the time needed for the target to re-load (90 degrees).
Why are you writing the same value to the servo 3 times in 30 milliseconds ?