дублирование кода ради добавления нового объекта никуда нахрен не годится.
Вот мои кнопки, если не устраивают Клаповские:
/* 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) - на работоспособности не отражалось, но на всякий случай пусть будет.
спасибо, но меня не то, чтобы что-то не устраивает, просто человек явно попросил высказать мнение, я высказал (когда не просят, я помалкиваю по принципу "не говори человеку что и как ему делать, и он не скажет, куда тебе идти").
Правда, когда просят, тоже надо осторожным быть. Помню как-то попросили замечаний на код для 7-сегментника. Предложил небольшим изменением переделать из одиночного экрана в "пул виртуальных экранов", чтобы в программе иметь несколько виртуальных экранов и выводить на них как на настоящие (не парясь показываются они или нет), а отдельная маленькая функциюшка в любой момент могла привязать любой из виртуальных экранов к реальному. Даже пример кода дал. Но контрагент не понял о чём это я и, на всякий случай, обхамил. Вот и думай помогать людям или не стоит, даже когда просят.
А кнопки, поверьте, если мне нужно запрограммировать кнопку - у меня нет никаких проблем :)
Ну, вот, смотрите, у меня обявлено 3 переменных (строки 17-19). Объвите там ещё 14, если нужно.
тогда я имел ввиду все уникальные переменные, используемые в моём коде, но сейчас это уже не актуально, т.к. мне ещё более непонятно, зачем объявлять переменные светодиодов, если в контексте использования класса для масштабирования - уникальный объект "светодиод" должен генериться автоматически при объявлении пина, к которому подключен светодиод.
т.е. должно выглядеть как:
led(pin_led); // где pin_led - номер пина, к которому подключен светодиод.
ЕвгенийП пишет:
Например, я хочу заявить, что у меня кнопки на пинах со второго по двенадцатый. Отлично, вместо строк 17-19, так и пишу.
ну тогда, так как мы знаем, куда подключены кнопки и светодиоды, то
btn.Blink(); // и, всё!
ЕвгенийП пишет:
В принципе, кнопки можно объявить массивом и тогда в loop не надо перечислять все, а достаточно написать цикл по массиву. Если интересно, могу написать и такой пример. Надо?
спасибо, пока не нужно - кроме генерации из примера блинк монстра с переменными, которых в начальном примере не было, ничего не происходит.
должно было получиться так
void loop() {
Blink(13); // светодиод подключен к пину 13.
// или
Blink(pin_led); // светодиод подключен к пину pin_led, pin_led объявляется или генерится программно.
*но за направление, вкуда копать - ещё раз спасибо.
Клапауций 999, боюсь, что Вы не понимаете смысла использования классов.
Объявляя класс Вы создаёте по сути новый тип данных. А потом просто обявляетете переменные этого типа.
Давайте. Вы для начала не будете искать ардуиновскеи примеры, а просто прочтёте классику - http://fet.aics.ru/doc/straus_cpp/C++.pdf . Надеюсь, после этой книги у Вас больше не будет вопросов по классам и их использованию.
есть библиотека, а есть люди у которых есть персональные хотелки - предоставленный код именно им и предназначен для самообучения или простой интеграции в свой проект.
что бы любопытствующим стало ясно, что тут происходит и зачем это всё нужно - просто понадобилось отрабатывать события нажатия и отпускания кнопки:
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() {} // здесь находится всё, что должно происходить при отпускании кнопки.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
По моему скромному мнению событие нажимания кнопки как начало процесса дребезга контактов не имеет никакого значения.
Значение имеет установившееся значения нажатия- то есть окончание дребезга.
Но !
Нажатие кнопки как таковое абсолютно не интересное событие.
( за исключением простых случаев - но это digitalRead() и нам такие случаи не интересны)
Для того чтобы понять что там с кнопкой происходит главное когда еёотпустили.
Иди сколько держали в нажатом состоянии.
Или щёлкали согласно нашим временнЫм параметрам.
И пока мы не определили ТОЧНО что это было: нажатие, двойное нажатие или удержание
все остальные события являются лишним "шумом" на выходе.....
То есть нажатие кнопки есть некое промежуточное событие участвующее в алгоритме определения
что мы там понажимали и не имеющее никакой ценности
и тем более необходимости для генерации события о нажатии.
И вообще в природе должна быть однозначность.
Да или Нет вот в чём вопрос.
По моему скромному мнению событие нажимания кнопки как начало процесса дребезга контактов не имеет никакого значения.
по моему нескромному мнению, ты несёшь полную ахинею, т.к.:
- нажатием кнопки считается первый факт физического замыкания контакта - не важно, вследсвии чего это произошло, дребезга, тремора или иного внешнего воздействия. так же не важно, что происходит после нажатия в течении времени фильтрации дребезга - т.к. мы уже сделали то, что нам нужно и дальнейшие события нас не волнуют абсолютно.
- отпусканием кнопки считается факт отсутсвия нажатия в течение времени фильтрации дребезга. иначе "нажато", если чаще длины времени фильтрации дребезга, то "дребезг" - блокируется весь мусор и всерьёз не воспринимается.
- снова за рыбу деньги, что тебе не написали машину времени или ты сам готов ждать несколько секунд, когда тебе вернётся результат действий с кнопкой - было ли это одиночное нажатие, даблклик, удержание или бездействие. не парь мосг - ты уже раза четыре об этом написал и я тебе отвечал.
*добавлен пример для визуально просветления восприятия:
// установить в исходнике класса
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 миллисекунд
Люди, вы зачем на человека накинулись? Опомнитесь! :-)
Здесь не все профи и асы, начинающих - хоть пруд пруди,
сделал человек доброе дело, "изобрел колесо" для своих нужд, и оно ему нравится, он его пользует и в ус не дует,
поделился с сообществом, ну дык чего вы на него накинулись?
То вам колесо кривое, то размер не тот, так колеса не делают, где брызговики? и.т.д.
В начале топика автор попросил критики и комментариев ("профессиональным программистам, конструктивная критика и предложения по внесению изменений в код приветсвуется"). Правда, судя по мату в адрес коллег, ожидал он вовсе не критики, а исключительно "восхищамс-одобрямс". Бывает.
Gummi_bear пишет:
Сделайте себе своё, как вам надо, и узбагойтесь :-)
так. проходящих мимо юмористов, попрошу прекратить бред в теме.
считающих себя профессиональными программистами, попрошу прекратить бред в теме.
профессиональных программистов, считающих, что их кто-то попросил и поэтому они вправе здесь бредить, попрошу прекратить бред в теме.
по сути сабжа:
- никто из считающих себя профессиональными программистами не выдал ни одной рекомендации по логике обработки событий нажатия кнопки, поэтому были отосланы в лес.
- некоторые любители пытались, но скатились в бред, поэтому были посланы в лес.
Вот мои кнопки, если не устраивают Клаповские:
Они не умеют dblclick, зато могут жаться длинно, более длинно и очень длинно. И ещё можно добавить очень гипер мега длинно - ещё одна метка времени и ещё один флаг. Синхронизация состояний по прерыванию - ну пришлось. Если выбросить кусок про подавление дребезга (там где delay) - на работоспособности не отражалось, но на всякий случай пусть будет.
std,
спасибо, но меня не то, чтобы что-то не устраивает, просто человек явно попросил высказать мнение, я высказал (когда не просят, я помалкиваю по принципу "не говори человеку что и как ему делать, и он не скажет, куда тебе идти").
Правда, когда просят, тоже надо осторожным быть. Помню как-то попросили замечаний на код для 7-сегментника. Предложил небольшим изменением переделать из одиночного экрана в "пул виртуальных экранов", чтобы в программе иметь несколько виртуальных экранов и выводить на них как на настоящие (не парясь показываются они или нет), а отдельная маленькая функциюшка в любой момент могла привязать любой из виртуальных экранов к реальному. Даже пример кода дал. Но контрагент не понял о чём это я и, на всякий случай, обхамил. Вот и думай помогать людям или не стоит, даже когда просят.
А кнопки, поверьте, если мне нужно запрограммировать кнопку - у меня нет никаких проблем :)
Вы имеет в виду 17 кнопок?
Ну, вот, смотрите, у меня обявлено 3 переменных (строки 17-19). Объвите там ещё 14, если нужно.
тогда я имел ввиду все уникальные переменные, используемые в моём коде, но сейчас это уже не актуально, т.к. мне ещё более непонятно, зачем объявлять переменные светодиодов, если в контексте использования класса для масштабирования - уникальный объект "светодиод" должен генериться автоматически при объявлении пина, к которому подключен светодиод.
т.е. должно выглядеть как:
Например, я хочу заявить, что у меня кнопки на пинах со второго по двенадцатый. Отлично, вместо строк 17-19, так и пишу.
выше писал, что так подозреваю, что должно выглядеть так
а для того, чтобы они все работали, вместо строк 24-26 пишу теперь:
ну тогда, так как мы знаем, куда подключены кнопки и светодиоды, то
В принципе, кнопки можно объявить массивом и тогда в loop не надо перечислять все, а достаточно написать цикл по массиву. Если интересно, могу написать и такой пример. Надо?
спасибо, пока не нужно - кроме генерации из примера блинк монстра с переменными, которых в начальном примере не было, ничего не происходит.
должно было получиться так
*но за направление, вкуда копать - ещё раз спасибо.
вот тут внятно расписано как использовать классы вместо дублирования кода: http://robotosha.ru/arduino/multi-tasking-arduino.html
ок. я почитаю.
Клапауций 999, боюсь, что Вы не понимаете смысла использования классов.
Объявляя класс Вы создаёте по сути новый тип данных. А потом просто обявляетете переменные этого типа.
Давайте. Вы для начала не будете искать ардуиновскеи примеры, а просто прочтёте классику - http://fet.aics.ru/doc/straus_cpp/C++.pdf . Надеюсь, после этой книги у Вас больше не будет вопросов по классам и их использованию.
Клапауций 999, боюсь, что Вы не понимаете смысла использования классов.
вы не представляете, как мне страшно.
сначала - мне нужно автоматически генерировать уникальные объекты на основе шаблона обработки работы кнопки.
идентификатором объекта предполагаю использовать номер пина, к которому подключена кнопка.
т.е. в контексте моего кода - кусок текста кода "_00" должен заменяться на "pin_btn", где pin_btn - пин к которому подключена кнопка.
результатом работы объекта должен быть переход на подпрограмму, имя которой... да, да - с именем BUTTON[pin_btn]_bounce_down();
*вы предложили классы - ну, может быть, когда я пойму смысл использования классов.
Есть библиотека "OneButton "
http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
Поддерживает функции :
Короткое нажатие, Длинное нажатие.
Двойное нажатие, защита от дребезга.
Назначение любого кол-ва кнопок.
Есть библиотека "OneButton "
http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
есть библиотека, а есть люди у которых есть персональные хотелки - предоставленный код именно им и предназначен для самообучения или простой интеграции в свой проект.
концептуално неправильный, но полезный фикс кода
строку
41
++c;
if
(c == 2) {BUTTON_00_doubleclick_down();}
// двойной клик.
меняем на
41
++c;
if
(c == 2) {c = 0; BUTTON_00_doubleclick_down();}
// двойной клик.
позволяет даблкликать в режиме реального времени, не зависимо от того, когда был произведён последний даблклик.
кароче - нет тупняка длиной времени отслеживания даблклика.
класс для титановый велосипед для тактовой кнопки лежит здесь
http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-...
что бы любопытствующим стало ясно, что тут происходит и зачем это всё нужно - просто понадобилось отрабатывать события нажатия и отпускания кнопки:
По моему скромному мнению событие нажимания кнопки как начало процесса дребезга контактов не имеет никакого значения.
Значение имеет установившееся значения нажатия- то есть окончание дребезга.
Но !
Нажатие кнопки как таковое абсолютно не интересное событие.
( за исключением простых случаев - но это digitalRead() и нам такие случаи не интересны)
Для того чтобы понять что там с кнопкой происходит главное когда её отпустили.
Иди сколько держали в нажатом состоянии.
Или щёлкали согласно нашим временнЫм параметрам.
И пока мы не определили ТОЧНО что это было: нажатие, двойное нажатие или удержание
все остальные события являются лишним "шумом" на выходе.....
То есть нажатие кнопки есть некое промежуточное событие участвующее в алгоритме определения
что мы там понажимали и не имеющее никакой ценности
и тем более необходимости для генерации события о нажатии.
И вообще в природе должна быть однозначность.
Да или Нет вот в чём вопрос.
По моему скромному мнению событие нажимания кнопки как начало процесса дребезга контактов не имеет никакого значения.
по моему нескромному мнению, ты несёшь полную ахинею, т.к.:
- нажатием кнопки считается первый факт физического замыкания контакта - не важно, вследсвии чего это произошло, дребезга, тремора или иного внешнего воздействия. так же не важно, что происходит после нажатия в течении времени фильтрации дребезга - т.к. мы уже сделали то, что нам нужно и дальнейшие события нас не волнуют абсолютно.
- отпусканием кнопки считается факт отсутсвия нажатия в течение времени фильтрации дребезга. иначе "нажато", если чаще длины времени фильтрации дребезга, то "дребезг" - блокируется весь мусор и всерьёз не воспринимается.
- снова за рыбу деньги, что тебе не написали машину времени или ты сам готов ждать несколько секунд, когда тебе вернётся результат действий с кнопкой - было ли это одиночное нажатие, даблклик, удержание или бездействие. не парь мосг - ты уже раза четыре об этом написал и я тебе отвечал.
*добавлен пример для визуально просветления восприятия:
теперь пробуйте нажимать кнопку чаще 250 миллисекунд
теперь пробуйте нажимать кнопку чаще 250 миллисекунд
Да с этим даже эстонец справится: http://old.gazeta.ee/view/8/88
теперь пробуйте нажимать кнопку чаще 250 миллисекунд
Да с этим даже эстонец справится: http://old.gazeta.ee/view/8/88
бля. есчё один долбоёб.
Блин, тема достойна IThappens или как минимум SU.HUMOR :-)
Люди, вы зачем на человека накинулись? Опомнитесь! :-)
Здесь не все профи и асы, начинающих - хоть пруд пруди,
сделал человек доброе дело, "изобрел колесо" для своих нужд, и оно ему нравится, он его пользует и в ус не дует,
поделился с сообществом, ну дык чего вы на него накинулись?
То вам колесо кривое, то размер не тот, так колеса не делают, где брызговики? и.т.д.
Сделайте себе своё, как вам надо, и узбагойтесь :-)
Для чайников вроде меня, такие вещи - это большое подспорье, экономия времени, опыт изучения и.т.д.
Придёт время, и я тоже изобрету свой костыль, колесо, и.т.д. по списку :-)
И так-же запилю пост, вот только в дискуссии вступать не буду :-) Работает? - Работает.
Дальше допиливайте сами как вам надо.
Дружелюбнее как-то быть надо :-)
За ТС не заступаюсь, просто выражаю своё мнение, форумы ведь и для этого тоже, правда?
Пойду, ща шпалами закидают :-)
Какие проблемы, есть достойный http://govnokod.ru
Люди, вы зачем на человека накинулись? Опомнитесь! :-)
Здесь не все профи и асы, начинающих - хоть пруд пруди,
сделал человек доброе дело, "изобрел колесо" для своих нужд, и оно ему нравится, он его пользует и в ус не дует,
поделился с сообществом, ну дык чего вы на него накинулись?
То вам колесо кривое, то размер не тот, так колеса не делают, где брызговики? и.т.д.
В начале топика автор попросил критики и комментариев ("профессиональным программистам, конструктивная критика и предложения по внесению изменений в код приветсвуется"). Правда, судя по мату в адрес коллег, ожидал он вовсе не критики, а исключительно "восхищамс-одобрямс". Бывает.
Дык, делаем же ж помаленьку.
Да, поняли мы уж насчёт леса, поняли. Впредь, если тебе понабится консультация, совет или мнение, можешь сразу идти лесом.
*привет всем.
Да, поняли мы уж насчёт леса, поняли. Впредь, если тебе понабится консультация, совет или мнение, можешь сразу идти лесом.
слушай, ты уже утомил своми бессмысленными претензиями и угрозами - иди в пень.