I have a project, which has two separate "jobs" in the loop code.
One is the "calibration" of the projects constraints
the other is "random movement within the constraints"
i don't THINK i can calibrate within the setup of the sketch
so what i have is "while a button is pressed, its in calibrate, else its in random"
what i want is, press the button to toggle between the two modes
rather than just ask for an answer , i have come up with this plan (which may seem simple/logical/daft to those who know) and was hoping for comment/review
So "integers" are the working part of the "duino
i figure, create an "int" called "toggle"
and then create a simple "if" loop.
"if int is a 0, and button is pressed, flip it to 1"
"if int is a 1, and button is pressed, flip it to 0"
then just read from this using an if/else over the whole sketch as appropriate.
rather than just ask for an answer , i have come up with this plan (which may seem simple/logical/daft to those who know) and was hoping for comment/review
OK. The approach described is fine. Except that the "if a button is pressed" bit needs work. For how long? Your idea of "the button was pressed" and the Arduino's may be quite different.
It appears that what you really mean is that when the switch is pressed now, but was not before, toggle the value.
It is that "but was not before" bit that is critical. It means that you need to keep track of the previous state of the switch, and compare that to the current state of the switch, to detect when a transition has occurred - from released to pressed or from pressed to released. Note, too, that you want to know which transition occurred, so you don't toggle again when releasing the switch. The current state of the switch will tell you which transition occurred.
you are missing an opening curly bracket " {" after this line:
if(currState != prevState)
and then you also need to add one more to the end of the void loop.
i think also that maybe you should change this line:
prevState = currState;
to a different place. Where you have it now, it is just working if the button is pressed. But you also want it to update the prevState on each pass, even if the button isn't pressed.
@ tasos
That last sketch works perfectly for what I am trying to achieve.
I am using a piezo switch as these are waterproof but they have no feel to them so I need to add a 1 second buzzer sound each time. It is to turn off & on a light and I will repeat this for the hydraulics off & on.
I had a play with trying to add this feature, but I can't work out how to get the buzzer to sound once only for 1 second.
theautomationguy:
@ tasos
Can you please explain why you have
digitalWrite(ledRd, ledRd_Bool); // set it at startup
digitalWrite(ledGn, ledGn_Bool); // set it at startup
in the void setup
I am glad it is working as you wish.
In some post you have you're code i see you try to make at start, one led to be on and the other to be off, ( you choose it in the variable
int prevState = HIGH;
int currState;
so in the case you use (digitalWrite ) at setup you can choose the led in you're case, which to be on and which to be off, before you press the button. Be in mind in setup routine everything it will run only one time when the power it is on.
Thanks Tasos,
I understand.
I understand the tones, but I am just going to use a 5 volt buzzer. But I cant work out how to get the buzzer to sound in that sketch for 1 second (& not repeat) everytime the button is pushed.
I found this while investigating debounce & it has flip flop. I added the pull up resistor & managed to invert the right parts to get it to work. I want to add a 1 off 1 second buzz each time the button is pushed. But get errors everytime I try to add code. Is anyone able to steer me in the right direction how to do this? Thanks in advance.
/* switch
*
* Each time the input pin goes from HIGH to LOW (e.g. because of a push-button
* press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's
* a minimum delay between toggles to debounce the circuit (i.e. to ignore
* noise).
*
* David A. Mellis
* 21 November 2006
*/
int inPin = 2; // the number of the input pin
int buzzPin = 8;
int outPin = 13; // the number of the output pin
int state = LOW; // the current state of the output pin
int reading; // the current reading from the input pin
int previous = HIGH; // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 300; // original 300 debounce time, increase if the output flickers
void setup()
{
pinMode(inPin, INPUT_PULLUP);
pinMode(buzzPin, OUTPUT);
pinMode(outPin, OUTPUT);
}
void loop()
{
reading = digitalRead(inPin);
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (reading == LOW && previous == HIGH && millis() - time > debounce) {
if (state == LOW)
state = HIGH;
else
state = LOW;
time = millis();
}
digitalWrite(outPin, state);
previous = reading;
}
I managed to use tasosstr's sketch & get the 1 sec buzzer I required, this also fixed the switch bounce, I guess the delay caused that.
const int swPin = 2;
const int ledRd = 9;
const int ledGn = 8;
const int buzzPin = 12;
bool ledRd_Bool = LOW,ledGn_Bool = HIGH;
void setup() {
pinMode(swPin, INPUT_PULLUP);
pinMode(ledGn, OUTPUT);
pinMode(ledRd, OUTPUT);
digitalWrite(ledRd, ledRd_Bool); // set it at startup
digitalWrite(ledGn, ledGn_Bool); // set it at startup
}
void loop() {
if(digitalRead(swPin) == LOW) {
ledRd_Bool = !ledRd_Bool;
ledGn_Bool = !ledGn_Bool;
while (digitalRead(swPin) == LOW) {}; // Wait here until release the button
digitalWrite(ledRd, ledRd_Bool);
digitalWrite(ledGn, ledGn_Bool);
digitalWrite(buzzPin, HIGH);
delay(1000);
digitalWrite(buzzPin, LOW);
}
}
Now to make it better one tone for off & another tone for on. Any suggestions out there. I will use another output pin for another buzzer, but after that I will create different tones which won't be difficult. Arduino's are addictive
@ boguz
I have managed to get it all to work using delay. I am not sure where the code you have just explained to me goes boguz.
Are you able to c&p what I have pasted here & make the changes, if that isnt too much trouble. I am struggling to grasp where the codes actually go even though I am starting to understand what they are doing.
const int swPin = 2;
const int ledRd = 9;
const int piezoPin = 10;
const int buzzPin = 12;
boolean ledRd_Bool = LOW;
void setup() {
pinMode(swPin, INPUT_PULLUP);
pinMode(buzzPin, OUTPUT);
pinMode(piezoPin, OUTPUT);
pinMode(ledRd, OUTPUT);
}
void loop() {
if(digitalRead(swPin) == LOW) {
ledRd_Bool = !ledRd_Bool;
while (digitalRead(swPin) == LOW) {}; // Wait here until release the button
digitalWrite(ledRd, ledRd_Bool);
digitalWrite(piezoPin, ledRd_Bool);
digitalWrite(buzzPin, !ledRd_Bool);
delay(800);
digitalWrite(piezoPin, LOW);
digitalWrite(buzzPin, LOW);
}
}
I modify the first code for you in one line to get the buzzer with a sound for a second.
const int swPin = 2;
const int ledRd = 9;
const int ledGn = 8;
#define buz 3 // Connect buzzer to pin 3 and the other pin to gnd
bool ledRd_Bool = LOW,ledGn_Bool = HIGH;
void setup() {
pinMode(swPin, INPUT_PULLUP); // make pin 2 as input and activate internall pull up resistor
pinMode(ledGn, OUTPUT);
pinMode(ledRd, OUTPUT);
}
void loop() {
if(digitalRead(swPin) == LOW) {
ledRd_Bool = !ledRd_Bool; // invert ledRd_Bool flag if it is HIGH make it LOW if it is LOW make it HIGH
ledGn_Bool = !ledGn_Bool;
while (digitalRead(swPin) == LOW) {}; // Wait here until release the button
digitalWrite(ledRd, ledRd_Bool);
digitalWrite(ledGn, ledGn_Bool);
tone(buz,450,1000); // create a tone on pin 3, create a 450Hz freq. for 1 Second
}
}
and i make some comment to explain you a bit more what some lines does because i understand now you learn c.
boguz use a delay check without block the entire program but in you're case tone(buz,450,1000); // create a tone on pin 3, create a 450Hz freq. for 1 Second this line does for you without any extra code.
Now the above it is to give you one sound on each button press, do you want another sound for each led change on High ?
if yes tell me and i will make an example for you.
the code while (digitalRead(swPin) == LOW) {}; // Wait here until release the button it is used for debounce of the button for the time you hold the button pressed then the program stay there.
const int swPin = 2;
const int ledRd = 9;
const int ledGn = 8;
#define buz 3 // Connect buzzer to pin 3 and the other pin to gnd
bool ledRd_Bool = LOW,ledGn_Bool = HIGH;
void setup() {
pinMode(swPin, INPUT_PULLUP); // make pin 2 as input and activate internall pull up resistor
pinMode(ledGn, OUTPUT);
pinMode(ledRd, OUTPUT);
}
void loop() {
if(digitalRead(swPin) == LOW) {
ledRd_Bool = !ledRd_Bool; // invert ledRd_Bool flag if it is HIGH make it LOW if it is LOW make it HIGH
ledGn_Bool = !ledGn_Bool;
while (digitalRead(swPin) == LOW) {}; // Wait here until release the button
digitalWrite(ledRd, ledRd_Bool);
digitalWrite(ledGn, ledGn_Bool);
//tone(buz,450,1000); // create a tone on pin 3, create a 450Hz freq. for 1 Second
if (ledRd_Bool == HIGH){ // Check if red led it is high then make a sound of 450Hz for a second
tone(buz,450,1000);
}
if (ledGn_Bool == HIGH){ // Check if Green led it is high then make a sound of 900Hz for a second
tone(buz,900,1000);
}
}
}