Modified version to work with EventQueue (outside of ISR)
Diff: MultiClick.cpp
- Revision:
- 5:cb4d45f41e17
- Parent:
- 4:8d6883cdc3c8
- Child:
- 6:7f1142cc196a
--- a/MultiClick.cpp Wed Jun 15 05:17:19 2016 +0000 +++ b/MultiClick.cpp Wed Jun 15 08:55:09 2016 +0000 @@ -10,155 +10,113 @@ if(_mode == PullUp) { DBG_PRINT("isr fall.\r\n"); _iin->fall(this, &MultiClick::isr_pressed); - _iin->rise(this, &MultiClick::isr_released); } else { DBG_PRINT("isr rise.\r\n"); - _iin->fall(this, &MultiClick::isr_released); _iin->rise(this, &MultiClick::isr_pressed); } - _timeout = new Timeout(); - _debounce_timeout = new Timeout(); - _longpress_timeout = new Timeout(); + _click_detect_timeout = new Timeout(); + _press_check = new Ticker(); _t = new Timer(); _t->start(); + _press_check_interval_us = 25*1000; + _shortpress_num = 1; + _longpress_num = 20; _click_interval_us = 300*1000; - _debounce_ignore_us = 100*1000; - _longpress_us = 1000*1000; - _debounce_ignore = false; + _pressed_count = 0; _longpressed = false; } void MultiClick::isr_pressed( void ) { -#if 0 - // チャタリングチェック1 - if(_pressed == true) { - DBG_PRINT("isr_pressed: illigal press, ignore."); - fflush(stdout); - return; - } else { - _pressed = true; - } -#endif + DBG_PRINT("isr_pressed called:\r\n"); + fflush(stdout); - // --- 長押し検出用タイマーを停止 - _longpress_timeout->detach(); + if(_pressed_count > 0) { // 「プレス中のプレス」 + DBG_PRINT("_"); + press_check_func(); + } else { // 通常時 + + // プレス判定処理開始 + _pressed_count = 0; + _press_check->detach(); + _press_check->attach_us(this, &MultiClick::press_check_func, _press_check_interval_us ); + _longpressed = false; - - // --- チャタリング(debounce)チェック2 ------------------------------------------------ - if(_debounce_ignore == true) { - DBG_PRINT("isr_pressed: bounce. "); - fflush(stdout); - } else { - DBG_PRINT("isr_pressed called:\r\n"); - fflush(stdout); - - // 長押し検出用タイマー開始 - _longpress_timeout->attach_us(this, &MultiClick::longpress_timeout, _longpress_us ); + } - } -void MultiClick::isr_released( void ) +void MultiClick::press_check_func( void ) { -#if 0 - if( _pressed == false) { - DBG_PRINT("isr_released: illigal release, ignore."); - fflush(stdout); - return; - } else { - _pressed = false; - } -#endif + int curr_state; + curr_state = _iin->read(); - // 長押し検出用タイマーを停止 - _longpress_timeout->detach(); - - // --- チャタリング(debounce)チェック ------------------------------------------------ - if(_debounce_ignore == true) { - DBG_PRINT("isr_released: bounce. "); - fflush(stdout); + if(curr_state == 0) { // 押されている場合 + DBG_PRINT("."); + _pressed_count++; + // 長押しチェック + if(_pressed_count > _longpress_num) { + if(_longpressed != true) { + if(_c_callback_longpressed != 0) { + (*_c_callback_longpressed)(); + } + _longpressed = true; + } + } + } else { // 押されていない場合 + DBG_PRINT("# _pressed_count=%d\r\n", _pressed_count); - return; - } else if(_longpressed == true) { // 長押しチェック - DBG_PRINT("isr_released: _longpressed. "); - fflush(stdout); + if(_pressed_count >= _shortpress_num) { + _click_times++; + } + DBG_PRINT("# _click_times=%d\r\n", _click_times); + + _press_check->detach(); // プレスチェックを停止 - _longpressed = false; - - return; - } else { - DBG_PRINT("isr_released called:\r\n"); - fflush(stdout); - } + _click_detect_timeout->detach(); // マルチクリック検出用タイマーを設定 + _click_detect_timeout->attach_us(this, &MultiClick::click_detect_timeout, _click_interval_us ); + + } - // クリック認定 - _click_times++; - - // チャタリングチェック期間を開始する設定(初回、押し下げ後一定時間は、押し下げを無視) - _debounce_ignore = true; - _debounce_timeout->detach(); - _debounce_timeout->attach_us(this, &MultiClick::debounce_timeout, _debounce_ignore_us ); - - // マルチクリック検出用タイマーを設定 - _timeout->detach(); - _timeout->attach_us(this, &MultiClick::click_timeout, _click_interval_us ); - - } -void MultiClick::debounce_timeout( void ) +void MultiClick::click_detect_timeout( void ) { - DBG_PRINT("--- debounce T.O.\r\n"); - _debounce_ignore = false; -} - -void MultiClick::click_timeout( void ) -{ - DBG_PRINT("===== multiclick T.O.\r\n\r\n"); + DBG_PRINT("-> click_detect T.O.\r\n"); - // クリックイベントを通知 - switch( _click_times ) { - case 0: - DBG_PRINT("error!"); - break; + if(_longpressed) { // 長押し時は何もしない + DBG_PRINT("-> skip n click C.B. \r\n"); + } else { // クリックイベントを通知 + switch( _click_times ) { + case 0: + DBG_PRINT("error!"); + break; + + case 1: + if(_c_callback_clicked != 0) { + (*_c_callback_clicked)(); + } + break; - case 1: - if(_c_callback_clicked != 0) { - (*_c_callback_clicked)(); - } - break; - - case 2: - if(_c_callback_doubleclicked != 0) { - (*_c_callback_doubleclicked)(); - } - break; - default: - if(_c_callback_n_clicked != 0) { - (*_c_callback_n_clicked)(_click_times); + case 2: + if(_c_callback_doubleclicked != 0) { + (*_c_callback_doubleclicked)(); + } + break; + default: + if(_c_callback_n_clicked != 0) { + (*_c_callback_n_clicked)(_click_times); + } } } - - _click_times = 0; + + _click_times = 0; + _pressed_count = 0; } -void MultiClick::longpress_timeout( void ) -{ - DBG_PRINT("===== longpress T.O.\r\n\r\n"); - - if(_c_callback_longpressed != 0) { - (*_c_callback_longpressed)(); - } - - _click_times = 0; - _longpressed = true; -} - - void MultiClick::attach_clicked(void (*function)(void) = 0) { _c_callback_clicked = function; } void MultiClick::attach_doubleclicked(void (*function)(void) = 0) { _c_callback_doubleclicked = function; }