HI, Iam trying to make a simple counter using a push button with arduino. What I want to do is to count only one step whenever the push button is pressed no matter how long it is pressed. Anyone could help me about this? Iam thinking if arduino can know if the button state is changed from 0 to 1 to 0 and only counts when the buttonstate is on 1.
Moved your topic to it's current location as it is more suitable.
Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.
This reads the input from 4 (easily changed) push buttons and increments a counter. It will repeat if you hold the button pressed for long enough, I leave it to you to test that and modify if you want to.
/* Simple button debounce for 4 buttons. Increments a count and sends the updated count to the serial monitor once per button press */
/* Tested on an Uno */
/* Connect simple push to make buttons between 0V and pin 2, 0V and pin 3, 0V and pin 4 and between 0V and pin 5 */
#define noOfButtons 4 //Exactly what it says; must be the same as the number of elements in buttonPins
#define bounceDelay 20 //Minimum delay before regarding a button as being pressed and debounced
#define minButtonPress 3 //Number of times the button has to be detected as pressed before the press is considered to be valid
const int buttonPins[] = {2, 3, 4, 5}; // Input pins to use, connect buttons between these pins and 0V
uint32_t previousMillis[noOfButtons]; // Timers to time out bounce duration for each button
uint8_t pressCount[noOfButtons]; // Counts the number of times the button is detected as pressed, when this count reaches minButtonPress button is regared as debounced
uint8_t testCount[noOfButtons]; //Test count, incremented once per button press
void setup() {
uint8_t i;
uint32_t baudrate = 115200;
Serial.begin(baudrate);
Serial.println("");
Serial.print("Serial port connected: ");
Serial.println(baudrate);
for (i = 0; i < noOfButtons; ++i) {
pinMode(buttonPins[i], INPUT_PULLUP);
Serial.print("Testcount ");
Serial.print(i);
Serial.print(" = ");
Serial.println(testCount[i]);
}
}
void loop() {
debounce();
delay(10); //Your other code goes here instead of this delay. DO NOT leave this delay here, it's ONLY for demonstration.
}
void debounce() {
uint8_t i;
uint32_t currentMillis = millis();
for (i = 0; i < noOfButtons; ++i) {
if (digitalRead(buttonPins[i])) { //Input is high, button not pressed or in the middle of bouncing and happens to be high
previousMillis[i] = currentMillis; //Set previousMillis to millis to reset timeout
pressCount[i] = 0; //Set the number of times the button has been detected as pressed to 0
} else {
if (currentMillis - previousMillis[i] > bounceDelay) {
previousMillis[i] = currentMillis; //Set previousMillis to millis to reset timeout
++pressCount[i];
if (pressCount[i] == minButtonPress) {
doStuff(i); //Button has been debounced. Call function to do whatever you want done.
}
}
}
}
}
// Function to do whatever you want done once the button has been debounced.
// In this example it increments a counter and send the count to the serial monitor.
// Put your own functions here to do whatever you like.
void doStuff(uint8_t buttonNumber) {
++testCount[buttonNumber];
Serial.print("Button ");
Serial.print(buttonNumber);
Serial.print(" testcount = ");
Serial.println (testCount[buttonNumber]);
}
PerryBebbington:
This reads the input from 4 (easily changed) push buttons and increments a counter. It will repeat if you hold the button pressed for long enough, I leave it to you to test that and modify if you want to./* Simple button debounce for 4 buttons. Increments a count and sends the updated count to the serial monitor once per button press */
/* Tested on an Uno /
/ Connect simple push to make buttons between 0V and pin 2, 0V and pin 3, 0V and pin 4 and between 0V and pin 5 */
#define noOfButtons 4 //Exactly what it says; must be the same as the number of elements in buttonPins
#define bounceDelay 20 //Minimum delay before regarding a button as being pressed and debounced
#define minButtonPress 3 //Number of times the button has to be detected as pressed before the press is considered to be valid
const int buttonPins[] = {2, 3, 4, 5}; // Input pins to use, connect buttons between these pins and 0V
uint32_t previousMillis[noOfButtons]; // Timers to time out bounce duration for each button
uint8_t pressCount[noOfButtons]; // Counts the number of times the button is detected as pressed, when this count reaches minButtonPress button is regared as debounced
uint8_t testCount[noOfButtons]; //Test count, incremented once per button press
void setup() {
uint8_t i;
uint32_t baudrate = 115200;
Serial.begin(baudrate);
Serial.println("");
Serial.print("Serial port connected: ");
Serial.println(baudrate);
for (i = 0; i < noOfButtons; ++i) {
pinMode(buttonPins[i], INPUT_PULLUP);
Serial.print("Testcount ");
Serial.print(i);
Serial.print(" = ");
Serial.println(testCount[i]);
}
}
void loop() {
debounce();
delay(10); //Your other code goes here instead of this delay. DO NOT leave this delay here, it's ONLY for demonstration.
}
void debounce() {
uint8_t i;
uint32_t currentMillis = millis();
for (i = 0; i < noOfButtons; ++i) {
if (digitalRead(buttonPins[i])) { //Input is high, button not pressed or in the middle of bouncing and happens to be high
previousMillis[i] = currentMillis; //Set previousMillis to millis to reset timeout
pressCount[i] = 0; //Set the number of times the button has been detected as pressed to 0
} else {
if (currentMillis - previousMillis[i] > bounceDelay) {
previousMillis[i] = currentMillis; //Set previousMillis to millis to reset timeout
++pressCount[i];
if (pressCount[i] == minButtonPress) {
doStuff(i); //Button has been debounced. Call function to do whatever you want done.
}
}
}
}
}
// Function to do whatever you want done once the button has been debounced.
// In this example it increments a counter and send the count to the serial monitor.
// Put your own functions here to do whatever you like.
void doStuff(uint8_t buttonNumber) {
++testCount[buttonNumber];
Serial.print("Button ");
Serial.print(buttonNumber);
Serial.print(" testcount = ");
Serial.println (testCount[buttonNumber]);
}
Thank you, but that is the problem so I dont consider using debounce for this., I need the button to only increment one step no matter how long I pressed the button
open04:
Thank you, but that is the problem so I don't consider using debounce for this., I need the button to only increment one step no matter how long I pressed the button
The idea was you try the code, get it working, then press the button for ages and see when it repeats. Then you study the code and find out what needs to change to stop it repeating. I'm offering this as a starting point, stopping it repeating is a simple change but I'm not prepared to do that for you, you have to do some work yourself.
If you just want finished, working code please click on 'report to moderator' and ask for this to be moved to gigs and collaborations'. Someone there will write code for you for a fee.
Try using a + or - edge detect interrupt feature. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil
PerryBebbington:
The idea was you try the code, get it working, then press the button for ages and see when it repeats. Then you study the code and find out what needs to change to stop it repeating. I'm offering this as a starting point, stopping it repeating is a simple change but I'm not prepared to do that for you, you have to do some work yourself.If you just want finished, working code please click on 'report to moderator' and ask for this to be moved to gigs and collaborations'. Someone there will write code for you for a fee.
Im sorry, but that is the first thing Ive tried and it doesnt worked out. but anyway Ive solved my problem. Thank you very much for the reply.
PS: I never want a finished code. I just want a little help and maybe a brainstorming with you guys. Thank you
You are on the right track, search state change (there is a "sticky") detailing how to monitor and respond to state changes.
open04:
Thank you, but that is the problem so I dont consider using debounce for this., I need the button to only increment one step no matter how long I pressed the button
That's not what bounce is about. Bounce occurs in the first milliseconds of every time the switch closes or opens.
If your code is fast the bouncing will look like many press and release events for one single press.
Cheap debounce uses a delay or timed wait and only catches the first pin state change.
What you need to do is detect CHANGE in pin state rather than trying to run directly from pin state.
Kiwi_Bloke:
You are on the right track, search state change (there is a "sticky") detailing how to monitor and respond to state changes.
Thank you.. Ill search for that!.
GoForSmoke:
That's not what bounce is about. Bounce occurs in the first milliseconds of every time the switch closes or opens.
If your code is fast the bouncing will look like many press and release events for one single press.Cheap debounce uses a delay or timed wait and only catches the first pin state change.
What you need to do is detect CHANGE in pin state rather than trying to run directly from pin state.
exactly what I need, Thank you for understanding