arduino button counter

Ep. 58 – Arduino Advanced Input & Button Control, Debouncing, Counters & Multitasking

Button & Input implementation on Arduino is fairly straight forward. However, many of you have been asking me questions with regards to implementing more advanced features such as an Arduino Button Counter. This tutorial is dedicated to exploring how you can properly check the status of your inputs and how you can utilize them within your software. We will start over with button debouncing. I’ve covered it in another video, but it’s something worth revisiting and knowing how to implement. We will also take a look at how to build multithreading, asynchronous checks and an arduino button counter in your software.

Debouncing

Button debouncing has been covered by many, yet many are still struggling with the concept. The bottom line is that buttons are mechanical devices which are not ideal and thus electrical / software engineers are left with the task to compensate for their shortcomings. Arduino has a very simple example which demonstrates how to properly implement this. You will need it in order to implement a proper arduino button counter which we will be covering in this tutorial.

Arduino Button Debouncing Example: Click Here.
A library for debouncing your inputs: Click Here.

Pull-up Requirement for an Arduino Input

I’m still confused as to why so many people keep asking me about pull-up resistors. The Atmega328 micro controller (Datasheet: Click Here) has built in pull-up resistors. This allows a single line of code to enable them and have no need for an external pull-up. If you’re still worried about them, 10k ohm should do the trick.

Hardware & Software for the Project

I’ve built an extremely simple setup which is composed of two buttons and an LED. From the picture below and the software, you should be easily able to figure out where my inputs & outputs going.

input output arduino button counter

The full program we will be implementing in this project is available here: Arduino Advanced Input Control. The Arduino IDE used is version 1.6.9.

Arduino Input Button Counters & State Implementation

In this section, we will be going over the program which was written for this tutorial. Each section will be explained in detail. If you have any questions after you’ve gone through the tutorial, feel free to post them below.

const int numOfInputs = 2;
const int inputPins[numOfInputs] = {2,3};
const int outputPin = 10;
int LEDState = 0;
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW,LOW};
bool inputFlags[numOfInputs] = {LOW,LOW};
int inputCounters[numOfInputs];
long lastDebounceTime[numOfInputs] = {0,0};
long debounceDelay = 50;

We begin out program by initializing all the variables and constants for the Inputs / Outputs. We are trying to implement an expendable program which leads us to have an array of inputs rather than a single line call out. We’ve placed the buttons on pins 2 & 3 and the LED (output) on pin 10 of the board. The following arrays are all used in the debouncing and state tracking process. For obvious reasons, each one of those arrays corresponds to the number of inputs we are using.

void setup() {
for(int i = 0; i < numOfInputs; i++) { pinMode(inputPins[i], INPUT); digitalWrite(inputPins[i], HIGH); // pull-up 20k } Serial.begin(9600); pinMode(outputPin, OUTPUT); }

The setup function is very simple; it has a "for" loop which calls out each input first. Notice that it enables an internal pull-up resistor for every input we will be using. It also implements the LED output and a serial function which we will be suing for debugging.

void loop() {
setInputFlags();
resolveInputFlags();
resolveOutputs();
}

The loop function is "simplistic" based on the number of lines. However, we've made our code very segmented on purpose. This way, you can de-couple any section and use it in your own program; the code is very modular.

void setInputFlags() {
for(int i = 0; i < numOfInputs; i++) { int reading = digitalRead(inputPins[i]); if (reading != lastInputState[i]) { lastDebounceTime[i] = millis(); } if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (reading != inputState[i]) {
inputState[i] = reading;
if (inputState[i] == HIGH) {
inputFlags[i] = HIGH;
}
}
}
lastInputState[i] = reading;
}
}

The "setInputFlags()" function takes care of debouncing our inputs. This function allows us to have much better Arduino Button Control and receive reliable signals back to our board. It will keep waiting until the button state is "LOW" and wait "debouceDelay" (50ms) before taking it into account. If at that time, the input is still low, it will wait for the button to be released before registering a flag.

Using flags is crucial. You can implement such flags and only react to them when you desire. In a way, this is as close as you can get to multithreaded programming on a micro controller. In order words, because the program is not using any timers or wait instructions, you can rely on these flags to be set and resolved at a later time.

void resolveInputFlags() {
for(int i = 0; i < numOfInputs; i++) { if(inputFlags[i] == HIGH) { // Input Toggle Logic inputCounters[i]++; updateLEDState(i); printString(i); inputFlags[i] = LOW; } } }

Resolving the flags we've previously created is crucial. Our goal is to store a flag bit until we are able to apply the logic and get rid of it. The above function does exactly that. This functionality is what gives our implementation such a smooth arduino button counter in the following step.

void printString(int output) {
Serial.print("Input ");
Serial.print(output);
Serial.print(" was pressed ");
Serial.print(inputCounters[output]);
Serial.println(" times.");
}
void updateLEDState(int input) {
// input 0 = State 0 and 1
if(input == 0) {
if(LEDState == 0) {
LEDState = 1;
}else{
LEDState = 0;
}
// input 1 = State 2 to 6
}else if(input == 1) { // 2,3,4,5,6,2,3,4,5,6,2,
if(LEDState == 0 || LEDState == 1 || LEDState > 5) {
LEDState = 2;
}else{
LEDState++;
}
}
}

The printString function is very straight forward; we won't be going over what it's doing. However, the updateLEDState function is a little more complex. What I'm trying to achieve is having a total of 7 states. The first two (0 & 1) are being controlled by the first button. The other 5 are toggled by the 2nd button. Notice that this logic has nothing to do with our final output. All it's doing is state transitions.

void resolveOutputs() {
switch (LEDState) {
case 0:
digitalWrite(outputPin, LOW);
break;
case 1:
digitalWrite(outputPin, HIGH);
break;
case 2:
analogWrite(outputPin, 30);
break;
case 3:
analogWrite(outputPin, 70);
break;
case 4:
analogWrite(outputPin, 100);
break;
case 5:
analogWrite(outputPin, 155);
break;
case 6:
analogWrite(outputPin, 255);
break;
default:
break;
}

During each cycle, we take a look at the state of the LED and change it accordingly. Just as described above, we have 7 different states and this function is responsible for the actual output. Arduino button counters which we've implemented earlier are what makes this possible.

Conclusion - Arduino Button Counter Implemented

A lot of you have been asking me about the way to implement an arduino button counter. This tutorial went over advanced input & output control which hopefully clears things out. If anyone still has any questions with regards to this; feel free to leave a comment below.

Link to FULL SOFTWARE: Click Here

Thank you for reading & watching,
- EEEnthusiast

Leave a Reply

Your email address will not be published.

CommentLuv badge