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.
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);
}
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...
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.