Hi folks,
I've made a simple sketch to make life easier for beginners and intermediairs!
Just take a look into the sketch, and if you have questions you may ask them directly under this post!
I will try to answer them all.
/* DISCLAIMER.
* Tutorial, button PRESSED and button RELEASED Example.
* To make things easier!
* Author J.Molenaar.
*/
int released = 0; // used to store value if released [in case of 0, means released].
int pressed = 0; // used to store value if pressed [in case of 1, means pressed].
bool Switch = true; // used to switch within the millis loop.
unsigned long currentMillis; // Store current millis().
unsigned long previousMillis; // store last measured millis().
void setup() {
Serial.begin(9600);
Serial.println("Started!");
Serial.println("");
pinMode(13,INPUT);
}
void loop() {
currentMillis = millis();
if(currentMillis - previousMillis > 25){ // Millis timer fuction, to get little bugs out while measuring. the 25 value stands for the delay, do not go below 25.
Switch = !Switch; // Switch bool Switch to the negative site, so true becomes false and false becomes true.
if(Switch == true){if(buttonReleased(13)){Serial.println("Released");}} // if bool Switch = true, and buttonReleased(pin) = true, it will print "Released" in the serial monitor.
if(Switch == false){if(buttonPressed(13)){Serial.println("Pressed");}} // if bool Switch = false, and buttonPressed(pin) = true, it will print "Pressed" in the serial monitor.
previousMillis = currentMillis; // Updates previousMillis to curentMillis.
}
}
bool buttonReleased(int bttn){ // Bool function for buttonReleased. for the working of this function just ask!
if(digitalRead(bttn) == HIGH){
released = 1;
return false;
}else if(digitalRead(bttn) < released){
released = 0;
return true;
}
delay(50);
}
bool buttonPressed(int bttn){ // Bool function for buttonPressed. for the working of this function just ask!
int i = 0;
if(digitalRead(bttn) == HIGH){
i = 1;
if(pressed < 1){
pressed = 1;
return true;
}else{
return false;
}
}else{
i=0;
pressed=0;
return false;
}
delay(50);
}
I liked your idea but wasnt happy about mixing millis() timing and delays; also could not understand why two seperate functions were needed. Here is my attempt at the same task, which appears to perform the same function
/*
Alternative button press release sketch based on idea by J.Molenaar
Sketch shows use of #define, millis() timing, and passing & returning values from a function
The sketch works on an Arduino Uno and requires one button switch connected between pin 13 and ground.
Output on the serial monitor.
Author: J L. Errington
*/
#define button 13 //the #define assigns a name to a constant value. Note there is no equals or semicolon!
bool oldState = 1, newState = 1; //used to compare current and previous state of the button
unsigned long currentTime, previousTime; // used for millis() timing
void setup() {
Serial.begin(9600);
Serial.println("Started! \n");
pinMode(button, INPUT_PULLUP);
oldState = !digitalRead(button); //inverse logic as button press gives a logic 0
newState = oldState;
}
void loop() {
currentTime = millis();
if (currentTime - previousTime > 50) { // Millis timer function, to allow time for switch bounce to expire.
if (buttonChanged(button)) {
if (newState == 1) { Serial.println("Button pressed "); } else { Serial.println("Button released "); };
}
previousTime = currentTime;
}
}
bool buttonChanged(int bttn) {
bool changed = 0;
newState = !digitalRead(bttn);
if (newState != oldState) { //its changed
changed = 1;
oldState = newState;
}
return (changed);
}
if you have questions you may ask them directly under this post!
I will try to answer them all.
Why do Switch and currentMillis have global scope?
If a button isn't pressed (closed?), then surely it is released (open?)?
I weondered about that - dont know if the OP is intending to have a flag that shows the last active condition
I'm not hella keen on reversing the state of the button read:
oldState = !digitalRead(button); //inverse logic as button press gives a logic 0
... to force a press to be a high.
Everyone is used to a press being a low and there's nowt wrong with that.
And this seems back to front to me logically, although it makes no difference (apart from the ! thing.)
oldState = !digitalRead(button); //inverse logic as button press gives a logic 0
newState = oldState;
It makes more sense to me to read the pin into the current (new as you call it) and then make the old one the same:
newState = digitalRead(button); //inverse logic as button press gives a logic 0
oldState = newState;
Previous states are not actually the result of their own reads; they're the result of saving the out-going new or current state into a variable to use as the (now) old version.
Everyone is used to a press being a low and there's nowt wrong with that.
I refer you to this site
Starting in C++, a new data type was added to the C language - boolean, declared as type "bool".
boolean constants are the values "true" and "false". ( new keywords in C++ )
Variables of type bool can be used to store true or false boolean values.
Zero is used to represent false, and One is used to represent true.
Of course the significance of any logical variable depends on how we define it.
I'd find it confusing if buttonChanged(int bttn) returned a 1 to indicate it had NOT changed.