This library improves behaviour of push buttons. The automatic repeat is very convenient for e.g. entering time with up/down buttons. The library buffers presses, so no presses are missed.
Dependents: Thermostat_NucleoF401
Diff: RepeatButton.cpp
- Revision:
- 0:8be79829ce90
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RepeatButton.cpp Sun Feb 20 18:47:18 2011 +0000 @@ -0,0 +1,110 @@ +/* mbed RepeatButton Library + * Copyright (c) 2011 Jeroen Hilgers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "mbed.h" +#include "RepeatButton.h" + +KeyBuffer::KeyBuffer(int size) +{ + // One byte cannot be used; if it were + // used, the buffer empty condition + // mReadIndex == mWriteIndex would apply. + // So one byte extra is allocated. + mBuffer = new uint8_t[size+1]; + mSize = size+1; + mReadIndex = 0; + mWriteIndex = 0; +} + +KeyBuffer::~KeyBuffer() +{ + delete mBuffer; +} + +void KeyBuffer::Write(uint8_t value) +{ + int nextIndex = mWriteIndex + 1; + if(nextIndex >= mSize) + nextIndex = 0; + if(nextIndex == mReadIndex) + { + // Buffer full! + return; + } + mBuffer[mWriteIndex] = value; + mWriteIndex = nextIndex; +} + +int KeyBuffer::Read() +{ + if(mReadIndex == mWriteIndex) + { + // Buffer empty! + return -1; + } + int value = mBuffer[mReadIndex]; + int nextIndex = mReadIndex + 1; + if(nextIndex >= mSize) + nextIndex = 0; + mReadIndex = nextIndex; + return value; +} + + +RepeatButton::RepeatButton(PinName pin, int delay_ms, int period_ms, KeyBuffer *buf, char value) : + mIn(pin), + mIrq(pin) +{ + mIn.mode(PullUp); + mValue = value; + mDelay = delay_ms * 1000; + mPeriod = period_ms * 1000; + mIrq.rise(this, &RepeatButton::OnChange); + mIrq.fall(this, &RepeatButton::OnChange); + mTarget = buf; +} + +void RepeatButton::OnChange() +{ + // Any change on input. Wait 5ms to get rid of bounce and get reading afterwards. + mTimeout.attach_us(this, &RepeatButton::OnBounce, 5000); +} + +void RepeatButton::OnBounce() +{ + if(mIn == 0) + { + // Key is still pressed. Generate first press. + mTimeout.attach_us(this, &RepeatButton::OnRepeat, mDelay); + mTarget->Write(mValue); + } +} + +void RepeatButton::OnRepeat() +{ + if(mIn == 0) + { + // Key is still pressed. Generate repeated press. + mTimeout.attach_us(this, &RepeatButton::OnRepeat, mPeriod); + mTarget->Write(mValue); + } +} \ No newline at end of file