Miss some button press

Hello, I have 2 problems with button presses (maybe the same that repeats):
Every time I start/reset Arduino, it miss the first key presses then it works wll if I press keys repeatedly (almost never miss a press), but if I don't press the button for even a short amount of time, it miss the first key press again.
I debounced the button with a 0,1uF capacitor, 1KOhm and 10KOhm resistors.

Why this happens and how to resolve this problem?
every help will be appretiated, Luca.

myMIDIcontroller.ino (3.05 KB)

Hello Luca,
Before you do anything else please take a moment to read General guidance and
How to use this forum
Especially item #7 on posting code.

As it is in order to help I or anyone else has to download your code, move it to as suitable folder and open it in the IDE.

Please also post a schematic.

Thank you.

I attached the project .INO file in the first post anyway is here the code:

#define debounce 20 // ms debounce period to prevent flickering when pressing or releasing the button
#define holdTime 1200 // ms hold period: how long to wait for press+hold event
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin

// variables will change:
// Button state variables
bool buttonState; // value read from button
bool buttonLast; // buffered value of the button's previous state
unsigned long btnDnTime; // time the button was pressed down
unsigned long btnUpTime; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered

int counter = 1;
byte ccValue;
void setup() {
	// initialize the pushbutton pin as an input:
	pinMode(buttonPin, INPUT);

	digitalWrite(buttonPin, LOW);
	
	//  Set MIDI baud rate:
	Serial.begin(31250);
	//Serial.begin(115200);
}

void loop() {
	// read the state of the pushbutton value:
	buttonState = !(digitalRead(buttonPin));

	  //Se lo stato del bottone risulta variato, conserva in btnDnTime, quando è stato premuto
	  //con questa formula:
	  //Se il (bottone è LOW e prima era HIGH) e ((ora attuale - quella del rilascio del btn) è maggiore del debounce)
	  if (buttonState == LOW && buttonLast == HIGH && (millis() - btnUpTime) > long(debounce))
	  {
		btnDnTime = millis();;
	  }

	  // Qui 
	  // Se il btn è HIGH e prima era LOW) e ((ora attuale - quella di quando btn è stato premuto) è maggiore del debounce
	  if (buttonState == HIGH && buttonLast == LOW && (millis() - btnDnTime) > long(debounce))
	  {
		buttonLast = buttonState;
		if (ignoreUp == false) ccToggle(0x14);
		else {
		  ignoreUp = false;
		  //REreleased();
		}
		btnUpTime = millis();
	  }

	  // Test for button held down for longer than the hold time
	  if (buttonState == LOW && (millis() - btnDnTime) > long(holdTime))
	  {
		//REhold();
		ignoreUp = true;
		btnDnTime = millis();
	  }
	buttonLast = buttonState;
}


void ccToggle(byte ccNumber){
	if (ccValue == 0) {
		ccValue = 127;
	} else {
		ccValue=0;
	}
	Serial.write(0xB0);
	Serial.write(ccNumber);
	Serial.write(ccValue);
	//serial.write("cc changed ");
	//serial.write(counter);
	//counter++;
	//serial.write(" times.\n");
}

//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void noteOnOff(byte pitch, byte velocity){
	// check if the pushbutton is pressed.
	// if it is, the buttonState is HIGH:
	if (buttonState == HIGH && buttonLast == LOW){
		noteOnOff(0x30,0x64);//0x41Hex = 144Dec = 10010000 in binary, note on command
		buttonLast = HIGH;
	}
	if (buttonState == LOW && buttonLast == HIGH){
		noteOff(0x30,0x00);			//		?da sostituire con noteOff?
		buttonLast = LOW;
	}
}

void noteOn(byte pitch, byte velocity) {
	Serial.write(0x90);
	Serial.write(pitch);
	Serial.write(velocity);
}

void noteOff(byte pitch, byte velocity) {
	Serial.write(128);
	Serial.write(pitch);
	Serial.write(velocity);
}

And the schematic I followed:

Thank you, that's better.

Your input circuit is probably OK, but as you are doing denouncing in software doing it in hardware is not needed.

When it comes to other people's code I am not the best at suggesting improvements so I hope someone better than me will suggest something to help you.

your schematic shows a pullup resistor. Your code shows you are using input-pullup as well. Why?

Paul

your schematic shows a pullup resistor. Your code shows you are using input-pullup as well. Why?
Paul

I see this which does not enable the internal resistor

pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, LOW);

Why do you use inverse logic here?

buttonState = !(digitalRead(buttonPin));

It certainly does not fit the comment with this line

// Test for button held down for longer than the hold time
	  if (buttonState == LOW && (millis() - btnDnTime) > long(holdTime))

Because i used a pulldown circuit before, so the software was written for pulldown logic, then I tried to change it to a pullup to see if I can solve the problem this way, but obviously it hasn't.
I prefer hardware debouncing rather than software because I'm creating a MIDI pedalboard and I'd like to have the quickest responsiveness possible. I'm going to add an inverter IC when the shipment will arrive...

cattledog:
I see this which does not enable the internal resistor

pinMode(buttonPin, INPUT);

digitalWrite(buttonPin, LOW);




Why do you use inverse logic here?


buttonState = !(digitalRead(buttonPin));




It certainly does not fit the comment with this line


// Test for button held down for longer than the hold time
  if (buttonState == LOW && (millis() - btnDnTime) > long(holdTime))

Someone is changing their program code after they post it on the forum.

Paul

I prefer hardware debouncing

OK. Then take out all the software debouncing from your code, and write for the correct logic with a pullup.

Post that revision.

Or make it easy by using library. See this post For beginners: The simple way to program for multiple buttons [code example] - Introductory Tutorials - Arduino Forum

Tronky:
I prefer hardware debouncing rather than software because I'm creating a MIDI pedalboard and I'd like to have the quickest responsiveness possible.

A properly implemented debounce routine has virtually zero latency (delay between the very first switch actuation and registration of a keystroke. A debounce interval follows that, but it happens transparently as far as the registration or action performed in response to it.

In fact, hardware and software debouncing both have the same logical basis, so there is no inherent performance advantage to either, concerning responsiveness. Depending on the hardware circuit, the hardware method may be slower if it uses a low pass filter, because that filter (unless it is designed otherwise) has the same time constant for actuation and release. On the other hand, software debouncing can be made quite reliable without any filtering or time constant. Hence, as I said, it can respond safely in a microsecond time scale.

In your circuit, the release time is approximately 10 times the actuation time, but it won't be as fast as a simple software debounce. If it is, it is not written wisely.

If you just think hardware debouncing is "cool", okay. Just don't make up reasons that are not correct.

What aarg said, plus, with software debouncing you can change the timing with a few keystrokes, with hardware debouncing you have to change physical components.

I've removed hardware debounce and rewritten the software from scratch: now it works very well. :smiley:
Thanks to all of you people, Luca.

Now it works very well.

:slight_smile:

Thanks to all of you people

You're welcome!