Библиотека kakmyc_btn.h

b707
Offline
Зарегистрирован: 26.05.2017

BOOM пишет:

Ты пойми, тут далеко не ВУЗ (или школа, или шарага, а форум (да, со своими странными правилами, но форум)), взрослый мужик ведь и должен уже "мух от котлет отделять".

понятно... То есть по итогу это я "должен мух от котлет отличать", а не ты?

 

Ну и пошел в ж тогда.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

b707 пишет:

Впрочем, я не обидчивый...

b707 пишет:

Ну и пошел в ж тогда.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Почему-то у всех библиотек для кнопок я вижу один и тот же недостаток: стремление авторов привязать кнопку к конкретному пину Ардуины.

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

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

Возможна, но только при условии, что мы полностью абстрагируемся от того, как на физическом уровне работает кнопка. А для этого кнопку надо рассматривать как устройство, имеющее два состояния: "нажата" и "отпущена". И тогда меняется вся идеология работы с кнопкой: на вход функции read() (исходя из приведенного исходника) должно подаваться сразу ее состояние, которое может определяться функцией  digitalRead(), условием вхождения в диапазон для функции analogRead(), битом результата, введенного из сдвигового регистра, результатом опроса матрицы и т.п. Т.е. это не функция библиотеки - опрашивать физическую кнопку, это должно быть сделано вне библиотеки.  А сама библиотека должна только обрабатывать дребезг, двойное нажатие, длинное нажатие, сообщать как о состоянии (нажата или отпущена в настоящий момент), так и о событии (было ли нажатие или отпускание с момента предыдущего опроса или нет) и т.п.

И еще одно замечание: библиотека должна делать две вещи: регулярно опрашивать [необработанное] состояние кнопки и по необходимости выдавать [обработанное] текущее состояние. Это две различные функции, которые вряд ли имеет смысл объединять в одну:

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

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

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

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

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

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

b707
Offline
Зарегистрирован: 26.05.2017

andriano пишет:

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

предлагаете передавать библиотеке указатель на функцию опроса кнопки? - да это интересный вариант...

Или Вы что-то иное имели в виду?

nik182
Offline
Зарегистрирован: 04.05.2015

Согласен с концепцией. Не согласен с приложением к МК. Не вижу смысла в библиотеках кнопки да и многих периферийных устройств, которые инициализируются и читаются парой строк. Сколько кнопок обычно в проекте? Четырёх хватает. Если больше то проще использовать сторонние клавиатуры. Или виртуальные на смартфоне или ПК. На 4 кнопки в моих проектах уходит 18 строк с функционалом подавления дребезга, длинных, коротких и коротких пулемётных нажатий. Мне этого хватает на все обычные действия - хождения по меню, изменения и выбор параметров, подтверждение действий, прерывания и переходы программы. Может быть мои заморочки следствие тех времён, когда МК были маленькие и медленные и шла борьба за каждый байт и тик. 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

andriano пишет:

Почему-то у всех библиотек для кнопок я вижу один и тот же недостаток: стремление авторов привязать кнопку к конкретному пину Ардуины.

Не к ночи будет сказано, но у Гайвера в библиотеке есть виртуальная кнопка без привязки к пину. С другой стороны это нужно, имхо, только для аналоговых кнопок. А разные функции одной и той же кнопки в разных режимах реализуются в самом скетче. Если это физически одна и та же кнопка, то какой смысл заморачиваться с виртуализацией? Считать состояние и выбрать действие в зависимости от режима.

Да и состояние кнопки не обязано теряться после его считывания

byte _state = btn1.getButtonState();

И используй _state на всем проходе loop как нужно

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

b707 пишет:

andriano пишет:

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

предлагаете передавать библиотеке указатель на функцию опроса кнопки? - да это интересный вариант...

Или Вы что-то иное имели в виду?

Позволю себе процитировать себя же:

andriano пишет:

И тогда меняется вся идеология работы с кнопкой: на вход функции read() (исходя из приведенного исходника) должно подаваться сразу ее состояние...

Т.е. на каждом проходе loop() должна вызывать (один раз) функция, которая сообщает библиотеке текущее состояние кнопки (либо всех кнопок), полученное от "железа". А для опроса кнопок предусматривается другая функция (или набор функций), которая сообщает по запросу, в каком состоянии находится кнопка и были ли с момента ее предыдущего опроса нажатия/отпускания.

Конкретно: в функцию read() нужно передавать логический параметр, нажата кнопка или отпущена, а не пытаться определить эту информацию внутри библиотеки.

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

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ну в общем то обработчик позволяет все это обрабатывать. В примере с аналоговыми кнопками это имеет место быть. #14

 

ЗЫ: кстати, как размещать ссылку на конкретное сообщение ?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nik182 пишет:

Согласен с концепцией. Не согласен с приложением к МК. Не вижу смысла в библиотеках кнопки да и многих периферийных устройств, которые инициализируются и читаются парой строк. Сколько кнопок обычно в проекте? Четырёх хватает.

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

 

PS. Среди моих тем, размещенный в "Проектах", есть и устройство на Nano с 60-ю кнопками.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Нано с 60кнопками сожрёт байт 700-800 с таким обработчиком.

Дорого...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Kakmyc пишет:

Нано с 60кнопками сожрёт байт 700-800 с таким обработчиком.

Дорого...

Ну так в "Нане" памяти в 3 раза больше.

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