I am trying to learn how to use subroutines and I am struggling with passing variables. I would like to learn the correct way (if there is such a thing) rather than ending up with spaghetti code.
The basic concept is to use the "debounce" example code as a subroutine for multiple push buttons on different pins. I understand that I can pass the pin number to read to the subroutine and how to return the state, the issue is how you handle the timing elements of the code to reference the timing for each button. Do I have to create global variables and assign each subroutine variable before the subroutine is called and then assign them back to the desired variable? I am sure there is an easier way.
I am struggling to even write some example code to post and was hoping someone may have some code similar that I could study and learn.
As always, your educational help is greatly appreciated.
You could pass variables by reference rather than by value so that the function can read and change the values. A little reading will help you understand the difference
Hi Mate,
Reading that again and I think I could have written that a little better, What I am thinking for now with the variables is like the following but I am sure there is a better way and I always want to improve my knowledge
I just wrote this as a concept:-
// constants won't change. They're used here to set pin numbers:
const int buttonPinOne = 2; // the number of the pushbutton pin
const int buttonPinTwo = 3;
const int ledPinOne = 13; // the number of the LED pin
const int ledPinTwo = 12;
// Variables will change:
int ledPin;
int ledState = HIGH; // the current state of the output pin
int ledStateOne = HIGH;
int ledStateTwo = HIGH;
int buttonState;
int lastButtonState = LOW;
int buttonStateOne;
int lastButtonStateOne = LOW;
int buttonStateTwo;
int lastButtonStateTwo = LOW;
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;
unsigned long lastDebounceTimeOne = 0;
unsigned long lastDebounceTimeTwo = 0;
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPinOne, INPUT);
pinMode(buttonPinTwo, INPUT);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
}
void loop() {
ledState = debounce(buttonPinOne, buttonStateOne, lastButtonStateOne, lastDebounceTimeOne);
ledSet(ledPinOne,ledState); // Do code
buttonStateOne = buttonState;
lastButtonStateOne = lastButtonState;
lastDebounceTimeOne = lastDebounceTime; // Save any changes to variable set one
ledState = debounce(buttonPinTwo, buttonStateTwo, lastButtonStateTwo, lastDebounceTimeTwo);
ledSet(ledPinTwo,ledState); // do code
buttonStateTwo = buttonState;
lastButtonStateTwo = lastButtonState;
lastDebounceTimeTwo = lastDebounceTime; // save any changes to variable set two
}
int debounce(int buttonPin, int buttonState, int lastButtonState, int LastDebounceTime) {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
lastButtonState = reading;
return ledState;
}
void ledSet(int ledPin, int ledState){
// set the LED:
digitalWrite(ledPin, ledState);
}
One problem with a single function for debounce is that it generally will also include state change detection. If you return HIGH/LOW from the function there is no way for the calling code to know if this was a state change without doing an additional state change detection. If state change detection is needed you will probably want a separate function that returns CHANGED_HIGH, CHANGED_LOW, or UNCHANGED. Since you now have two functions operating on the same data you have even more reason to define an object class.
And then there is the common case of a button that toggles a state. Another member function for the object.
Wow,
I have started to research classes and I think this will be the avenue I need to head down. As mentioned above, this is not so much for a functioning end result, more fore my own education of C++ and the best way to implement different types of functions. I really appreciate the guidance these forums give.
i have an application that monitors a number of buttons. chkButtons() checks a list of pins in an array, sets a butPress[] which is cleared each iteration and set when a button change occurs and the button state is low. it also returns a true result if any button is pressed used as an abort for things that might block.
in my tiny application (~ 2400 lines), butPress[] is used globally (or at least globally w/in the file). in a much larger application, butPress [] could be hidden and a separate function called to check if a particular button was pressed.
for my applications, i simply delay for 10 msec if there is a button state change to debounce