Arduino Button running in Loop without stopping

Hy there,
im new to Arduino. I am trying to build a stream Cheap with 8 buttons that will run different shortcuts. But I don't just want to copy a project, I want to understand it.
Here is the original Project:
http://www.partsnotincluded.com/electronics/diy-stream-deck-mini-macro-keyboard
but I also want to include Layers. So when I Push button 8 (Pin 9) it will change to a different Layer.
Somewhat like this:
https://github.com/nickfrancisco-s/StreamCheap

So I tried some code. But whenever I connect ground and Pin 9 it just runs through the Layers without stopping. (so my serial Log just runs "Test1Test2Test3Test4")
What am I doing wrong? How do I get it to just see it as the button was pressed once.

#include <Bounce2.h>
Bounce debouncer = Bounce();

int counter = 0;

const int buttonPin = 9;
int buttonState = 0;

void setup() {
  pinMode(1, INPUT_PULLUP);

  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  debouncer.attach(buttonPin);
  debouncer.interval(5);
}

void loop() {
  {
    // Update the debouncer
    debouncer.update();
    // Get the update value
    
    int value = debouncer.read();
    
    if (value == LOW) {
      counter++;
      digitalWrite(buttonPin, HIGH);

      //Reset count if over max mode number
      if (counter == 4)
      {
        counter = 1;
      }else {digitalWrite(buttonPin, HIGH);
}
    }
  }
  switch (counter) {
    case 1:
      Serial.print("Test1");
      break;
    case 2:
      Serial.print("Test2");
      break;
    case 3:
      Serial.print("Test3");
      break;
    case 4:
      Serial.print("Test4");
      break;
  }
}

You need to detect when the button becomes pressed rather than when it is pressed
See the StateChangeDetection example in the IDE

So I included

   // read the pushbutton input pin:
    buttonState = digitalRead(value);

    // compare the buttonState to its previous state
    if (buttonState != lastButtonState) {
      // if the state has changed, increment the counter
      if (buttonState == HIGH) {

And it helped, that it didn't run through the loop anymore, but it still is giving me "Test1Test1Test1" in the serial monitor.

Is there something else I am missing?

I am connecting ground and Pin 9 with a simple tactile switch.

Hi Josch,

you should post your complete sketch in a new posting. Exactly that sketch that shows the behaviour you have described. In most cases it is very hard to assume what you have coded that it does not yet work as you want it.

You can post code by using this method that adds the code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

best regards Stefan

Maybe not saving the current state as the previous state ready for the next test but without seeing your complete sketch only you will know

#include "Keyboard.h"

int counter = 0;

const int buttonPin = 9;
const int button1 = 2;
const int button2 = 3;

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(button1, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  {
    // read the pushbutton input pin:
    buttonState = digitalRead(buttonPin);

    // compare the buttonState to its previous state
    if (buttonState != lastButtonState) {
      // if the state has changed, increment the counter
      if (buttonState == HIGH) {

        counter++;

        //Reset count if over max mode number
        if (counter == 4)
        {
          counter = 1;
        }
      }
      // save the current state as the last state, for next time through the loop
      lastButtonState = buttonState;
    }
    switch (counter) {
      case 1:
          Serial.print("Test1");
          if (digitalRead(button1) == HIGH) {
            Keyboard.press(99);
          }
        break;
      case 2:
        Serial.print("Test2");
        if (digitalRead(button1) == HIGH) {
          Keyboard.press(100);
        }
        break;
      case 3:
        Serial.print("Test3");
        if (digitalRead(button1) == HIGH) {
          Keyboard.press(97);
        }
        break;
      case 4:
        Serial.print("Test4");
        if (digitalRead(button1) == HIGH) {
          Keyboard.press(55);
        }
        break;
    }
  }
}

AHa...

You seem to have changed your mind as to which sketch you are having problems with

I'm sorry, I had deleted the Serial.print for a test.
I copied the wrong version. I am just trying to understand why I get a Loop instead of a single button push.

Here is my current Code again.

#include "Keyboard.h"

int counter = 0;

const int buttonPin = 9;
const int button1 = 2;
const int button2 = 3;

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(button1, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  {
    // read the pushbutton input pin:
    buttonState = digitalRead(buttonPin);

    // compare the buttonState to its previous state
    if (buttonState != lastButtonState) {
      // if the state has changed, increment the counter
      if (buttonState == HIGH) {

        counter++;

        //Reset count if over max mode number
        if (counter == 4)
        {
          counter = 1;
        }
      }
      // save the current state as the last state, for next time through the loop
      lastButtonState = buttonState;
    }
    switch (counter) {
      case 1:
          Serial.print("Test1");
          if (digitalRead(button1) == HIGH) {
            Keyboard.press(99);
          }
        break;
      case 2:
        Serial.print("Test2");
        if (digitalRead(button1) == HIGH) {
          Keyboard.press(100);
        }
        break;
      case 3:
        Serial.print("Test3");
        if (digitalRead(button1) == HIGH) {
          Keyboard.press(97);
        }
        break;
      case 4:
        Serial.print("Test4");
        if (digitalRead(button1) == HIGH) {
          Keyboard.press(55);
        }
        break;
    }
  }
}

This part of your code does the state-change-detection

    // read the pushbutton input pin:
    buttonState = digitalRead(buttonPin);

    // compare the buttonState to its previous state
    if (buttonState != lastButtonState) {
      // if the state has changed, increment the counter
      if (buttonState == HIGH) {

        counter++;

        //Reset count if over max mode number
        if (counter == 4)
        {
          counter = 1;
        }
      }
      // save the current state as the last state, for next time through the loop
      lastButtonState = buttonState;
    }

but the part below that does the serial print is executed independent from the if-condition

    if (buttonState != lastButtonState) {

and this is the reason why you get a repeated printed test1 test1 test1
If it shall be printed only one time you have either to put the whole switch-case-structure inside the if-condition

or to use another flag-variable something like
boolean textPrinted;

if(textPrinted == false) {
  textPrinted = true;
  Serial.print("Test1");
}

and inside the if-codition

 if (buttonState == HIGH)
textPrinted = false;

changing textPrinted from false to true inside the if-condition that checks for (textPrinted == false)
locks itselfs and becomes reset if a new button-press occured.

best regards Stefan

Thank you so much! That did the trick.a

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.