|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings |
|
|
uint8_t samples[SAMPLE_COUNT]; //bitwise, one bit per key, most recent readings |
|
|
uint8_t samplesIndex = 0; //samples[] current write index |
|
|
uint8_t samplesIndex = 0; //samples[] current write index |
|
|
uint8_t debounced = 0; //bitwise, one bit per key |
|
|
|
|
|
|
|
|
uint8_t previousDebounced = 0; //bitwise, one bit per key |
|
|
|
|
|
|
|
|
uint8_t debounce(const uint8_t rowState) |
|
|
|
|
|
|
|
|
uint8_t isFallingEdge; //1 means falling edge |
|
|
|
|
|
uint8_t isRisingEdge; //1 means rising edge |
|
|
|
|
|
|
|
|
|
|
|
uint8_t debounce(const uint8_t rowState, uint8_t& debounced) |
|
|
{ |
|
|
{ |
|
|
|
|
|
uint8_t debouncedChanged; //bitwise |
|
|
uint8_t all_1 = ~0; //bitwise |
|
|
uint8_t all_1 = ~0; //bitwise |
|
|
uint8_t all_0 = 0; //bitwise |
|
|
uint8_t all_0 = 0; //bitwise |
|
|
|
|
|
|
|
|
//delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce key |
|
|
|
|
|
|
|
|
//delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce key |
|
|
|
|
|
|
|
|
samples[samplesIndex] = rowState; //insert rowState into samples[] ring buffer |
|
|
samples[samplesIndex] = rowState; //insert rowState into samples[] ring buffer |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// update newDebounce if all the samples agree with one another |
|
|
// update newDebounce if all the samples agree with one another |
|
|
// if all samples=1 then newDebounced=1 |
|
|
|
|
|
// elseif all samples=0 then newDebounced=0 |
|
|
|
|
|
// else newDebounced=debounced i.e. no change |
|
|
|
|
|
//return all_1 | (all_0 & debounced); |
|
|
|
|
|
debounced = all_1 | (all_0 & debounced); |
|
|
|
|
|
return debounced; |
|
|
|
|
|
|
|
|
// if all samples=1 then debounced=1 |
|
|
|
|
|
// elseif all samples=0 then debounced=0 |
|
|
|
|
|
// else debounced=previousDebounced i.e. no change |
|
|
|
|
|
debounced = all_1 | (all_0 & previousDebounced); |
|
|
|
|
|
|
|
|
|
|
|
debouncedChanged = debounced xor previousDebounced; |
|
|
|
|
|
previousDebounced = debounced; |
|
|
|
|
|
return debouncedChanged; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void pressRelease(const uint8_t debouncedChanged) |
|
|
|
|
|
{ |
|
|
|
|
|
//bit=1 if last debounced changed from 1 to 0, else bit=0 |
|
|
|
|
|
isFallingEdge = debouncedChanged & ~previousDebounced; |
|
|
|
|
|
|
|
|
|
|
|
//bit=1 if last debounced changed from 0 to 1, else bit=0 |
|
|
|
|
|
isRisingEdge = debouncedChanged & previousDebounced; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int main() |
|
|
int main() |
|
|
{ |
|
|
{ |
|
|
//Test input and output only shows first bit of each byte. |
|
|
//Test input and output only shows first bit of each byte. |
|
|
const uint8_t pressed[] = {1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0}; |
|
|
|
|
|
const uint8_t bouncy[] = {1,0,0,0,0,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0}; |
|
|
|
|
|
|
|
|
const uint8_t pressed[] = {1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0}; |
|
|
|
|
|
const uint8_t bouncy[] = {1,0,0,0,0,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0}; |
|
|
|
|
|
const uint8_t expectDebounced[]= {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0}; |
|
|
const uint8_t SCAN_COUNT = sizeof(bouncy)/sizeof(*bouncy); |
|
|
const uint8_t SCAN_COUNT = sizeof(bouncy)/sizeof(*bouncy); |
|
|
uint8_t i; |
|
|
uint8_t i; |
|
|
uint8_t newDebounced; |
|
|
|
|
|
|
|
|
uint8_t debounced; //1 means pressed, 0 means released |
|
|
|
|
|
uint8_t debouncedChanged; //1 means debounced changed |
|
|
|
|
|
|
|
|
std::cout << "button pressed: "; |
|
|
|
|
|
|
|
|
std::cout << "button pressed: "; |
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
{ |
|
|
{ |
|
|
std::cout << (int)pressed[i]; |
|
|
std::cout << (int)pressed[i]; |
|
|
} |
|
|
} |
|
|
std::cout << std::endl; |
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
std::cout << "bouncy signal: "; |
|
|
|
|
|
|
|
|
std::cout << "bouncy signal: "; |
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
{ |
|
|
{ |
|
|
std::cout << (int)bouncy[i]; |
|
|
std::cout << (int)bouncy[i]; |
|
|
} |
|
|
} |
|
|
std::cout << std::endl; |
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
std::cout << "debounced signal: "; |
|
|
|
|
|
|
|
|
std::cout << "debounced signal: "; |
|
|
|
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
debouncedChanged = debounce(bouncy[i], debounced); |
|
|
|
|
|
//pressRelease(debouncedChanged); |
|
|
|
|
|
std::cout << (int)debounced; |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
|
|
|
std::cout << "expected debounced signal: "; |
|
|
|
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
std::cout << (int)expectDebounced[i]; |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "isFallingEdge: "; |
|
|
|
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
debouncedChanged = debounce(bouncy[i], debounced); |
|
|
|
|
|
pressRelease(debouncedChanged); |
|
|
|
|
|
std::cout << (int)isFallingEdge; |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
|
|
|
std::cout << "isRisingEdge: "; |
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
for (i=0; i<SCAN_COUNT; i++) |
|
|
{ |
|
|
{ |
|
|
newDebounced = debounce(bouncy[i]); |
|
|
|
|
|
std::cout << (int)newDebounced; |
|
|
|
|
|
|
|
|
debouncedChanged = debounce(bouncy[i], debounced); |
|
|
|
|
|
pressRelease(debouncedChanged); |
|
|
|
|
|
std::cout << (int)isRisingEdge; |
|
|
} |
|
|
} |
|
|
std::cout << std::endl; |
|
|
std::cout << std::endl; |
|
|
} |
|
|
} |