Press button x3 что значит
Перейти к содержимому

Press button x3 что значит

  • автор:

Press button x3 что значит

Фото Press F to pay respect. Что значит мем F и откуда он взялся

press the button

4 press the button

5 press the button

6 press the button

7 press the button

8 press the button

9 press the button

10 to press the button lightly

11 to press the button

12 to press the button

13 press the panic button

14 press the panic button

15 press the reset button

16 press a button on the panel

17 button

18 button

19 press

20 press

press the button — To set in motion some momentous action, esp the launching of nuclear weapons against an enemy target • • • Main Entry: ↑button press the button 1. To put machinery into operation 2. To start things moving, esp in a momentous or irreversible way • … Useful english dictionary

press the button — Begin … A concise dictionary of English slang

(press) panic button — If you hit or press the panic button, you raise the alarm too quickly or react too hastily in a difficult or stressful situation. Calm down! There s no need to press the panic button yet! … English Idioms & idiomatic expressions

press the panic button — press/push/the panic button informal phrase to become very worried about something bad that happens and react suddenly instead of thinking about it calmly The thought of turning 50 makes me want to press the panic button. Thesaurus: to worry or… … Useful english dictionary

press the right button — press/push the right button/buttons to do exactly what is necessary to get the result that you want. You have to know how to push all the right buttons if you want to be a successful diplomat. Sometimes you re interviewing someone really shy and… … New idioms dictionary

press the right buttons — press/push the right button/buttons to do exactly what is necessary to get the result that you want. You have to know how to push all the right buttons if you want to be a successful diplomat. Sometimes you re interviewing someone really shy and… … New idioms dictionary

press the panic button — become very scared, panic, freak If a dog growls at me, I press the panic button. I scream and run … English idioms

press the right buttons — push/press/the right buttons mainly journalism phrase to please an audience with a political speech by saying things that the audience agrees with The Prime Minister’s speech pushed all the right buttons. Thesaurus: to perform or entertain, or to … Useful english dictionary

press the panic button — hit/press/push the panic button to do something quickly without thinking about it in order to deal with a difficult or worrying situation. We may have lost the last three games but we re not pushing the panic button yet. (often negative) … New idioms dictionary

press the panic button — Go to hit the anic button … Dictionary of American slang and colloquial expressions

Push the Button (Teapacks song) — Infobox ESC entry song = flagicon|Israel Push the Button caption = Performance at the Eurovision Song Contest year = 2007 country = Israel artist = Kobi Oz, Meir Amar ( Big M ), Motti Yoseff, Rami Yosifov, Gal Peremen, Dani Aberjel as = Teapacks… … Wikipedia

Обзор V.Thru Pro Pod от компании Voopoo

Обзор Voopoo V.Thru Pro Pod

Цена в онлайн магазинах: 3FVAPE$16 | AVE40$30 | CLOUMIX$18 | FASTTECH$23 | GEARBEST$34 | HEALTHCABIN$16 | VAPESOURCING$20 | SOURCEMORE$16 |

Обзор V.Thru Pro Pod от компании Voopoo

Автор Павел Котков · 17:00, 21 июля 2021 · AIO и POD / Обзоры · Читать 6 мин · 28

Обзор Voopoo V.Thru Pro Pod

В сегодняшнем обзоре мы посмотрим на продвинутую под-систему с названием V.Thru Pro, выпускает которую производитель Voopoo.

Спасибо магазину SigaretNet за предоставленное устройство

Содержание и навигация

Цена в онлайн магазинах: 3FVAPE $16 | AVE40 $30 | CLOUMIX $18 | FASTTECH $23 | GEARBEST $34 | HEALTHCABIN $16 | VAPESOURCING $20 | SOURCEMORE $16 |

Упаковка Voopoo V.Thru Pro Pod

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

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

Комплектация Voopoo V.Thru Pro Pod

  • Под-система V.Thru Pro Pod (батарейный блок + картридж на 0.7Ω)
  • Дополнительный картридж на 1.2Ω
  • Зарядный кабель формата USB Type-C
  • Инструкция пользователя
  • Пакетик с силикагелем

Внешний вид и конструктив Voopoo V.Thru Pro Pod

На момент своего релиза V.Thru Pro Pod выпускался в шести основных расцветках корпуса, но с недавних пор Voopoo производит свой девайс еще в четырех цветовых решениях, которые отличаются от первоначального дизайна еще и узором.

Под-система V.Thru Pro выполнена в гладком и обтекаемом корпусе из алюминиевого сплава, а комплектные картриджи изготавливаются из пищевого пластика PCTG . Дизайн устройства не слишком броский, из декоративных решений здесь присутствует разве что скромный узор, выполненный при помощи покраски. Чуть ниже виднеется логотип фирменной платы – GENE Chip.

На обратной стороне царит минимализм: один единственный логотип производителя и парочка сертификатов внизу. Боковые грани располагают двумя воздухозаборными отверстиями совсем небольшого диаметра, которые еще и не поддаются какой-либо регулировке. Можно заметить и одну из главных особенностей устройства – монохромный OLED-дисплей с диагональю 0.69 дюйма. Рядом размещена функциональная кнопка, отвечающая за настройку работы платы.

На почему-то глянцевом торце, покраска которого не совпадает по цвету с остальной частью девайса, компания Voopoo установила современный разъем формата USB Type-C для зарядки встроенного аккумулятора на 900мАч. Весь процесс отображается на экране в виде иконки и более информативных процентов. Максимальный ток в данном случае составит не слишком выдающиеся 5В и 1А.

Картриджи Voopoo V.Thru Pro Pod

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

На дне картриджа изначально наклеен стикер, на котором есть надпись о необходимости подождать 5 минут после заправки, тем самым дав испарителю как следует пропитаться. По умолчанию в V.Thru Pro Pod установлен картридж с интегрированным испарителем 0.7Ω Mesh Coil, а в отдельном пакетике в комплекте поставки идет еще один картридж – 1.2Ω GENE Helix Coil. В первом случае в качестве койла используется сетка, а во втором фигурирует двойная спираль (“параллелька”).

Заправка картриджей реализована через незамысловатое боковое отверстие под резиновой заглушкой. На последних есть стрелочка, указывающая направление открытия, а также здесь обозначено сопротивление испарителя. Весь процесс достаточно удобный. Всего же в резервуар для жидкости вмещается не слишком много, но и не слишком мало – до 3мл. Еще одной важной особенностью картриджей заявляется система по сбору конденсата. Проверим ее на практике.

Технические характеристики Voopoo V.Thru Pro Pod
  • Габариты: 95.5мм*28.5мм*14.9мм
  • Материал корпуса: алюминиевый сплав
  • Материал картриджей: PCTG
  • Аккумулятор: 900мАч
  • Зарядка: USB Type-C, 5В/1А
  • Выходная мощность: 5-25Вт
  • Дисплей: монохромный, OLED 0.69″
  • Плата: GENE Chip
  • Автоматическая активация при затяжке
  • Вместительность картриджей: 3мл
  • Испарители: 0.7Ω Mesh Coil, 1.2Ω GENE Helix Coil

Экран и управление Voopoo V.Thru Pro Pod

Как и говорилось выше, в под-системе V.Thru Pro установлена фирменная плата под названием GENE Chip. Для включения устройства необходимо 5 раз нажать на специальную кнопку. На главном экране будет отображаться заряд аккумулятора, длительность последней затяжки, выбранная мощность, напряжение и сопротивление испарителя.

Однократным нажатием на все ту же клавишу можно переместиться на другой экран, и здесь уже будет выводиться счетчик затяжек, снова заряд АКБ и длительность последней затяжки, а также минимальная длительность затяжки. Необходимость всей этой информации весьма спорная. Устройство позволяет настроить выходную мощность в диапазоне 5-25 Ватт, для чего нужно на какое-то время зажать кнопку до тех пор, пока цифры не начнут мигать, а после с шагом в 1 Ватт установить необходимую мощность. Выбранный ваттаж зафиксируется автоматически спустя пару секунд.

В устройстве есть еще кое-какой дополнительный функционал, для доступа к которому во включенном состоянии необходимо пять раз кликнуть на кнопку, после чего покажется меню из трех элементов: Lock, Puff Clear и Power Off. Последний пункт отвечает за выключение, а первый – за защиту от детей. При выборе пункта Lock на экране около мощности будет отображаться значок замка, и если в течение 5 минут не пользоваться девайсом, устройство перейдет в режим сна и потребуется трехкратное нажатие на кнопку для доступа к функционалу, что будет сопровождаться надписью на экране Press Button x3. Что касается второго пункта меню, то он отвечает за сброс счетчика затяжек, все просто. Из другой информации, которая показывается на дисплее, стоит отметить предупреждение о коротком замыкании, о перегреве, о низком уровне заряда и о превышении длительности парения (отсечка в 8 секунд).

Впечатления и выводы

Под-система V.Thru Pro радует сразу несколькими своими особенностям. Девайс выполнен достаточно качественно, ощущается монолитной конструкцией, а благодаря алюминиевому корпусу, небольшим габаритами и скромному весу эргономично лежит в руке. Комплект поставки пусть и не слишком разнообразный, но в нем есть все самое необходимое, в том числе и дополнительный картридж. Для подобного устройства наличие платы с дисплеем и возможностью каких-то настроек тоже большой плюс. Выходной мощности до 25 Ватт достаточно, а следить за уровнем заряда не по цвету индикатора, а по иконке гораздо удобнее. Ориентироваться в функционале тоже несложно. Картриджи стоит похвалить за неплохой объем и в меру насыщенную вкусопередачу. Система по сбору конденсата, если коротко, работает корректно.

К условно негативным моментам отнесем в первую очередь низкий ток заряда – всего 1А. Быстрая зарядка здесь фигурирует разве что в контексте не самой большой емкости АКБ в 900мАч. Также не совсем понятна необходимость отдельного пункта в меню по затяжкам и наличие функции защиты от детей, тем более, что девайс информирует пользователя о том, как его разблокировать. Ребенок (по крайней мере англоговорящий) не сможет прочитать “Press Button x3”? Что касается непосредственно работы, то при затяжке отчетливо слышно какое-то гудение, как будто электрическое, как от небольшого трансформатора, и это не звук обдува. На работу, конечно, не влияет, но упомянуть нужно.

Расшифровка автомобильной аудиосистемы: что означают кнопки

Кнопки информационно-развлекательной системы: назначение.

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

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

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

  • APPS – дополнительные приложения для мультимедийных систем. Многие современные автомобили имеют на борту полнофункциональные мобильные операционные системы, которые позволяют узнавать погоду, информацию (с сообщениями) и даже выводить на экран социальные приложения, такие как Twitter
  • AUX/USB-входы для дополнительного источника звука (смартфон, планшет, портативный плеер и т. д.)
  • BALANCE – регулятор громкости между боковыми колонками автомобиля – справа/налево
  • BAND – изменение диапазона радиоволн
  • BLUETOOTH – беспроводная связь аудиосистемы с другим устройством. Позволяет подключать устройства громкой связи, телефоны и т. д., чтобы мы могли не только безопасно выполнять телефонные звонки, но и в новых автомобилях получать и отправлять sms, воспроизводить музыку на автомобильной аудиосистеме с телефона или совместно использовать Интернет с различными службами в автомобиле
  • CD-проигрыватель компакт-дисков. Что интересно, в некоторых современных автомобилях уже может быть недоступно. Некоторые производители решили отказаться от компакт-дисков в пользу воспроизведения музыки по Bluetooth или с жестких дисков, установленных в машине
  • DAB – цифровое радио (более высокое качество радиотрансляции)
  • DISP-дисплей выключен (затемнение экрана в основном необходимо во время поездок в ночное время)
  • FADER – регулятор баланса звука вперед/назад
  • FM/AM – диапазон радиоволн
  • INFO – дополнительная информация об источнике звука (список дорожек, названия песен и т. д.)
  • MEDIA/SOURCE – переключение источников звука. Это решение можно найти в новых автомобилях, которые оснащены различными возможностями воспроизведения, например, USB, через который мы подключаем флеш-карту (USB-флешка), или телефон, AUX-IN, или линейный аудиовход, или вышеупомянутый Bluetooth
  • MENU/HOME – возврат в главное меню
  • NAV/NAVI – включить навигацию
  • PHONE – переключение режима громкой связи Hands-Free Phone или переход в меню настроек подключения мобильного устройства к машине. Эта функция наиболее распространена в автомобилях, оснащенных Bluetooth. Это кнопка в некоторых машинах либо соединяет телефон с машиной по беспроводной связи (если подключение не произошло автоматически), либо разрывает соединение
  • RADIO – включение радио
  • RDS – отображение названия радиостанции, названия музыкальной дорожки, коротких текстовых сообщений от радиостанции
  • SEEK – поиск предустановленных радиостанций
  • SOUND – настройки частот звука (низкий, высокий, средний).В простых версиях с помощью этой функции мы попадаем в простое меню. В более новых автомобилях с более обширными и сложными аудиосистемами можно полностью управлять эквалайзером и его различными предустановленными настройками. Во втором случае здесь также можно найти опции, соответствующие ранее упомянутым BALANCE и FADER
  • TA/TP – информация о трафике. Это одна из самых интересных функций, которую используют не все. Многие люди просто не знают, что такое TA/TP. Здесь мы активируем дорожные объявления, которые транслируются некоторыми радиостанциями, обычно через регулярные промежутки времени. Когда радио начинает передавать сообщение, наш приемник автоматически переключается на данный канал. Это связано с тем, что прослушиваемая нами в настоящий момент программа прерывается. Многие водители отключают эту функцию именно по этой причине. Не всем нравится, когда радиоприемник автоматически выключает нашу любимую станцию. Но иногда эта оперативная информация может быть очень полезной
  • TUNE – поиск радиостанций по частоте
  • VOL – регулятор громкости

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

Блокирующая обработка тактовой кнопки для Arduino. Настолько полный гайд, что ты устанешь его читать

image

В одной из своих прошлых статей я писал про подключение тактовой тактильной кнопки. И, казалось бы, такой простой вопрос, вызвал «бурю» в комментариях. Публика разделилась на два лагеря: на тех, кто все знает, но обычно молчит; и тех, кто не знает, и стесняется спросить. А я так и не понял, к какому лагерю отношусь!

Поиски в интернете по запросу «программирование кнопки для Arduino» выдает весьма противоречивый контент. Где-то код очень крутой, но из-за скудного описания не понятный. А где-то код очень простой, и от того не понятно, что с ним можно делать.

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

Вот я и решил собраться с мыслями и обобщить свой опыт программирования обработчика кнопки для Arduino. Если вам интересно пополнить/проверить свои знания в данном вопросе, ну или проверить мои знания, то приглашаю под кат.

Дисклеймер. Текст рассчитан на публику, которая только начинает познавать азы программирования контроллеров Arduino. Запрещено к просмотру людям с ослабленной психикой или психикой с долголетней инженерной выдержкой и беременным женщинам (это так, на всякий случай, а то мало ли… британские ученые пока до исследований на эту тему не добрались). Материал предназначен исключительно для просмотра лицам, не достигшим 21 года.

❯ Вступление

Для экспериментов я буду использовать плату Arduino Uno. Программировать буду в Arduino IDE и для отладки использую ISIS Proteus 8.6. Это практически стандартный набор для начинающих любителей микроконтроллеров.

Функции для обработки кнопки, как и любые другие функции, могут быть блокирующими и неблокирующими.

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

О подключении кнопки к Arduino вы можете почитать в одной из моих прошлых статей. А теперь погнали программировать.

Блокирующий обработчик кнопки

Рассмотрим самый простой способ обработки кнопки, который можно использовать при реализации линейных алгоритмов. Для этого предлагаю собрать простую схему. Подключите кнопку между цифровым входом 2 платы Arduino Uno и общим проводом GND, как показано на рисунке. Для отладки кода и демонстрации его работоспособности я буду использовать терминал. При моделировании в Proteus для этого нужно добавить виртуальную модель терминала. При физических экспериментах можно воспользоваться терминалом в Arduino IDE.

image

Для примера я напишу программу, которая будет выводить в терминал надпись «кнопка нажата» или «кнопка не нажата» при соответствующих событиях. Обобщенный алгоритм этой программы можно изобразить следующим образом.

image

Для начала, в функции «setup()» настраиваю порт для управления кнопки и запускаю USART для передачи данных со скоростью 9600bps. Номер цифрового порта Arduino, к которому подключена кнопка, для удобства программирования назову «BUTTON_INPUT«.

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

image

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

Обратите внимание, что при выполнении кода из данного примера, текст будет «сыпаться» в терминал непрерывно. Такой способ обработки кнопки не всегда удобен.

❯ Обработка отдельных нажатий кнопки

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

image

Для реализации данного алгоритма обработки кнопки я модифицирую текст программы в функции «loop()» следующим образом:

При выполнении полученного примера программного кода в Proteus, текст в терминал действительно будет выводиться однократно при каждом отдельном нажатии на кнопку. Но вот, если попробовать выполнить программу в «реальном» железе, то при каждом нажатии кнопки в терминал может выскочить одновременно несколько строк текста.

❯ Защита от дребезга контактов

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

image

Самым простым способом избавиться от дребезга контактов в нашей программе является использование задержки времени. Задержка времени вводится сразу после первой фиксации замыкания кнопки. Длительность задержки подбирается таким образом, чтобы за ее время все переходные процессы гарантированно завершились. После чего кнопка опрашивается повторно. На практике я обычно использую задержку в 50мс100мс.

image

Макроопределение «#define BUTTON_PROTECTION 50» лучше разместить в самом начале программы. Величину задержки можно подобрать по своему вкусу.

Если произошло нажатие кнопки, то при первом замыкании контактов кнопки, условие первого оператора if будет истинным. Затем выполнится задержка, за время которой дребезг контактов должен прекратиться. После чего сработает второй оператор if, и можно считать, что кнопка сработала.

image

Если кнопка не была нажата, а произошел случайный дребезг ее контактов, то после выполнения задержки времени второй оператор if не сработает. А значит, обработка нажатия кнопки не произойдет.

image

❯ Пишем функцию для обработки кнопки

Для удобства использования полученного кода, я размещу его в функцию «get_button()«. Функция будет возвращать значение «buttonPress» при нажатии кнопки, и «buttonNotPress» — если кнопка не нажата.

Для проверки работоспособности функции можно написать следующий код, который будет выводить в терминал сообщение «кнопка нажата».

Особенность работы функции «get_button()» заключается в том, что теперь она обрабатывается не по нажатию, а когда ее отпустили. На самом деле такое часто бывает. К примеру, кнопка блокировки экрана на большинстве смартфонов работает именно так. «Крестик» в верхнем углу вашего браузера тоже закрывает окно, когда вы отпустите кнопку мыши, а никогда нажмете на нее.

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

❯ Обработка длинного и короткого нажатия кнопки

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

В общем-то, длинное и короткое нажатие кнопок принципиально отличается временем, в течение которого кнопка зажата. И наш алгоритм должен это время учитывать. Обратите внимание на графики. Фактически, наша программа должна различать три интервала времени: время дребезга, время короткого нажатия и время длинного нажатия. Для удобства использования такой кнопки, следует сделать разницу между этими интервалами побольше.

image

Алгоритм работы функции «get_button()» нужно изменить. Для измерения времени нажатий кнопки я использую цикл while, в котором с периодичностью в 10мс будет увеличиваться переменная-счетчик.

Дискретность измерения времени нажатия кнопки в 10мс я считаю оптимально. Это дает достаточную точность измеренного интервала. Если увеличить задержку, то это приведет к дополнительной потере времени в момент отпускания кнопки. Ну а чаще измерение проводить наверное ни к чему. В общем, я обычно обрабатываю нажатие кнопки с интервалом в 10мс, и этого всегда было достаточно.

После того, как кнопка будет отпущена, алгоритм сравнит время с заданными интервалами и вернет в программу соответствующий код.

image

В тексте программы я допишу необходимые константы для обозначения интервалов времени и добавлю коды, которые будет возвращать функция «get_button()«.

Далее перепишу функцию «get_button()».

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

❯ Обработка нескольких кнопок

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

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

Для удобства, верхнюю кнопку назовем SB1 (вход 3), а нижнюю — SB2 (вход 2).

image

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

Далее исправлю перечисление «ButtonResult«, добавлю в него коды для нажатий первой и второй кнопки.

Теперь в функции «setup()» настрою выходы Arduino на ввод с внутренним подтягивающим резистором для обеих кнопок, используя новые макро-имена.

Самым простым и очевидным для обработки двух кнопок будет продублировать код из первого примера в функции «get_button()«, и подправить в нем новые имена кнопок.

В фоновой программе допишу оператор switch так, чтобы при нажатии кнопок SB1 и SB2 в терминал выводились соответствующие сообщения.

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

Проблема с обработкой одновременного нажатия нескольких кнопок

Но все таки, если вам каким-то магическим образом удастся нажать обе кнопки совершенно синхронно, то их обработка будет выполнена в порядке приоритета, обусловленного порядком выполнения операторов if. Также этот алгоритм не заметит нажатие кнопки SB2, если оно будет менее продолжительным, чем нажатие кнопки SB1.

image

В случае, если кнопки были нажаты одновременно, и нажатие кнопки SB2 происходило дольше, то возникнет неоднозначная ситуация. Обработка кнопки SB1 произойдет корректно при первом вызове функции «get_button()«. А при следующем вызове функции, алгоритм примет «хвост» графика за отдельное нажатие кнопки SB2. И если этот «хвост» окажется короче паузы для защиты от дребезга, то функция не заметит нажатия кнопки SB2. Чтобы функция заметила нажатие кнопки SB2, ее нужно отпустить значительно позже, чем SB1.

image

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

Увеличиваем количество кнопок

А как быть, если нужно еще увеличить количество кнопок? Еще больше дублировать код? Пожалуй, это не самая лучшая идея. Программа станет громоздкой, и ее сложно будет даже читать. Попробуем решить эту задачу. Для этого дополним схему еще двумя кнопками, пусть теперь их будет четыре.

image

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

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

image

Первым делом я дополню перечисление «ButtonResult» кодами для новых кнопок. Эти коды будет возвращать функция «get_button()«.

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

Для удобства обращения к кнопкам, я перечислю их имена в соответствии с позиционными обозначениями на схеме. Это, конечно, не обязательно, но мне так привычнее. Имена «ButtonNamesStart» и «NumberOfButtons» будет удобно использовать для работы в циклах.

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

Когда параметры кнопок определены, выполню инициализацию портов в функции «setup()«. Цикл for поочередно выбирает номера портов, к которым подключены кнопки, из массива «button«.

Остается дописать функцию «get_button».

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

На всякий случай полный текст программы я спрятал под спойлер. Вы можете скопировать его в Arduino IDE и поэкспериментировать с ним.

❯ Обработка нескольких кнопок с разной длительностью нажатия

Повторить тот же «финт ушами» с дублированием кода для обработки каждой кнопки, в данном случае не получится. Если использовать цикл while, как в прошлом примере обработки кнопки с разной длительностью нажатия, при нескольких одновременно нажатых кнопках результат работы кода будет крайне неудовлетворительным.

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

image

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

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

Количество кнопок в схеме увеличилось, каждая кнопка теперь может иметь два состояния: короткое и длинное нажатие. Чтобы можно было все это в программе различить, дополню перечисление состояний «ButtonResult » новыми кодами.

Перечисление «ButtonNames» имен кнопок остается без изменений из прошлого примера.

А вот структура «ButtonConfig» с описанием параметров кнопок изменилась. В ней добавились поля «shortPressIdentifier» и «longPressIdentifier» для хранения кодов нажатия, поле «result» будет использовано для промежуточного хранения результата нажатия кнопки, поле «pressingTime» будет использовано для измерения времени нажатия кнопки.

Далее я заполняю массив «button» для каждой кнопки. На этом этапе важно не перепутать номера цифровых портов. И это является главным преимуществом. Если нужно переназначить кнопки, допустим их порядок изменился при трассировке платы, или еще по каким-то причинам, то не нужно лезть глубоко в код, достаточно переставить цифры при инициализации одного массива.

Следующий код может показаться сложным, но это на первый взгляд. Присмотритесь к нему повнимательнее. В отличие от многих примеров для Arduino, где используют односложные имена типа: x, y, z, a, d, c и тому подобное, я люблю длинные и емкие имена. Мне так проще. Не нужно их запоминать, достаточно помнить к чему относится имя. К примеру, для кнопок все имена начинаются со слова «button», для интервалов времени — со слова «time», и так далее. При наборе кода я пользуюсь функциями автоматического ввода, нажимаю комбинацию клавиш на клавиатуре, потом просто читаю имена в списке и выбираю подходящее. И итоговый код удобно читать, с хорошо подобранными именами он практически не нуждается в комментариях.

Чтобы не мучиться с do-while и не терять лишнюю задержку в 10мс при каждом вызове обработчика клавиатуры, я разделил код на две функции. Функция «get_button()«, как и прежде, будет основной, ее будем использовать при необходимости опросить кнопки. А функция «checkingButtonStatus()» будет оценивать состояние кнопок только в текущий момент времени. Функция «get_button()» будет вызывать функцию «checkingButtonStatus()» с интервалом в 10мс, пока хотя бы одна кнопка остается нажатой.

Переменная «check» используется как флаг, показывающий было нажатие хотя бы одной кнопки, или нет. Если при обработки кнопок ни одна не была нажата, то значение переменной останется равным «buttonNotPress«, в противном случае в нее будет записано значение «buttonPress«.

Цикл «for(uint8_t num = ButtonNamesStart; num < NumberOfButtons; ++num)» поочередно перебирает все кнопки с помощью переменной-счетчика «num«.

В теле цикла оператор «if(digitalRead(button[num].pin) == LOW)» проверяет состояние кнопок. И если кнопка нажата, то ее счетчик времени «button[num].pressingTime» увеличивается на величину базового интервала 10мс.

Если кнопку отпустили, то происходит оценка интервала, накопленного в «button[num].pressingTime«. Результат проверки записывается в «button[num].result«, чтобы потом вернуть код наиболее приоритетной кнопки. После чего «button[num].pressingTime» сбрасывается для следующего измерения.

После того, как все кнопки проверены, функция «checkingButtonStatus()» возвращает свой результат: «buttonNotPress» — если нажатий не было, или «buttonPress» — если хотя бы одна кнопка нажата.

Теперь посмотрим, что у меня получилось с функцией «get_button()«.

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

Далее, цикл «while(checkingButtonStatus() == buttonPress)» вызывает функцию «checkingButtonStatus()«, пока хотя бы одна кнопка остается нажатой.

Когда не остается ни одной нажатой кнопки, цикл «for(uint8_t num = ButtonNamesStart; num < NumberOfButtons; ++num)» проверяет результат обработки для каждой кнопки. Если кнопка нажата, то ее код помещается в переменную «temp«, а содержимое «button[num].result» и «button[num].pressingTime» сбрасываются, чтобы не помешать обработке кнопок в следующий раз.

Таким образом получается, что приоритет обработки кнопки определяется ее порядковым номером. При одновременном нажатии нескольких кнопок, функция «get_button()» вернет код той кнопки, порядковый номер которой больше остальных.

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

Если вам интересно протестировать получившуюся программу, можете скопировать ее код целиком.

❯ Как получить код нескольких одновременно нажатых кнопок

Ну и конечно же, статью нельзя было бы считать полной, если бы мы не заставили функцию «get_button()» оповещать фоновую программу об одновременном нажатии нескольких кнопок. Благо, что код из предыдущего примера для этого не требует серьезных доработок.

Так как в нашем примере используется 4 кнопки, а каждая кнопка может возвращать два состояния: короткое и длинное нажатие. То можно результат обработки такой клавиатуры упаковать в один байт. Каждый бит в этом байте будет обозначать соответствующее состояние для каждой кнопки. Нулевой бит будет кодировать короткое нажатие кнопки SB1. Первый бит — длинное нажатие SB1. Ну и так далее, как показано на рисунке.

image

Чтобы реализовать эту идею, я подправлю перечисление «ButtonResult«. Пусть теперь коды кнопок будут соответствовать битовым маскам.

Также подправлю функцию «get_button()«, чтобы она возвращала значение в формате одного байта. Переменная «temp» теперь тоже будет иметь размер одного байта для хранения комбинации битовых масок.

Дальше подправлю одну строчку в теле цикла «for».

Вместо того, чтобы присвоить переменной «temp» код нажатой кнопки, будет производиться логическое умножение значения, которое уже накопила переменная «temp» на битовую маску, полученную при нажатии кнопки.

Предположим, что одновременно были нажаты кнопки SB3 и SB4, и переменная «temp» уже запомнила код короткого нажатия SB3. Тогда в результате логического умножения содержимого переменной «temp» на битовую маску кода короткого нажатия SB4, в переменной «temp» изменится только 6-ой бит. А все остальные биты останутся без изменений.

image

Проверку нажатия кнопок в фоновой программе тоже придется изменить. Больше мне оператор switch не подойдет. Я буду использовать оператор if, в условиях которого буду производить логическое сложение значения, полученного от функции «get_button()» и маски соответствующего кода кнопки. Для короткого нажатия кнопки SB1 код будет выглядеть вот так:

Если значение, которое передала функция «get_button()» содержит единицу в нулевом разряде, то результат логического сложения будет отличаться от нуля, т.е. будет истинным. Если результат работы функции содержит в нулевом разряде 0, то получим ноль, т.е. ложное значение.

image

Полный текст программы с этими изменениями положу под спойлером, вдруг кому пригодится.

❯ Заключение

«Внимательный читатель» может спросить меня: зачем все эти навороты с массивами структур и прочими «кренделями», не проще ли сразу писать классы и использовать прерываний? И это справедливый вопрос.

Отвечу на него так:

1. Прежде чем вникать в прерывания и особенности построения дискретных алгоритмов, все таки стоит прочувствовать на себе все тяготы линейных программ.
2. Классы и в целом объектно-ориентированная парадигма программирования — это достаточно сложно для новичков… и иногда не только для новичков. И, по моему мнению, ООП больше подходит для написание больших проектов на ПК и далее.… хотя, всего каких-то два десятка лет назад некоторые товарищи (стыдливо отвожу взгляд в сторону) ни как не хотели слазить с ассемблера.

Если вам понравилась эта статья, то в следующей вы можете почитать про неблокирующий способ обработки кнопки

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *