Browse Source

break up Row::detectEdge(), move parts into debounce() and pressRelease()

tags/v0.5.0
wolfv6 8 years ago
parent
commit
1d3af27ebd
3 changed files with 75 additions and 45 deletions
  1. 61
    17
      examples/debounce_unit_test.cpp
  2. 11
    24
      src/RowBase.cpp
  3. 3
    4
      src/RowBase.h

+ 61
- 17
examples/debounce_unit_test.cpp View File



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

+ 11
- 24
src/RowBase.cpp View File

//these variables are all bitwise, one bit per key //these variables are all bitwise, one bit per key
uint8_t rowState; //1 means pressed, 0 means released uint8_t rowState; //1 means pressed, 0 means released
uint16_t rowEnd; //1 bit marks positioned after last key of row uint16_t rowEnd; //1 bit marks positioned after last key of row
uint8_t debounced; //1 means pressed, 0 means released
uint8_t isFallingEdge; //1 means falling edge
uint8_t isRisingEdge; //1 means rising edge
uint8_t debounced; //1 means pressed, 0 means released
uint8_t debouncedChanged; //1 means debounced changed
scan(activeHigh); //save column-port-pin values to portState scan(activeHigh); //save column-port-pin values to portState
rowState = getRowState(rowEnd, activeHigh); rowState = getRowState(rowEnd, activeHigh);
debounced = debounce(rowState);
detectEdge(debounced, isFallingEdge, isRisingEdge);
pressRelease(rowEnd, isFallingEdge, isRisingEdge);
debouncedChanged = debounce(rowState, debounced);
pressRelease(rowEnd, debouncedChanged);
} }
/* /*
} }
/* /*
Computes isFallingEdge and isRisingEdge.
All 3 parameters are bitwise.
pressRelease() calls key's press() or release() function if it was pressed or released.
Both parameters are bitwise.
*/ */
void RowBase::detectEdge(uint8_t debounced, uint8_t& isFallingEdge, uint8_t& isRisingEdge)
void RowBase::pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged)
{ {
uint8_t debouncedChanged; //bitwise
debouncedChanged = debounced xor previousDebounced;
previousDebounced = debounced;
uint8_t isFallingEdge; //1 means falling edge
uint8_t isRisingEdge; //1 means rising edge
uint8_t rowMask; //bitwise, active col bit is 1
uint8_t col; //index for ptrsKeys[col] array
//bit=1 if last debounced changed from 1 to 0, else bit=0 //bit=1 if last debounced changed from 1 to 0, else bit=0
isFallingEdge = debouncedChanged & ~previousDebounced; isFallingEdge = debouncedChanged & ~previousDebounced;
//bit=1 if last debounced changed from 0 to 1, else bit=0 //bit=1 if last debounced changed from 0 to 1, else bit=0
isRisingEdge = debouncedChanged & previousDebounced; isRisingEdge = debouncedChanged & previousDebounced;
}
/*
calls key's press() or release() function if it was pressed or released.
All 3 parameters are bitwise.
*/
void RowBase::pressRelease(const uint16_t rowEnd, const uint8_t isFallingEdge,
const uint8_t isRisingEdge)
{
uint8_t rowMask; //bitwise, active col bit is 1
uint8_t col; //index for ptrsKeys[col] array
for (rowMask=1, col=0; rowMask<rowEnd; rowMask<<=1, col++) //for each key in row for (rowMask=1, col=0; rowMask<rowEnd; rowMask<<=1, col++) //for each key in row
{ {

+ 3
- 4
src/RowBase.h View File

void scan(const bool activeHigh); void scan(const bool activeHigh);
uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh); uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh);
virtual uint8_t debounce(const uint8_t rowState)=0; //debouncer and I2C error correction
void detectEdge(uint8_t debounced, uint8_t& isFallingEdge, uint8_t& isRisingEdge);
void pressRelease(const uint16_t rowEnd,
const uint8_t isFallingEdge, const uint8_t isRisingEdge);
virtual uint8_t debounce(const uint8_t rowState, uint8_t& debounced)=0;
//void detectEdge(uint8_t debounced, uint8_t& isFallingEdge, uint8_t& isRisingEdge);
void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged);
virtual void keyWasPressed(); virtual void keyWasPressed();
protected: protected:
uint8_t previousDebounced; //bitwise, one bit per key uint8_t previousDebounced; //bitwise, one bit per key