All I see is that your button reading solution checks the status of the button at 50 ms intervals. That is not really debouncing.
This example I use from time to time. It requires that any change of state is stable for a defined number on milliseconds before accepting it and so is quite suited for noisy environments.
bool getKey() {
// get debounced key press
static bool currentKeyState = HIGH ;
static bool newKeyState = HIGH ;
static uint32_t newKeyStateAtMs = millis() ;
bool dr = digitalRead(inputPin) ;
if ( dr != newKeyState ) {
newKeyState = dr ;
newKeyStateAtMs = millis() ;
}
if ( currentKeyState != newKeyState && millis() - newKeyStateAtMs > 50) { // configure this as required.
// debounce: accept only a mature change ( > X ms )
currentKeyState = newKeyState ;
}
return currentKeyState ;
}