титановый велосипед для тактовой кнопки

std
Offline
Зарегистрирован: 05.01.2012

ЕвгенийП пишет:
дублирование кода ради добавления нового объекта никуда нахрен не годится.

Вот мои кнопки, если не устраивают Клаповские:

/* Connection:
                      +-----------+
    +--/ --+----------| in1       |
    |  S1  |          |           |
    |      +--|<|--+  |           |
    |         D1   |  |           |
    +--/ --+-------|--| in2       |
    |  S2  |       |  |           |
    |      +--|<|--+  |           |
    |         D2   |  |           |
    |              +--| D2 (INT0) |
    |                 |...........|
   _|_ gnd                                   */

#define btn1 (4)
#define btn2 (5)
#define btn3 (6)
#define btn4 (7)

#define reprate    (200)    // repeat rate, ms
#define btnsingthr (500)    // hold thresholds, ms
#define btndecthr  (2000)
#define btnhundthr (4500)

/* Keycodes:
  1..4   - press
  11..14 - hold
  21..24 - hold more
  31..34 - hold even more
  0      - no key          */

volatile boolean       bKeyDown=false,
                       bPrevKeyDown=false;
volatile byte          nKey,prevKey;
unsigned long tot_key,last_key;
boolean  bKeyPressing=false;

void setup(){
  pinMode(2,INPUT_PULLUP);     // int0
  pinMode(btn1,INPUT_PULLUP);  // btns
  pinMode(btn2,INPUT_PULLUP);
  pinMode(btn3,INPUT_PULLUP);
  pinMode(btn4,INPUT_PULLUP);
  attachInterrupt(0,kbdFlag,CHANGE);
  Serial.begin(9600);
  last_key=millis();
  nKey=0;
}

void kbdFlag(){
  if(digitalRead(2)){          // rising
    prevKey=nKey;
    nKey=0;
    bKeyDown=false;
  }else{                       // falling
    nKey=0;
    if(!digitalRead(btn1)) nKey=1;
    if(!digitalRead(btn2)) nKey=2;
    if(!digitalRead(btn3)) nKey=3;
    if(!digitalRead(btn4)) nKey=4;
    bKeyDown=true;
  }
}

byte kbdMain(){  
  byte kbdres;
  if(bPrevKeyDown!=bKeyDown){        // debounce
    bPrevKeyDown=bKeyDown;
    delay(10);
  }
  if(!bKeyPressing && bKeyDown){     // press
    if(nKey!=0) tot_key=millis();
    bKeyPressing=true;
    return 0;
  }
  if(bKeyPressing && bKeyDown){      // repeat
    if(millis()-tot_key>=btnhundthr) kbdres=nKey+30;
     else if(millis()-tot_key>=btndecthr) kbdres=nKey+20;
      else if(millis()-tot_key>=btnsingthr) kbdres=nKey+10;
  }
  if(bKeyPressing && !bKeyDown){     // release
    if(millis()-tot_key<btnsingthr) kbdres=prevKey;
     else kbdres=0;
    bKeyPressing=false;
  }
  if(kbdres<10) return kbdres;       // return press code immediately
   else{
    if(millis()-last_key>=reprate){  // return hold code at repeat rate
      last_key=millis();
      return kbdres;
    }
  }
}

void loop(){
  switch(kbdMain()){
    case 1:  Serial.println("P1");break;
    case 2:  Serial.println("P2");break;
    case 3:  Serial.println("P3");break;
    case 4:  Serial.println("P4");break;

    case 11: Serial.println("H1");break;
    case 12: Serial.println("H2");break;
    case 13: Serial.println("H3");break;
    case 14: Serial.println("H4");break;

    case 21: Serial.println("H1+10");break;
    case 22: Serial.println("H2+10");break;
    case 23: Serial.println("H3+10");break;
    case 24: Serial.println("H4+10");break;

    case 31: Serial.println("H1+100");break;
    case 32: Serial.println("H2+100");break;
    case 33: Serial.println("H3+100");break;
    case 34: Serial.println("H4+100");break;
  }
}

Они не умеют dblclick, зато могут жаться длинно, более длинно и очень длинно. И ещё можно добавить очень гипер мега длинно - ещё одна метка времени и ещё один флаг. Синхронизация состояний по прерыванию - ну пришлось. Если выбросить кусок про подавление дребезга (там где delay) - на работоспособности не отражалось, но на всякий случай пусть будет.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

std,

спасибо, но меня не то, чтобы что-то не устраивает, просто человек явно попросил высказать мнение, я высказал (когда не просят, я помалкиваю по принципу "не говори человеку что и как ему делать, и он не скажет, куда тебе идти").

Правда, когда просят, тоже надо осторожным быть. Помню как-то попросили замечаний на код для 7-сегментника. Предложил небольшим изменением переделать из одиночного экрана в "пул виртуальных экранов", чтобы в программе иметь несколько виртуальных экранов и выводить на них как на настоящие (не парясь показываются они или нет), а отдельная маленькая функциюшка в любой момент могла привязать любой из виртуальных экранов к реальному. Даже пример кода дал. Но контрагент не понял о чём это я и, на всякий случай, обхамил. Вот и думай помогать людям или не стоит, даже когда просят.

А кнопки, поверьте, если мне нужно запрограммировать кнопку - у меня нет никаких проблем :)

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

ЕвгенийП пишет:

Вы имеет в виду 17 кнопок?

Ну, вот, смотрите, у меня обявлено 3 переменных (строки 17-19). Объвите там ещё 14, если нужно.

тогда я имел ввиду все уникальные переменные, используемые в моём коде, но сейчас это уже не актуально, т.к. мне ещё более непонятно, зачем объявлять переменные светодиодов, если в контексте использования класса для масштабирования - уникальный объект "светодиод" должен генериться автоматически при объявлении пина, к которому подключен светодиод.

т.е. должно выглядеть как:

led(pin_led); // где pin_led - номер пина, к которому подключен светодиод.

ЕвгенийП пишет:

Например, я хочу заявить, что у меня кнопки на пинах со второго по двенадцатый. Отлично, вместо строк 17-19, так и пишу.

Blinker btn2(2), btn3(3), btn4(4), btn5(5), btn6(6), btn7(7), 
    btn8(8), btn9(9), btn10(10), btn11(11), btn12(12);

выше писал, что так подозреваю, что должно выглядеть так

btn(pin_btn); // где pin_btn - пин к которому подключена кнопка.

ЕвгенийП пишет:

а для того, чтобы они все работали, вместо строк 24-26 пишу теперь:

btn2.DoBlink(); btn3.DoBlink(); btn4.DoBlink(); btn5.DoBlink(); 
btn6.DoBlink(); btn7.DoBlink(); btn8.DoBlink(); btn9.DoBlink(); 
btn10.DoBlink(); btn11.DoBlink(); btn12.DoBlink(); 

ну тогда, так как мы знаем, куда подключены кнопки и светодиоды, то

btn.Blink(); // и, всё!

ЕвгенийП пишет:

В принципе, кнопки можно объявить массивом и тогда в loop не надо перечислять все, а достаточно написать цикл по массиву. Если интересно, могу написать и такой пример. Надо?

спасибо, пока не нужно - кроме генерации из примера блинк монстра с переменными, которых в начальном примере не было, ничего не происходит.

должно было получиться так

void loop() {
Blink(13); // светодиод подключен к пину 13.
// или
Blink(pin_led); // светодиод подключен к пину pin_led, pin_led объявляется или генерится программно.

*но за направление, вкуда копать - ещё раз спасибо.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

Tomasina пишет:

вот тут внятно расписано как использовать классы вместо дублирования кода: http://robotosha.ru/arduino/multi-tasking-arduino.html

ок. я почитаю.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Клапауций 999, боюсь, что Вы не понимаете смысла использования классов.

Объявляя класс Вы создаёте по сути новый тип данных. А потом просто обявляетете переменные этого типа. 

Давайте. Вы для начала не будете искать ардуиновскеи примеры, а просто прочтёте классику - http://fet.aics.ru/doc/straus_cpp/C++.pdf . Надеюсь, после этой книги у Вас больше не будет вопросов по классам и их использованию.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

ЕвгенийП пишет:

Клапауций 999, боюсь, что Вы не понимаете смысла использования классов.

вы не представляете, как мне страшно.

сначала - мне нужно автоматически генерировать уникальные объекты на основе шаблона обработки работы кнопки.

идентификатором объекта предполагаю использовать номер пина, к которому подключена кнопка.

т.е. в контексте моего кода - кусок текста кода "_00" должен заменяться на "pin_btn", где pin_btn - пин к которому подключена кнопка.

результатом работы объекта должен быть переход на подпрограмму, имя которой... да, да - с именем BUTTON[pin_btn]_bounce_down();

*вы предложили классы - ну, может быть, когда я пойму смысл использования классов.

fot
Offline
Зарегистрирован: 23.10.2011

Есть  библиотека  "OneButton "

http://www.mathertel.de/Arduino/OneButtonLibrary.aspx

Поддерживает функции :

Короткое нажатие, Длинное нажатие. 

Двойное нажатие, защита от дребезга.

Назначение любого кол-ва кнопок.

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

fot пишет:

Есть  библиотека  "OneButton "

http://www.mathertel.de/Arduino/OneButtonLibrary.aspx

есть библиотека, а есть люди у которых есть персональные хотелки - предоставленный код именно им и предназначен для самообучения или простой интеграции в свой проект.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

концептуално неправильный, но полезный фикс кода

строку

41 ++c;      if (c == 2) {BUTTON_00_doubleclick_down();} // двойной клик.

меняем на

41 ++c;      if (c == 2) {c = 0; BUTTON_00_doubleclick_down();} // двойной клик.

позволяет даблкликать в режиме реального времени, не зависимо от того, когда был произведён последний даблклик.

кароче - нет тупняка длиной времени отслеживания даблклика.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

класс для титановый велосипед для тактовой кнопки лежит здесь

http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-...

Клапауций 998
Offline
Зарегистрирован: 12.08.2015

что бы любопытствующим стало ясно, что тут происходит и зачем это всё нужно - просто понадобилось отрабатывать события нажатия и отпускания кнопки:


boolean b00 = 1; // переменная, хранящая состояние кнопки b00.

void setup() {
// здесь, возможно, потребуется сконфигурировать пин кнопки как вход.
}

void loop() {
BUTTON_00();
// здесь крутятся подпрограммы и-или тело основной программы.
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void BUTTON_00() {
boolean nb00 = digitalRead(3);
if (nb00 != b00) {b00 = nb00;
if (b00 == 0) {BUTTON_00_on();} // срабатывает один раз при нажатии кнопки.
if (b00 == 1) {BUTTON_00_of();} // срабатывает один раз при отпускании кнопки.
}
}

void BUTTON_00_on() {} // здесь находится всё, что должно происходить при нажатии кнопки.
void BUTTON_00_of() {} // здесь находится всё, что должно происходить при отпускании кнопки.

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

По моему скромному мнению событие нажимания кнопки как  начало процесса дребезга контактов не имеет никакого значения.
Значение имеет установившееся значения нажатия- то есть окончание дребезга.
 

Но !
Нажатие кнопки как таковое абсолютно не интересное событие.
( за исключением простых случаев - но это digitalRead() и нам такие случаи не интересны)
Для того чтобы понять что там с кнопкой происходит главное когда её отпустили.
Иди сколько держали в нажатом состоянии.
Или щёлкали согласно нашим временнЫм параметрам.
И пока мы не определили ТОЧНО что это было: нажатие, двойное нажатие или удержание
все остальные события являются лишним "шумом" на выходе.....

То есть нажатие кнопки есть некое промежуточное событие участвующее в алгоритме определения
что мы там понажимали и не имеющее никакой ценности
и  тем более необходимости для генерации события о нажатии.

И вообще в природе должна быть однозначность.
Да или Нет вот в чём вопрос.

 

 

Клапауций 998
Offline
Зарегистрирован: 12.08.2015

trembo пишет:

По моему скромному мнению событие нажимания кнопки как  начало процесса дребезга контактов не имеет никакого значения.

по моему нескромному мнению, ты несёшь полную ахинею, т.к.:

- нажатием кнопки считается первый факт физического замыкания контакта - не важно, вследсвии чего это произошло, дребезга, тремора или иного внешнего воздействия. так же не важно, что происходит после нажатия в течении времени фильтрации дребезга - т.к. мы уже сделали то, что нам нужно и дальнейшие события нас не волнуют абсолютно.

- отпусканием кнопки считается факт отсутсвия нажатия в течение времени фильтрации дребезга. иначе "нажато", если чаще длины времени фильтрации дребезга, то "дребезг" - блокируется весь мусор и всерьёз не воспринимается.

- снова за рыбу деньги, что тебе не написали машину времени или ты сам готов ждать несколько секунд, когда тебе вернётся результат действий с кнопкой - было ли это одиночное нажатие, даблклик, удержание или бездействие. не парь мосг - ты уже раза четыре об этом написал и я тебе отвечал.

*добавлен пример для визуально просветления восприятия: 


// установить в исходнике класса
static const byte bounce_              =  250; // длительность отслеживания дребезга.

// void loop() поместить это
if (BUTTON_01.click_down) {digitalWrite(led_01, 0); digitalWrite(led_02, !digitalRead(led_02));}
if (BUTTON_01.click_up) {digitalWrite(led_01, 1); digitalWrite(led_03, !digitalRead(led_03));}
// led_01 загорится при BUTTON_01.click_down == TRUE - событие нажатия
// led_01 погаснет при BUTTON_01.click_up == TRUE - событие отпускания
// led_02 будет инвертирован при изменении BUTTON_01.click_down - удобно для визуального контроля частоты отработки события
// led_03 будет инвертирован при изменении BUTTON_01.click_up - удобно для визуального контроля частоты отработки события

теперь пробуйте нажимать кнопку чаще 250 миллисекунд

step962
Offline
Зарегистрирован: 23.05.2011

Клапауций 998 пишет:

теперь пробуйте нажимать кнопку чаще 250 миллисекунд

Да с этим даже эстонец справится: http://old.gazeta.ee/view/8/88

Клапауций 998
Offline
Зарегистрирован: 12.08.2015

step962 пишет:

Клапауций 998 пишет:

теперь пробуйте нажимать кнопку чаще 250 миллисекунд

Да с этим даже эстонец справится: http://old.gazeta.ee/view/8/88

бля. есчё один долбоёб.

Gummi_bear
Offline
Зарегистрирован: 23.11.2014

Блин, тема достойна IThappens или как минимум SU.HUMOR  :-)

Люди, вы зачем на человека накинулись? Опомнитесь! :-)

Здесь не все профи и асы, начинающих - хоть пруд пруди,

сделал человек доброе дело, "изобрел колесо" для своих нужд, и оно ему нравится, он его пользует и в ус не дует,

поделился с сообществом, ну дык чего вы на него накинулись?

То вам колесо кривое, то размер не тот, так колеса не делают, где брызговики? и.т.д.

Сделайте себе своё, как вам надо, и узбагойтесь :-)

Для чайников вроде меня, такие вещи - это большое подспорье, экономия времени, опыт изучения и.т.д.

Придёт время, и я тоже изобрету свой костыль, колесо, и.т.д. по списку :-)

И так-же запилю пост, вот только в дискуссии вступать не буду :-) Работает? - Работает.

Дальше допиливайте сами как вам надо.

Дружелюбнее как-то быть надо :-)

За ТС не заступаюсь, просто выражаю своё мнение, форумы ведь и для этого тоже, правда?

Пойду, ща шпалами закидают :-)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Какие проблемы, есть достойный http://govnokod.ru

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Gummi_bear пишет:

Люди, вы зачем на человека накинулись? Опомнитесь! :-)

Здесь не все профи и асы, начинающих - хоть пруд пруди,

сделал человек доброе дело, "изобрел колесо" для своих нужд, и оно ему нравится, он его пользует и в ус не дует,

поделился с сообществом, ну дык чего вы на него накинулись?

То вам колесо кривое, то размер не тот, так колеса не делают, где брызговики? и.т.д.

В начале топика автор попросил критики и комментариев ("профессиональным программистам, конструктивная критика и предложения по внесению изменений в код приветсвуется"). Правда, судя по мату в адрес коллег, ожидал он вовсе не критики, а исключительно "восхищамс-одобрямс". Бывает.

Gummi_bear пишет:
Сделайте себе своё, как вам надо, и узбагойтесь :-)

Дык, делаем же ж помаленьку.

Клапауций 998
Offline
Зарегистрирован: 12.08.2015
так. проходящих мимо юмористов, попрошу прекратить бред в теме. 
считающих себя профессиональными программистами, попрошу прекратить бред в теме. 
профессиональных программистов, считающих, что их кто-то попросил и поэтому они вправе здесь бредить, попрошу прекратить бред в теме. 
 
по сути сабжа: 
 
- никто из считающих себя профессиональными программистами не выдал ни одной рекомендации по логике обработки событий нажатия кнопки, поэтому были отосланы в лес. 
- некоторые любители пытались, но скатились в бред, поэтому были посланы в лес. 
 
*привет всем.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, поняли мы уж насчёт леса, поняли. Впредь, если тебе понабится консультация, совет или мнение, можешь сразу идти лесом.

*привет всем.

Клапауций 998
Offline
Зарегистрирован: 12.08.2015

ЕвгенийП пишет:

Да, поняли мы уж насчёт леса, поняли. Впредь, если тебе понабится консультация, совет или мнение, можешь сразу идти лесом.

слушай, ты уже утомил своми бессмысленными претензиями и угрозами - иди в пень.