pulseIn и двойное нажатие клавиши
- Войдите на сайт для отправки комментариев
Ср, 19/11/2014 - 00:01
смысл такой
по зажатию кнопки больше чем на 0,5 секунды активировать void lob(); и держать пока не отпустишь кнопку.
по двойному клику на туже кнопку активировать void fara();.
Давлю на кнопку как могу, нихрена. Схему привел, скетч скинул.
Часть с двойным кликом в моем исполнении - бред сивой кобылы. Приму в дар исправления.
в конце все будет на Аттине13
int Fara = 7;
int Lob = 6;
int nasos = 3;
int clapan = 2;
int lepestok = 5;
int davil = 0;
void setup()
{
pinMode(Fara, OUTPUT);
pinMode(Lob, OUTPUT);
pinMode(nasos, OUTPUT);
pinMode(clapan, OUTPUT);
pinMode(lepestok, INPUT);
pinMode(12,OUTPUT);
}
void loop()
{
int time1 = millis();
davil = pulseIn(lepestok, HIGH);
if (davil > 500000)
{
lob();
}
else if (davil<500000&&davil>200000)
{
if (((time1-millis())>220)&&(time1-millis())>2000)
{
fara();
}
}
}
void lob()
{
digitalWrite(Lob,HIGH);
digitalWrite(nasos,HIGH);
delay(5000);
digitalWrite(Lob,LOW);
digitalWrite(nasos,LOW);
}
void fara()
{
int lep=digitalRead(lepestok);
while( lep = 1)
{
digitalWrite(Fara,HIGH);
digitalWrite(clapan,HIGH);
digitalWrite(nasos,HIGH);
delay(5000);
digitalWrite(Fara,LOW);
digitalWrite(clapan,LOW);
digitalWrite(nasos,LOW);
}
}
pulseIn ждет изменение уровня секунду, и если ничего нет, то возвращает 0, ЕМНИП.
Т.е. проверяешь перед замером, что кнопка не нажат и начинаешь ловить. Если после замера 0, то прогон оказался пустым и ничего делать не надо.
Еще я не понял сакральный смысл 29-й строки.
чтобы эту мысль реализовать по человечески, нужно бы пользоваться прерываниями функция (attachInterrupt() ), и еще - кроме LOW и HIGH есть еще другие значения- в данном случае может быть актуально.
так что тут до фары, насоса и клапана еще очень далеко :-)
pulseIn ждет изменение уровня секунду, и если ничего нет, то возвращает 0, ЕМНИП.
Т.е. проверяешь перед замером, что кнопка не нажат и начинаешь ловить. Если после замера 0, то прогон оказался пустым и ничего делать не надо.
Еще я не понял сакральный смысл 29-й строки.
Секунду? Я вроде понял что таймаут ожидания можно выставлять, приписывая 3 параметр как время в МИКРОсекундах.
29 строкой пытался поймать быстрый клик, т.е. Зажатие больше чем на 0,2 секунды но меньше чем на 0,5
чтобы эту мысль реализовать по человечески, нужно бы пользоваться прерываниями функция (attachInterrupt() ), и еще - кроме LOW и HIGH есть еще другие значения- в данном случае может быть актуально.
так что тут до фары, насоса и клапана еще очень далеко :-)
я более менее умею обращаться с прерыванием.
У меня цель освоить пульсИн.
пусть фара, насос и клапан вас не смущают, допустим там 4 светодиода как на схеме.
А где могут быть интересующие меня значения кроме 1 и 0, я не понял
> А где могут быть интересующие меня значения кроме 1 и 0, я не понял
в digitalRead(), которым Вы не пользуетесь.
а 29я строка не причем, там просто в первой части знак перепутан (должно быть "<"). Ваша проблема, естественно, в том, что Вы храните сравниваете значения, которые имеют тип unsigned long (функции времени вроде millis() ) со своими переменными типа int. Если Вы посмотрите, какая максимальная величина может храниться в int, всё встанет на свои места.
IMHO, pulseIn() в данной задаче выглядит насильно притянутым за уши с целью изучения, а вот attachInterrupt() - самое то.
IMHO, pulseIn() в данной задаче выглядит насильно притянутым за уши с целью изучения, а вот attachInterrupt() - самое то.
согласен полностью. Просто хочу освоить
> А где могут быть интересующие меня значения кроме 1 и 0, я не понял
в digitalRead(), которым Вы не пользуетесь.
а 29я строка не причем, там просто в первой части знак перепутан (должно быть "<"). Ваша проблема, естественно, в том, что Вы храните сравниваете значения, которые имеют тип unsigned long (функции времени вроде millis() ) со своими переменными типа int. Если Вы посмотрите, какая максимальная величина может храниться в int, всё встанет на свои места.
В digitalRead() на выходе можно получить иное чем 0 или 1????
Да неужели?
>Да неужели?
Угу. только для этого нужны кой-какие телодвижения, в общем не грузитесь )
И вообще, простого "спасибо" было вполне достаточно ;-)
>Да неужели?
Угу. только для этого нужны кой-какие телодвижения, в общем не грузитесь )
И вообще, простого "спасибо" было вполне достаточно ;-)
с телодвижениями все можно.
за тип спасибо
с внимательным чтениям мануалов у меня всегда проблемы были и будут
Топикстартеру за давностью лет наверное уже не нужно, но если кто пришел по поиску как я, то вот моё (рабочее) решение фиксации события с кнопкой:
// Объявляем переменные и константы const int buttonPin = 2; // Пин с кнопкой int currentButtonStatus = 0; // 0 - Кнопка не нажата // 1 - Кнопка нажата первый раз // 2 - Кнопка отжата после нажатия // 3 - Кнопка нажата во второй раз unsigned long currentButtonStatusStart1; // Кол-во милисекунд от начала работы программы, когда начался статус 1 unsigned long currentButtonStatusStart2; // Кол-во милисекунд от начала работы программы, когда начался статус 2 unsigned long currentButtonStatusStart3; // Кол-во милисекунд от начала работы программы, когда начался статус 3 int currentValue = 10; // Текущее значение громкости const int maxValue = 30; // Максимальное значение громкости const int minValue = 5; // Минимальное значение громкости const int delayFalse = 10; // Длительность, меньше которой не регистрируется единоразовый клик const int delayLongSingleClick = 1000; // Длительность зажатия кнопки для выхода в режим увеличения громкости const int delayDeltaDoubleClick = 800; // Длительность между кликами, когда будет зафиксирован двойной клик void setup() { // Прописываем пины pinMode(buttonPin, INPUT); // Вывод Serial.begin(9600); } void loop() { // Определяем текущий статус кнопки int event = changeButtonStatus(); if(event > 0) { // Если поменялся статус Serial.print("status change: "); //time = millis(); Serial.println(event); } } /** * Смена текущего статуса * @return = 0 - ничего не произошло * 1 - простой клик * 2 - двойнок клик * 3 - зажата кнопка * 4 - отжата кнопка после долгого зажатия */ int changeButtonStatus() { // Событие int event = 0; // Текущее состояние кнопки int currentButtonClick = digitalRead(buttonPin); // Текущее время unsigned long timeButton = millis(); switch(currentButtonStatus) { case 0: // В настоящий момент кнопка не нажималась if(currentButtonClick) { // Зафиксировали нажатие кнопки currentButtonStatus = 1; currentButtonStatusStart1 = millis(); } else { // Кнопка не нажата // Ничего не происходит } break; case 1: // В настоящий момент кнопка на этапе первого нажатия if(currentButtonClick) { // Кнопка все еще нажата if(timeButton - currentButtonStatusStart1 >= delayLongSingleClick) { // Кнопка в нажатом состоянии уже дольше времени, после которого фиксируем длительное одинарное нажатие на кнопку // Событие длительного давления на кнопку - продолжаем давить event = 3; } } else { // Кнопку отжали обратно if(timeButton - currentButtonStatusStart1 < delayFalse) { // Время, которое была кнопка нажата, меньше минимального времени регистрации клика по кнопке // Скорее всего это были какие то флюктуации // Отменяем нажатие currentButtonStatus = 0; event = 0; } else if(timeButton - currentButtonStatusStart1 < delayLongSingleClick) { // Время, которое была кнопка нажата, меньше времени фиксации долгого нажатия на кнопку // Значит это первое одноразовое нажатие // Дальше будем ожидать второго нажатия currentButtonStatus = 2; currentButtonStatusStart2 = millis(); } else { // Время, которое была нажата кнопка, больше времени фиксации долгого единоразового нажатия // Значит это завершение длительного нажатия currentButtonStatus = 0; event = 4; } } break; case 2: // Мы находимся в фазе отжатой кнопки в ожидании повторного ее нажатия для фиксации двойного нажатия // или, если не дождемся - значит зафиксируем единичное нажатие if(currentButtonClick) { // Если кнопку снова нажали // Проверяем, сколько времени кнопка находилась в отжатом состоянии if(timeButton - currentButtonStatusStart2 < delayFalse) { // Кнопка была в отжатом состоянии слишком мало времени // Скорее всего это была какая то флюктуация дребезга кнопки // Возвращаем обратно состояние на первичное нажатие кнопки currentButtonStatus = 1; } else { // Кнопка была достаточно долго отжата, чтобы зафиксировать начало второго нажатия // Фиксируем currentButtonStatus = 3; currentButtonStatusStart3 = millis(); } } else { // Если кнопка все еще отжата // Проверяем, не достаточно ли она уже отжата, чтобы зафиксировать разовый клик if(timeButton - currentButtonStatusStart2 > delayDeltaDoubleClick) { // Кнопка в отжатом состоянии слишком долго // Фиксируем одинарный клие currentButtonStatus = 0; event = 1; } } break; case 3: // Мы на этапе второго нажатия // Для подтверждения факта двойного нажатия if(currentButtonClick) { // Кнопка все еще зажата // Ничего не происходит, ждем, когда отожмут } else { // Кнопку отжали // Проверям, действительно ли отжали, или это дребезг кнопки if(timeButton - currentButtonStatusStart3 < delayFalse) { // Кнопку отжали слишком рано // Скорре всего это дребезг // Гинорируем его } else { // Кнопка была в нажатом состоянии уже достаточно длительное время // Это завершение цикла фиксации двойного нажатия // Сообщаем такое событие event = 2; currentButtonStatus = 0; } } break; } return event; }Делаю возможность смены композиций в mp3-плеере работая с одной кнопкой: нажал = включил - еще раз нажал = выключил - два раза нажал = следующая композиция - долго давлю на кнопку = увеличение звука.
в примере нет работы с музыкой. есть только получение действий с кнопкой. а это уже можно куда хотите прикрутить...
Добрый день. Наверное, уже не актуально, но добавлю свои 5 копеек. Может кому пригодится по поиску. Скетч для мультиклика. Более подробные комментарии написал на сайте. + возможность удержания кнопки и разные функции от времени удержания. arcadepub.ru/кнопка/
#define BUTTON_PIN 2 int bounceTime = 10; // задержка для подавления дребезга int doubleTime = 500; // время, в течение которого нажатия можно считать двойным int i = 0; boolean lastReading = false; // флаг предыдущего состояния кнопки boolean buttonSingle = false; // флаг состояния "краткое нажатие" boolean buttonMulti = false; // флаг состояния "двойное нажатие" long onTime = 0; // переменная обработки временного интервала long lastSwitchTime = 0; // переменная времени предыдущего переключения состояния void setup(){ Serial.begin(9600); } void loop(){ boolean reading = digitalRead(BUTTON_PIN); // проверка первичного нажатия if (reading && !lastReading){ onTime = millis(); } if (!reading && lastReading){ if (((millis() - onTime) > bounceTime)){ if ((millis() - lastSwitchTime) >= doubleTime){ lastSwitchTime = millis(); buttonSingle = true; i=1; } else { i++; lastSwitchTime = millis(); buttonSingle = false; buttonMulti = true; } } } lastReading = reading; if (buttonSingle && (millis() - lastSwitchTime) > doubleTime){ isButtonSingle(); } if (buttonMulti && (millis() - lastSwitchTime) > doubleTime){ isButtonMulti(i); } } void isButtonSingle(){ buttonMulti = false; buttonSingle = false; Serial.println(1); } void isButtonMulti( int count ){ buttonSingle = false; buttonMulti = false; Serial.println(count); }