долгое нажатие на кнопку, что не так?
- Войдите на сайт для отправки комментариев
Пнд, 08/02/2016 - 22:48
Всем привет! пытаюсь на одну кнопку навесить несколько функций, короткое нажатие и длинное нажатие!Что делаю не так?
// джойстик #define rows 3 #define cols 2 // номера кнопок в соответствии со схемой const byte keys[rows][cols] = { {1,4}, {2,5}, {6,3} }; // состояния направлений енкодера const byte encoderdirection[3][3] = // 0 - на месте, 1 - вниз, 2 - вверх { {0, 1, 2}, // 0 {2, 0, 1}, // 1 {1, 2, 0} // 2 }; // 10 9 8 7 6 5 // строки // красный ч красный // коричневый ч желтый 6 // черный ч черный // столбцы // зеленый б красный // голубой б черный // желтый б желтый // номера пинов const byte rowPins[rows] = {10, 9, 8}; // строки (желтый, зеленый, голубой) const byte colPins[cols] = {7, 5}; // столбцы (черный, красный) #define encoderPin 6 // пин енкодера (коричневый) byte encodervalue; // маски для клавиш #define MaskMediaButton 1 #define MaskRadioButton 2 #define MaskVolumeUpButton 4 #define MaskVolumeDownButton 8 #define MaskOkButton 16 #define MaskMuteButton 32 #define MaskScrollDown 64 #define MaskScrollUp 128 #define MaskLongPress 256 unsigned long starttime; bool workkbd; unsigned long startlongpresstime; bool oldpressed; ///////////////////////////////////////////////////////////////// void setup() { Serial.begin(9600); int i; // строки - на выход for (i = 0; i < rows; ++i) { pinMode(rowPins[i], OUTPUT); } // столбцы - на вход for (i = 0; i < cols; ++i) { pinMode(colPins[i], INPUT); digitalWrite(colPins[i], HIGH); // включаем подтягивающий резистор } // столбец для енкодера pinMode(encoderPin, INPUT); digitalWrite(encoderPin, HIGH); // включаем подтягивающий резистор encodervalue = 0; starttime = millis(); workkbd = false; oldpressed = false; } // сканирование джойстика unsigned int scan(void) { int i, j; unsigned int code = 0; bool pressed = false; for (i = 0; i < rows; ++i) { digitalWrite(rowPins[i], LOW); // кнопки for (j = 0; j < cols; ++j) { if(digitalRead(colPins[j]) == false) { code |= 1 << (keys[i][j] - 1); pressed = true; } } // енкодер if (digitalRead(encoderPin) == false) { int oldencodervalue = encodervalue; encodervalue = i; switch (encoderdirection[oldencodervalue][encodervalue]) { case 1: // вниз code |= 64; break; case 2: // вверх code |= 128; break; } } digitalWrite(rowPins[i], HIGH); } if (code |= 16 & pressed == true) { if (oldpressed == false) { startlongpresstime = millis(); } else { if (millis() - startlongpresstime > 1000) // значение временного промежутка в мс { code |= 256; startlongpresstime = millis(); // сброс счетчика. иначе признак будет выполняться каждый цикл опроса } } } oldpressed = pressed; return code; } // цикл программы void loop() { unsigned int code; code = scan(); if (workkbd == false) { if (millis() - starttime > 3000) workkbd = true; return; } if (code & MaskMediaButton){delay(250); if (code & MaskMediaButton){ Serial.print("Source>"); Serial.println();}} if (code & MaskRadioButton){delay(250); if (code & MaskRadioButton){ Serial.print("Source<"); Serial.println();}} if (code & MaskVolumeUpButton){delay(250); if (code & MaskVolumeUpButton){ Serial.print("VolumeUp"); Serial.println();}} if (code & MaskVolumeDownButton){delay(250); if (code & MaskVolumeDownButton){ Serial.print("volumeDown"); Serial.println();}} if (code & MaskOkButton){delay(250); if (code & MaskOkButton){ Serial.print("TR"); Serial.println(); } } if (code & MaskMuteButton){delay(250); if (code & MaskMuteButton){ Serial.print("Mute"); Serial.println();}} if (code & MaskScrollDown){ Serial.print("RotateDown"); Serial.println();} if (code & MaskScrollUp){ Serial.print("RotateUp"); Serial.println();} if (code & MaskLongPress){ Serial.print("BAND"); Serial.println();} }
Serial выводит несколько TR и только потом одно BAND... задача стоит сделать если коротко то TR, если длинно то BAND, а не tr tr tr tr band Помогите что не так делаю
привет. или сам лови тараканов в своём коде или пользуся готовым.
класс титановый велосипед для тактовой кнопки.
Да нет спасибо, что мне его подгонять под матрицу надо и не известно что из этого получится...
тот же велосипед и получится.
пользуй мой клас и библиотеку для энкодера http://www.pjrc.com/teensy/td_libs_Encoder.html
*нафига там у тебя матрицы? в чём суть сакральная?
В строке 122 какой глубокий смысл в установке бита: if (code |= 16...?
да ничего сакрального... джойстик подрулевой от рено делаю обработку кнопок, кнопки там организованны в виде матричной клавиатуры 1 2 3
4 5 6
7 8 9
где с 1 по 6 это кнопки, а 7 по 9 это энкодер, который представляет из себя следующее: три контакта, и один общий, одно вращение(один щелчок), замыкатся к примеру на 7, еще один на 8 и далее на 9... в обратную сторону аналогично.
опрос кнопок сделал не без помощи людей(помогли с энкодером т.к. он нестандартный) все работает... но захотелось на некоторые кнопки повесить длинное нажатие. пример с mills() не особо у меня выходит!
пардон я уже под вечер тупил... целый день возился с milis() и выло следующее, что описал в выше
Вернемся к строке 122, что ты хотел в ней написать?
if
(code |= 16 & pressed ==
true
) //у меня фантазии не хватает понять, какой смысл ты хотел заложить в эту строку
Вот так было изначально, в принципе работает... если нажать на любую клавишу и удерживать, но сначало идет несколько нажатий того что нажал, и только потом один раз событие соответсвующее долгому нажатию
Событие надо генерить по отпусканию кнопки. И нужен антидребезг.
а можете что то накинуть, как по отпуску делать или просто пример было бы достаточно, что бы понять для начала сам принцип!
хотелось бы понять несколько кнопок могут нажиматься одновременно или только одна.
одна, т.к. как ранее писал это подрулевой джойсик и комбинации там не будет, да и муторно это, запоимнать их... за дорогой следить надо))
Тогда мне не понятно назначение масок для клавиш
В данной реализации предполагается возможность нажатия нескольких кнопок. Если в любой момент нажимается только одна кнопка разумно возвращать только код этой кнопки. Логичнее будет так:
Отловили нажатие кнопки, начали считать, дождались отпускания, по подсчитанному приняли решение. Дребезг убрать.
Как вариант ликвидации дребезга, нажатие не может быть короче 20-100мС (подбирать).
Эт если лисапед уж так не нравится.
И с энкодером у меня что-то никак не укладывается в голове, для чего там матрица 3х3...
У энкодера вроде один контакт постоянно замкнут.... нет?
попробуйте использовать библиотеку keypad.h
с этой библиотекой удобно работать с событиями кнопки: нажата, отпущена, удержана.
ну вы посмотрите схему, коричневый провод общий, желтый синий и зеленый., из них всегда один замкнут на коричневый
накидал по отжатию
спасибо, я делал с этой библиотекой... добился нормальной работы кнопок, но энкодер так и не смог завести... жалко код не сохранил. Поэтому и отошел от нее
попробуйте использовать библиотеку keypad.h
с этой библиотекой удобно работать с событиями кнопки: нажата, отпущена, удержана.
спасибо, я делал с этой библиотекой... добился нормальной работы кнопок, но энкодер так и не смог завести... жалко код не сохранил. Поэтому и отошел от нее
Тогда уж так:
Тогда уж так:
Вообщем вставил этот кусок кода, история таже, сначала несколько раз нажатие проскакивает кнопки и только, как отпущу кнопку и убрался больше 1 секунды, тогда уже событие))) понятно почему, если целый код смотреть, то видно что после короткого нажатия присваиваеся значение маски, и данный кусок кода не может заблокировать это действие... поэтому и проскальзывает сначало((
Спасибо вам что со мной повозились! Реально думал что можно обработать кнопку на деле все иначе... попробую пару вариантов что накидал выше народ с друшими готовыми примерами попробую переделать и подогнать под себя!