Debounce/Serial/Latency Nightmare.

First, I want to thank you for reading this post. I understand that it is a simple/common problem with a lot of literature on it, and I don’t take your time lightly. Thank you. I have screamed over this (but just once.)

The Goal:

I am trying to write a low-latency, de-bounced button routine in Arduino. I want to write to the serial port, so that a second Processing program can read that serial information and trigger various sounds in real time, accordingly.

What I’ve tried:

I’ve tried a NUMBER of debouncing variations, including, but not limited to, the solutions here:

(I have to de-URL these, as this is my first post, and the bb won’t let me)

playground/Code/Debounce
playground/Learning/SoftwareDebounce
playground/Code/Buttons
and in the book “Getting Started witH Arduino”

It seems no matter what I do, I end up with two problems

a. Latency in the Serial.printing (regardless of de-bounce, actually)
b. Unresponsiveness of the button.

Latency goes away, IF I take away all debouncing, and just read the status of the pin, and then Serial.print…

My system: OS 10.5.6, Duemilanove, Arduino 015.

Any help would be greatly appreciated.

Here is the code to my current “solution”, which is a solution the same way that golf is a sport. Which is to say, kinda, but not really.

(No offense to Golfers, I understand that it is very difficult.)

#define LED 13
#define BUTTON 7 
#define BOUNCE_PERIOD 150

long last_read_time;
long last_value;


int val = 0;

void setup()
{ 
  Serial.begin(115200);
  pinMode(LED,OUTPUT);
  pinMode(BUTTON,INPUT);
}

void loop()
{
  
  // If we are past our bounce period
  if (millis() - last_read_time > BOUNCE_PERIOD){
   
   // Check the button 
   val = digitalRead(BUTTON);
   // If the button has changed since last bounce period

   if (val != last_value){
     digitalWrite(LED,val);
     if (val == HIGH) Serial.print("7");
     last_read_time = millis();
     last_value = val;
   }
   
}
}

You current solution seems to be correct. Obviously it can't do anything with the button press until the debounce time has passed (it looks like 150mS in this case). You could probably set that value down some to make it more responsive. I would guess that you can get down to around 10mS and still be pretty clean.

Here is a great article on switch debouncing: www.ganssle.com/debouncing.pdf

The next option would be hardware filtering on the button with a cap and resistor.

You mention that you need low latency. How low?

Jes,

Thanks for responding.

I don't know, I mean, it doesn't have to be amazingly low. Just without a humanly-noticeable delay, if that's possible.

The problem is that when monitoring the Serial window, or just in a dummy processing app, even with this code there is a visible delay (200ms? 400? not a full second) between when I hit the button and the Serial.println, even though the light flashes instantaneously.

There's no way it can take THAT long to send a character through a USB port, is there? Just one character? Not at 115200 bits per second, right?

And, even with this code, I still sometimes get repeats... :(

I will read the Ganssle doc. I am new to both Arduino, and Hardware, and Processing, to be perfectly honest.

I read the Ganssle, and tweaked the latency and it's counting properly. It's still slow on the Serial.print, for whatever reasons, but I guess I can deal with that...

Now, am I going to have a problem trying to do this with 4 buttons? 16? My plan is to just make loops for all 16 button vals, is there a better way to do it? Ganssle discusses it but it's a bit programatically difficult for me to follow.

You can send to the serial port immediately after detecting the button state change. The debounce just has to keep you from going back and forth too much.

Some of the latency you're seeing may be on the host side. The Serial Monitor is hardly optimized for low latency communications; I don't know how good or bad the processing serial driver is.

Thank you westfw. I’ve come to terms with the lag, I guess it’ll have to do. I am confused though because people have made things like midi triggers, which seem to be a LOT more latency-prone, except I guess maybe they aren’t going through processing, perhaps their going straight to something more serially optimized.

If the debouncing is no longer the problem, then i think that the recieving end of the serial connection is causing the problems.

I have been able to read the values of 16 multiplexed potentiometers, convert the values to a commadelimited string of "bytes", send the string (39 chars) out the serial port to a recieving .net program, all in 10ms, and i think it could have run faster, i just didn't try.

Have you tried using a terminal program to just read the data coming from the Arduino to eliminate any other variables?