Problem with virtual double-press.

I’m using the Arduino as an intelligent switch or sorts. The hardware side is a couple of momentary switches as input, and an NPN transistor as the output switch.

It’s connected to the switching circuit of a guitar pedal, so with a single button press on the Arduino, I can produce a “double press” on the pedal.

I’m having a hard time getting the code working. I massaged some DELAY values around as it looks like the pedal has a minimum value before it will read a press.

Also notable is that the press and release timing is important in the functionality of this code. (It sets the start/stop/duration of an audio loop)

Here is the code:

#include <Button.h>                       

Button button1 = Button(8,PULLDOWN);   
Button button2 = Button(9,PULLDOWN);  
#define SWITCH  12        // transistor switch

void setup(){
pinMode(SWITCH, OUTPUT);        // transistor switch
}

void loop(){
  button1.isPressed();
  button2.isPressed();
  if (button1.stateChanged()){
    if (button1.wasPressed()){
    digitalWrite(SWITCH, HIGH);
  } else {
    digitalWrite(SWITCH, LOW);
    }
  }
  if (button2.stateChanged()){
    if (button2.wasPressed()){
    digitalWrite(SWITCH, HIGH);
    delay(2);
    digitalWrite(SWITCH, LOW);
    delay(5);
    digitalWrite(SWITCH, HIGH);
  } else {
    delay(2);
    digitalWrite(SWITCH, LOW);
  }
  }
}

Button1 is working more or less fine. I get false reads and bounces, but the switch I’m using for that ones input is pretty old (when I use a different switch it’s more consistent).

Button2, however, is giving me no joy. Now as mentioned, press and release timings are important. What I’m trying to do with the code is when I first press Button2, it sends a press/release, as the first “virtual” button press, then sends a second “press”, with it’s subsequent release when I physically release the button. If I do it very slowly (hold the button down for half a second or so each go) it works fine. But anything faster than that (nowhere near 9ms) the logic breaks. I don’t know if I’m getting bouncing still (is the Button library bullet proof for debouncing?), or if the timing/code is wrong, or if there’s an issue with using an NPN transistor to switch things this quickly(5-10ms), but it’s really confusing me.

Any help would be appreciated.

I'm starting to think it might be bouncing related problems, either at the physical input switches, or transistor switch, as I'm having inconsistency problems all around.

Should I incorporate a dedicated debouncing library to the mix?

I tried using "uniquePress" in the logic of that, but it doesn't register.

I looked at the "Bounce" library, but I don't know if I should try that instead of the "Button" library, or in addition to it.

Have you tried a pull down resisitor? That fixes most bounce issues I've run in to.

What do you mean?

My switches are wired through resistors. One pin to 5v, the other pin to ground through a resistor AND an arduino digital pin.

What you want is to ground out the digitalPin side of the circuit with a high ohm resistor. That way when the switch is open it's still grounded and thus you don't get the bounce. Here is a good example:

http://www.ladyada.net/learn/arduino/lesson5.html

So hardware debouncing? In order to supplement the code deboucing or to replace it?

I had seen that guide before, but it covers so much ground I just went with what's in the "getting started with Arduino book".

Do you wire up all switches like that?

I highly recommend using hardware debounce instead of software. Yes I wire all switches that way. It's really pretty simple.

So in looking over things, I believe I'm doing that already.

My wiring is like this:

In looking through that link you posted, I think you're talking about doing this?:

So the only difference is the 100ohm between the digital pin and the switch?

It looks like you already have a pull down resistor. A pull down resistor should be a high ohm resistor on the pin side of your digital switch. It should connect the pin to ground when the switch is open.

Remember electricity will take the path of least resistance. When the switch is closed the 5v goes to the digital pin, and ignores the ground because the resistance is too high (it's easier to go to the digital pin). When the switch is open the digital pin is connected to the ground so you'll get a solid 0 (LOW) when you read it.

You're still getting bounce?

Well, I don't know if it's bouncing, or poor code logic, or a problem with the electronic circuit.

But I'm getting "bounce" like problems.

Pressing the button sometimes does what it's supposed to do, and other times doesn't.

If it was a bounce problem it would still work everytime, it would just "stick" or "bounce"

If it's not reliably tripping it might be something else. Try adding some Serial.print() statements to see what the status of the buttons is after you trip it and it doesn't catch it.

Remember electricity will take the path of least resistance.

Sorry that is just plane wrong, that's not how electricity works.

If there are two paths then more current will flow down the path of least resistance but the same amount of current still flows down the high resistance path as did before the low resistance path was available. In this case current still flows down the 10K resistor when the switch is closed, in fact there is 5 / 10K = 0.5mA of current through the pull down resistor. This is considerably more than actually flows down the digital pin. In this case the digital pin is the highest resistance path.

The pull down resistor should be a lowish value not a high value as you get better noise immunity with the lower values. The extra series 100R resistor will not do much to stop contact bounce but it will do something due to the input capacitance of the arduino pin. To make it more effective also put a capacitor say 1nF from the ardunno pin to ground.

Pressing the button sometimes does what it's supposed to do, and other times doesn't.

That depends on what the rest of the circuit is. Have you posted it and the code.

If it was a bounce problem it would still work everytime,

No bounce problems do show themselves as intermittent.

Here’s the code (might be a bit different from the first post):

#include <Button.h>                        // BUTTON library

// ======= SWITCHES
Button button1 = Button(8,PULLDOWN);       // normal on/off 
Button button2 = Button(9,PULLDOWN);       // restutter button
#define SWITCH  12                         // transistor switch

// ======= LEDS
#define LED 13                             // onboard LED for button press status

void setup(){
  
pinMode(LED,OUTPUT);                       // button press LED status
pinMode(SWITCH, OUTPUT);                   // transistor switch
}


void loop(){
  button1.isPressed();
  button2.isPressed();
  if (button1.stateChanged()){
    if (button1.wasPressed()){
    digitalWrite(SWITCH, HIGH);
  } else {
    digitalWrite(SWITCH, LOW);
    }
  }
  if (button2.stateChanged()){
    if (button2.wasPressed()){
    digitalWrite(SWITCH, HIGH);
    delay(2);
    digitalWrite(SWITCH, LOW);
    delay(5);
    digitalWrite(SWITCH, HIGH);
    delay(2);
  } else {
    digitalWrite(SWITCH, LOW);
  }
  }
}

The switches are wired up like this:

The output switching circuit is an NPN resistor sort of like this:

One pin (Emitter?) is connected to ground. The middle pin (Base?) is going to a digital pin (12) on the Arduino through a 1k resistor. And the other pin (Collector?) is connected to what is being switched.

The actual switching that I’m making a virtual version of connects to ground as it’s connection.

So you're using a transistor (emitter, base, collector are parts of a transisitor) to do the switching. I don't see why that wouldn't work, but maybe someone more knowledgeable than I can chime in. I'm not 100% sure you can use a transisitor to short to ground. You might have to use a relay instead. I'm not sure.

I’m starting to think the problem is on the output side (code and/or transistor).

I setup up some code working just off delays, with no input presses and it’s acting funny.

Like this code:

void loop(){
 digitalWrite(SWITCH, HIGH);
 delay(10);
 digitalWrite(SWITCH, LOW);
 delay(500);
 digitalWrite(SWITCH, HIGH);
 delay(10);
 digitalWrite(SWITCH, LOW);
 delay(200);
 digitalWrite(SWITCH, HIGH);
 delay(10);
 digitalWrite(SWITCH, LOW);
 delay(1000);
 digitalWrite(SWITCH, HIGH);
 delay(10);
 digitalWrite(SWITCH, LOW);
 delay(10);
 digitalWrite(SWITCH, HIGH);
 delay(10);
 digitalWrite(SWITCH, LOW);
  }

Since a HIGH/LOW combination engages the button, it alternates. The first time turns the effect on, and the next time turns the effect off.
What I have there is ON, OFF, ON, OFF, ON.
If I just had ON, OFF, ON, OFF, it didn’t work right (I wouldn’t get two different duration ON cycles, it would just do one ON cycle per go around). I tried adding an extra ON and the first time through the loop it acts weird, then settles into what I wanted; a short ON cycle, then a long ON cycle.

Very confusing/frustrating.