problem with button to react as switch

Hi!
As sort of a noob I’d like to so say hello to the whole community. :slight_smile:
My project what I’m working on has to do with MIDI. This is all working great so far but I’ve got some problems with the easy suff, here it is:

I’ve got 3 buttons which are supposed to work like switches. To keep it simple I started to do it with just one button which should switch on a LED and switch it off again when pressed a second time. So here is what I programmed so far for just the button/LED stuff:

/********************************************************************************

FOR:       Arduino Atmega328
CLOCK:  16.00 MHz Crystal

********************************************************************************/

byte LedPin = 8;   // select the pin for the status LED
byte SwitchState=HIGH;                                         // HIGH = switch is not pushed
byte currentSwitch[3]={0,0,0};
byte switches[3]={12,13,14};                                                          // button input pins
byte x,i,n,val,t;
int LFOLed = 9;                                                              // LED pins
int delta_bounce = 0;                                                                      // difference between debounce_time_now and debounce_time_past
unsigned long debounce_time_now;
unsigned long debounce_time_past=0;
byte LedStatus=0;                                                             // 0 = LED is off
byte ReleaseState=1;                                                        // 1 = switch was released


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void setup() {                                       // void setup unchanged to higher MIDI project, so a lot of additional stuff left in here
  
  pinMode(2, OUTPUT);     
  pinMode(3, OUTPUT);  
  digitalWrite(3, LOW);                                  // GND 0 Volt supply to opto-coupler
  digitalWrite(2, HIGH);                                  // +5 Volt supply to opto-coupler
  
  for (i = 4; i <=7; i++){pinMode(i, INPUT);}    // include midi DIP switch
  for (i = 4; i <=7; i++){digitalWrite(i, HIGH);} // turn on internal pullups
  
  for (i = 12; i <=14; i++){pinMode(i, INPUT);}                                // these are my buttons
  for (i = 12; i <=14; i++){digitalWrite(i, HIGH);}// turn on internal pullups

  for (i = 9; i <=11; i++){pinMode(i, OUTPUT);}                              // these are the LFO LEDs

  pinMode(LedPin, OUTPUT);

  for (x=1; x<=4; x++){                              // blinking four times to see device is booting
    digitalWrite( LedPin, HIGH );
    delay(300);
    digitalWrite( LedPin, LOW );
    delay(300);
  }
  
  Serial.begin(31250);                                   // set Standard MIDI baud rate
  
  Serial.flush();

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


void loop() {

 
  //~~~~~~~~~~~~~~~ scan switches on inputs 12,13,14=A0 NOTE: switches toggle HIGH to Ground (=LOW)
  
    debounce_time_now = millis();                                                                    // debounce switches
    delta_bounce = debounce_time_now - debounce_time_past;                                           // debounce switches
    debounce_time_past = debounce_time_now;                                                          // debounce switches
  if (delta_bounce >= 50) {                                                                          // debounce switches
           SwitchState = digitalRead (switches[0]);
           if (SwitchState == LOW && LedStatus == 0 && ReleaseState == 1) {        // button just gets pushed, LED is off
                 digitalWrite (LFOLed, HIGH);
                 LedStatus = 1;
                 ReleaseState = 0;
             }
 
           if (SwitchState == LOW && LedStatus == 1 && ReleaseState == 1) {    // button just gets pushed, LED is on
               digitalWrite (LFOLed, LOW);
               LedStatus = 0;
               ReleaseState = 0;}
  
           if (SwitchState == HIGH) {ReleaseState = 1;}                            // button ist not pushed and is so declared as released
      
  }  
} // bracket of void loop

I tried to keep everything in English, when there is something in German, I’m sorry…

The LED is connected with a resistor to pin 9, as the button is connected to ground at pin 12.
I’m lost 'cause it just doesn’t work. The hardware is fine, I selected the correct pins.

I did some research like “arduino button as switch” and found some examples which are ok. But I’d really like to figure out what I’m doing wrong.

So when there is somebody feeling like helping me understanding all this I would appreciate it.

Regards, Joe

I am not an expert but i think your delta_bounce timer can never make it past a few microseconds.

debounce_time_now = millis();                                          
delta_bounce = debounce_time_now - debounce_time_past;    
debounce_time_past = debounce_time_now;                            

     if (delta_bounce >= 50) {

this code is in your loop and runs every time through. So every time your code comes around you are setting delta_bounce to the amount of time it took to run 1 set of loop code. (very small amount of time, will never make it to 50 milliseconds)

you might need something more like:

int delta_bounce = 50;

debounce_time_now = millis();    
     if (debounce_time_now - debounce_time_past >= delta_bounce) {
          
          // Do some cool flashy light type stuff

          debounce_time_past = debounce_time_now;
     }

notice that the resetting of the past time doesn't happen until the threshold of 50 has been satisfied already.. this way it wont reset every single loop.

btw, just as added information. If a value will only ever be 1 or 0, bool would be a good choice for variable type (button state, led state)

and if you want to set the delta_bounce to a variable that cant change, int is fine. If you will calculate the delta_bounce from millis() a long might be a better choice since an int could only handle a time span of 32 seconds before you might get some strange results.

Goofballtech:
I am not an expert but i think your delta_bounce timer can never make it past a few microseconds.

debounce_time_now = millis();                                          

delta_bounce = debounce_time_now - debounce_time_past;   
debounce_time_past = debounce_time_now;

if (delta_bounce >= 50) {




this code is in your loop and runs every time through. So every time your code comes around you are setting delta_bounce to the amount of time it took to run 1 set of loop code. (very small amount of time, will never make it to 50 milliseconds)

you might need something more like:



int delta_bounce = 50;

debounce_time_now = millis();   
    if (debounce_time_now - debounce_time_past >= delta_bounce) {
         
          // Do some cool flashy light type stuff

debounce_time_past = debounce_time_now;
    }




notice that the resetting of the past time doesn't happen until the threshold of 50 has been satisfied already.. this way it wont reset every single loop. 

btw, just as added information. If a value will only ever be 1 or 0, bool would be a good choice for variable type (button state, led state)

and if you want to set the delta_bounce to a variable that cant change, int is fine. If you will calculate the delta_bounce from millis() a long might be a better choice since an int could only handle a time span of 32 seconds before you might get some strange results.

agree

:fearful: oops
Somehow I expected this to be so obvious but I couldn't see it anyway. Well, I'll gonna try this tonight and report how it works...
Thanks a lot!
By the way, I chose long for debounce_time_now and *_past and just the differnce between those two is an integer. Shouldn't that be fine since the difference is just going to be something smaller than 32,767?

Joe

the difference between those two will be smaller than 32767 up to a different of 32.767 seconds.

This is why i said after 32 seconds you might get some strange behavior.
If you press the button to toggle your led at 33.1 seconds of different between your timers, what number will be stored in delta_bounce?

As expected - now it's working.

Just as soon as I put in my arrays to cope with my three buttons, I get somehow some "debounce issues". But since it's still unreliable when I put my debounce time up to 300 ms it's unlikely to be a real debounce problem... but I have to think about that tomorrow or so. (it's past 12pm here :sleeping:)

Thanks for clarify the topic with int and long - still expected the time difference to be reset each time the loop runs through. My bad.

Cheers, and thanks again,
Joe