Push Button switch issues with Digital Read for a Beat Sequencer

Hey everybody, for about a month I have been working on a final project for my music class in university and it has consisted of building and interfacing a beat sequencer to Max/MSP. It is due in about a week so I am more or less stuck to my decisions at this point and need some help on a basic problem. On my physical controller I have eight lines that begin at a common source node (+5 V) on a bread board from the Arduino Uno, go to a push button switch, and end on a 10 kohm resistor connected to ground. I have a digital input attached in between the end of the switch and 10 kohm resistor so it is in a pull down configuration and goes 5V -> push button -> digital input -> 10 kohm resistance -> GRND.

My problem is with what I believe to be floating pin issues that result in the digital read of each of these pins returning some-what random results when buttons are pressed (Should return a HIGH when pressed and a LOW otherwise). Due to my wires being connected to the breadboard without being soldered on I worry that they are picking up noise. I would love to solder these on but I don't have the means by which to do so within a week. Are there any recommendations you can make to me which will help me resolve my issue? Would it make sense to activate the Arduino's internal PUP to make sure that random values aren't being written to my input pins? Please let me know and I will provide more details if needed!

Here’s a picture of an individual button for reference.

Well, conventional wisdom is that pullups (active low) are preferable to pulldowns (active high like you have) anyway, and then if you do go the pullup route, internal is way easier than external.

If you do change it, remember (I'm sure you will...) to reverse your logic in the code from active high to active low.

But that said, please add a sketch of one of those configurations just so others can check it's actually what you think it is. Pictures and 1000s of words.....

ls306beatsequencer: Here's a picture of an individual button for reference.

Let's have a schematic rather please....

Well, firstly you have it wired wrong if you are taking the pushbuttons to 5V and using pull-downs, as it is much safer and more reliable to use pull-ups - yes, the internal pull-ups - and the switches to ground. This avoids bringing your 5V line out from the board and a potential, however slight, of accidentally shorting the 5V line to ground.

Secondly, your problem when buttons are pressed suggests that you do not understand the problem of bounce as it relates to all kinds of mechanical switches.

Here is an example code of debouncing to make a toggle function reliably work:

// Button toggle with extreme reliability!

const int led1Pin =  13;    // LED pin number
const int button1 =  10;
int led1State = LOW;        // initialise the LED
char bstate1 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led1State == LOW) {
      led1State = HIGH;
    }
    else {
      led1State = LOW; 
    } 
    digitalWrite(led1Pin, led1State);
  } 
}

In fact, a quite simple variant of this code can be used to debounce eight buttons concurrently. And of course, though this code is [u]configured[/u] to respond specifically to a new "make" operation, it is equally relevant to conveying a reliable "on-off" determination.

Those square buttons are notorious for causing wiring problems.... you need to be 100% sure you're actually switching what you think you're switching.

Hey JimboZ, here is a schematic of my button configuration, it is only four buttons so just imagine that there are four more identical lines attached here.

Paul__B, I see what you are getting at with the debounce but I already have code in place to account for it. I essentially ripped the debounce code from the debounce example given by Arduino. I guess according to your advice and JimboZ’s though I should attempt this circuit in a PUP manner with internal resistances so as to avoid more noise, I will take this advice to heart and attempt it asap as it sounds like a good idea.

Out of curiosity, I should know this but forgot it from class, why is PUP always preferable to PDN?

ls306beatsequencer: why is PUP always preferable to PDN?

Paul explained that here:

Paul__B: Well, firstly you have it wired wrong if you are taking the pushbuttons to 5V and using pull-downs, as it is much safer and more reliable to use pull-ups - yes, the internal pull-ups - and the switches to ground. This avoids bringing your 5V line out from the board and a potential, however slight, of accidentally shorting the 5V line to ground.

Yep the sketch shows it's correct. Just be very sure with those pesky 4-pin buttons that you have them the right way round. Check with your ohm-meter to see which pins are always connected to each other and which are switched.

I will, I slightly hope it's a stupid issue such as that so I can work with my current setting.

For quick reiteration/clarification though, its preferable in the case of Arduino because it limits the number of external connections and the potential for an accidental short of the source to ground? Just making sure I don't assume this for everything electronics where internal connections might not be as available as they are with the Arduino.

I think it's a general guideline that pullups (active low) is better, not just an Arduino thing.

(edit... I just Googled to see which is better and got a whole lot of advice about exercising.....)

Bahahaha, well good to know you stay in shape by reading about circuits. Yes I remember that being the case in class, I just wish I remembered why. I think it has something to do with powering transistors more efficiently or what not… Regardless I appreciate all the help man, if I have further trouble I’ll post in a day or two, but hopefully all is well!

Cheers!

No, it has to do with safety, not having 5V (or any other) supply lines wandering around anywhere you can avoid in case they are shorted to ground, and because you generally use ground lines for shielding against noise.

However, I can assure you your problems are not due to noise pickup as long as you are using pull-ups (or in fact, even pull-downs), but most likely to contact bounce. I do not trust debounce code in Arduino examples (as I am sure JimboZA will agree), which is why I gave you a "bullet-proof" example to work from.

If you wish to get serious, you will need to post your code.

If you want/need to debounce, there's a library here in the Playground: very easy to implement, all the trickiness is hidden in the library.

Hey guys, I updated my debounce code like you suggested (I used bounce2 from the Arduino playground) and I am still getting the same issues. This leads me to believe that the problem with my controller is still issues with noise. To be more specific when a button is pressed on my system it is supposed to output the number 2 followed by the number of the beat pin (0-7). For some reason I find that pressing 0-2 does nothing while pressing 3-7 will often spit out messages for the lot (eg if I press beat pin 3 it will output “2 x” for all x values between 3-7). I have checked over my circuit many times and I am sure it is connected correctly. I think that maybe I should switch the internal pull up resistor and inverse my logic. Any final thoughts before I proceed?

Here is my code…

receiverCode2.ino (7.05 KB)

I guess anything that eliminates a possible cause is good, and as said before, active low is best practice.

BUT are you 100% sure you have those square buttons oriented properly? See the bottom right of the attached pic to see how the innards work.

switch schematic.jpg

So for anyone wondering with the same issue, I switched my logic to PUP and it completely removed all issues of noise! My controller seems to be operating fine except for the fact that my code doesn't seem to recognized if a few of my later buttons are pressed. Now I am wondering is it possible that these burned out due to the last configuration or did the lines in the breadboard potentially burn out? This is my new issue haha.

And yeah JimboZ they are defintely oriented correctly as I get a good response from pressing my first two buttons. This post helped me a lot too http://blog.kennyrasschaert.be/blog/2014/04/01/digital-input-on-an-arduino-using-a-push-button/ . Now I just have issues with no response from the other buttons due to a potential burnout (?).