Полку кнопок прибыло.
При работе нед одним проектом столкнулся с необходимостью уменьшать/увеличивать технологическую переменную на один шаг при нажатии кнопки.
Если использовать обычную кнопку, то часто возникает ситуация неконтролируемого многократного уменьшения/увеличения параметра, пока кнопка нажата. Поэтому приходится придумывать разные блокировки таких процессов. Однако оказалось проще "сделать" кнопку, которая бы при достижении условий срабатывания выдавала однократно "Нажата" в текущем лупе.
Следующее срабатывание такой кнопки возможно только после ее отпускания и последующего нажатия с выполнением условий срабатывания.
Код: Выделить всё
// Однолуповая кнопка
// Не забудьте включить монитор порта для контроля работы скетча
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
#define BUTT 5 // tested Button
#define BEEP 13 // звуковой выход
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
class Button
{
public:
void Set( byte pin, boolean defaultButt, boolean pullup, // метод начальной установки
int retention ) ;
void mScan() ; // опроса состояния моноимпульсной кнопки
boolean pressed = false ; // кнопка длительно/хорошо нажата
private:
byte _digitPin ; // номер опрашиваемого цифрового пина
boolean _defaultButt ; // исходное состояние кнопки/пина
boolean _pullup ; // "подтяжка" ( или нет )
int _retention ; // время непрерывного удержания кнопки [ мсек ]
} ;
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
Button keyTest ; // объявление кнопки keyTest
unsigned int i = 0 ; // вспомогательня демо-переменная
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
void setup() { // put your setup code here, to run once:
Serial.begin(9600) ;
keyTest.Set ( BUTT, true, true, 200 ) ; // нажатие кнопки 200 мсек
pinMode( BEEP, OUTPUT ) ; // включение биппера/зуммера
}
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
void loop() { // put your main code here, to run repeatedly:
keyTest.mScan () ;
if (keyTest.pressed) {
i = i + 1 ;
tone ( BEEP, 880, 100 ) ;
Serial.println ( "Button pressed " + String ( i ) ) ;
}
delay( 1 ) ;
}
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
/*
Методы обработки нажатия кнопки и очистки от дребезга
путем многократного непрерывного в течение заданного интервала времени
опроса состояния
*/
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
void Button:: Set( byte pin, boolean defaultButt, // установка параметров кнопки
boolean pullup, int retention ) {
_digitPin = pin ; // присвоение номера PIN
_defaultButt = defaultButt ; // исходное состояние разомкнуто
_pullup = pullup ; // подтяжка к ПЛЮС
_retention = retention ; // время удержания [ мсек ]
if (_pullup) {
pinMode(_digitPin, INPUT_PULLUP) ;
} else {
pinMode(_digitPin, INPUT) ;
}
}
/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+*/
void Button:: mScan ( ) { // моноимпульсная кнопка
static boolean _lock ; // параметр "захвата" срабатывания кнопки
static unsigned long timeClick ; // момент нажатия кнопки [мсек]
if ( digitalRead( _digitPin) == _defaultButt ) { // кнопка в исходном состоянии ОТЖАТО
timeClick = millis() ; // непрерывно запоминаем время вызова
pressed = false ; // кнопка не нажата
_lock = false ; // "захват" сброшен
} else { // НАЖАТО
if ( millis() - timeClick > _retention ) { // время прошло -
if ( !_lock ) { // проверяем "захват"
_lock = true ; // фиксируем событие захвата
pressed = true ; // возвращаем состояние ВКЛ
} else // в следующем цикле
pressed = false ; // сбрасываем состояние ВКЛ
}
}
}
PS. Может, кто подскажет что нужно сделать, чтобы упростить луп и улучшить читаемость скетча объединив чтение PIN и получение состояния кнопки?
Код: Выделить всё
...
keyTest.mScan () ;
if ( keyTest.pressed == true ) {
...
на, предположим, ЭТО
Код: Выделить всё
...
if ( keyTest () == true ) {
...
Благодарности моей не будет предела в рамках моих скромных возможностей