Взаимозаменяем потенциометр, джойстик и энкодер в схемах на Arduino (Часть I)

30 ноября 2020

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

Приветствую всех поклонников и поклонниц Arduino на сайте магазина Amperkot.ru. С этой статьи я начинаю интересную тему “Взаимозамена потенциометра, джойстика и энкодера в различных проектах”. Этот большой и структурированный объем материала будет полезен начинающим и более продвинутым пользователям.

На примере простых проектов будет разобрано и изучено много полезного материала, но самое главное, что после прочтения всего цикла, 95% из Вас будут знать намного больше, чем ранее. Ваш покорный слуга будет намеренно моделировать проблемы (которые могут встретиться и в реальной жизни), чтобы подтянуть гибкость и остроту мышления читателя в теме Arduino!

В этом цикле статей Вас будут ждать:
- Интуитивно понятное объяснение основ написания скетчей для Arduino;
- Разбор схем подключения;
- Поиск интересных и самых разнообразных способов решения проблем в проектах на аппаратном, программном и “колхозном” уровнях.

Введение

Итак, потенциометр, джойстик и энкодер. Всё на первый взгляд просто.

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

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

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

А теперь кратко о трех наших героях!

Немного теории

Потенциометр — он же переменный резистор, он же “какая-то крутилка с ручкой”, предлагает нам пропорционально изменять сопротивление внутри устройства в зависимости от положения ручки. На его выходе получаем напряжение (в зависимости от подключения контактов питания, в крайних положениях ручки, получаем значения 0 и 5 вольт, так как плата Arduino выдает максимальное напряжение 5 вольт) которое с помощью Ардуино преобразуется в цифровые значения от 0 до 1023. Оперируя ими, можно влиять на параметры различных устройств.

Энкодер — это уже крутилка с ручкой и кнопкой, но важным изменением в практическом смысле является то, что у потенциометра диапазон вращения ручки ограничен минимальным и максимальным значениями, а у энкодера ручка вращается безостановочно все стороны. В теоретическом плане тоже есть отличие — при изменении угла поворота ручки энкодера меняются значения двух сигналов, генерируемых устройством на выходах DT и CLC. Они сообщают контроллеру о направлении и скорости вращения ручки.

Джойстик — устройство для ввода данных по двум осям: OX и OY, а также с помощью встроенной кнопки. В состоянии покоя напряжение на этих контактах равняется 2,5 вольтам, а с помощью перемещению стика изменяется в диапазоне от 0 до 5 вольт. Основное отличие джойстика от энкодера и потенциометра — выходные значения не сохраняются, так как стик не фиксируется и всегда возвращается в исходное положение

Подготовимся заранее

Прежде, чем начать практическим путем получать полезные навыки, подготовим компоненты, которые нам понадобятся. Купить их Вы можете на сайте интернет-магазина Amperkot.ru по вполне себе демократичным ценам!

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

А если Вы живете в одной из двух столиц России: Санкт-Петербурге или Москве, то сможете получить необходимое в течение дня (самовывоз). Очень даже удобно!

Вот список компонентов, которые нам понадобятся в этих уроках:

- Плата Arduino Uno + usb кабель в комплекте для подключения к компьютеру
- Беспаечная макетная плата (число точек не принципиально важно)
- Потенциометр на 10кОм
- Модуль энкодера (либо обычный энкодер, но тогда будете дольше и усерднее его подключать к плате)
- Модуль джойстика
- Резисторы 220 Ом
- Резисторы 10 кОм
- Керамические конденсаторы на 100 мкФ (?)
- Перемычки “папа-папа” и “папа-мама” (по 20 штук каждого типа будет достаточно).
- Светодиоды 5 мм

А теперь к практике

Наша с Вами задача — научиться находить нестандартные выходы из любых проблем и не опускать руки, поэтому смоделируем эти самые ситуации и поработаем с кодом!

Пример 1.1: Регулировка яркости светодиода потенциометром

Практичнее всего в данном случае использовать потенциометр. Для начала подключим все по схеме:

Обратите внимание, что в схеме не используется подтягивающий резистор. Такие резисторы (чаще всего номиналом от 10 до 30 кОм) используются для уменьшения помех в данных, передаваемых через аналоговый сигнал. Но многие забывают, что в плату Arduino уже встроены такие резисторы на каждый контакт. В данной же ситуации использовать его нет смысла, так текущая задача не требуется высокой точности значений. Но в следующих частях этого большого ликбеза эта тема обязательно будет освещена!

Настало время написать код. В следующих нескольких абзацах я позволю себе написать небольшое руководство по структуре написания кода на Arduino, чтобы начинающие не чувствовали себя некомфортно:) Все, кто уже обладают этими базовыми навыками, — можете пропустить этот текст, либо постараться почерпнуть для себя что-нибудь новое.

Для начала посчитаем, сколько устройств ввода и вывода информации мы используем в нашей схеме: их два — переменный резистор и светодиод. Теперь обозначим их в коде.

Сделаем это с помощью констант (ячейки памяти в контроллере). Используя директиву #define, мы создаем ячейку памяти, в которой будет храниться значение пина платформы Arduino, которому соответствует подключенное устройство.

Чтобы понимать, где будет храниться информация, и легко к ней обращаться в будущем, назовем каждую из констант удобными словами (led, pot), а после оператора присваивания (‘=’) записываем данные, которые будем хранить в конкретной ячейке. В нашем случае, это номера пинов платы Arduino, к которым подключаются наши устройства. Выглядит это так:

Далее в коде идут две обязательные функции — void setup() и void loop(). В первой пишется то, что контроллер обработает только один раз (сразу после подачи питания), а во второй прописываются уже конкретные действия, которые мы хотим выполнять с нашими устройствами на протяжении всей работы кода. Код обрабатывается сверху вниз, однако после выполнения последней команды в void loop() контроллер возвращается в начало функции void loop() и продолжает выполнять те же самые действия в том же самом порядке. Так и проявляется цикличность. Не зря loop переводится с английского, как “петля”.

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

Теперь классифицируем устройства по их назначению: устройства ввода и вывода данных (относительно платы Arduino конечно же). Когда мы крутим ручку потенциометра, то мы лично изменяем значения на его сигнальном контакте, которые затем считываются на аналоговом пине и обрабатываются контроллером. Это те данные, которые поступают/вводятся в контроллер, а значит и потенциометр будет устройством ввода данных.

После кручения ручки контроллер должен посылать сигнал уже на светодиод, чтобы тот светился с определенной яркостью. Эти данные выводятся из контроллера. А значит светодиод — устройство вывода данных.

Оперируя этими данными, запишем назначение этих устройств в функции void setup (контроллеру достаточно один раз понять, с какими типами устройств он имеет дело, чтобы продолжить работу с ними). Делается это с помощью функции pinMode (номер пина с подключенным устройством, режим работы для данного пина). Для устройств ввода данных — INPUT, а для устройств вывода данных — OUTPUT.

В функции void loop() прописываем цикличные действия: считывание данных с контакта потенциометра, регулировка яркости светодиода.
Работу с контактами на плате Arduino можно преобразовать для лучшего понимания в такую простую схему:

Имеются два типа контактов: цифровые (могут выдавать только два значения: 1 и 0, как реле или выключатель) и аналоговые (диапазон значений от 0 до 1023). Есть еще ШИМ контакты (это некоторые цифровые контакты, но со встроенным аналого-цифровым преобразователем, обозначаются на плате вот таким значком ~): они могут работать в обоих режимах. Все зависит от того, как Вы это пропишете в коде.

Далее самые распространенные функции ввода (чтения) и вывода (написания команды) данных — Write и Read. Запомнить их очень просто: если мы хотим считать данные с пина контроллера, то иначе говоря, хотим прочесть их (как с открытой книги), а значит пишем после типа контакта (digital или analog) слово Read (с английского языка “читать”). В случае вывода данных можно представить, что мы прописываем команду нашему устройству сделать то или иное действие (в нашем случае — команда светодиоду включиться). Писать с английского языка “write”.

Так и получаются эти функции путем объединения двух различных слов: digitalWrite, digitalread, analogWrite, analogRead.

Для функций с чтением данных прописываем в скобках только один параметр (номер пина, с которого происходит считывание): analogRead (pot).

Для функций с выводом данных прописываем в скобках два параметра: номер пина и значение сигнала. Таким образом яркость светодиода будет настраиваться функцией analogWrite (номер пина, к которому подключен светодиод, логическое значение). Не забывайте, что для цифровых пинов допустимо на месте второго параметра писать значения 1 или HIGH (высокий логический уровень) и 0 или LOW (низкий логический уровень), а для аналоговых или цифровых с поддержкой ШИМ число от 0 до 255 (на выводе Arduino может генерировать только такой диапазон значений).

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

Чтобы эти данные было удобнее использовать в процессе работы кода, их нужно сохранить в новую ячейку памяти — переменную. Она создается также, как и константа, только вместо #define пишется тип переменной (который определяет ее размер). Какие бывают типы переменных можно посмотреть в любой табличке в Яндекс Картинках. Нам будет достаточно целочисленного типа int. Создадим переменную с названием val (от английского value — "значение") и присвоим ей значения с вывода потенциометра. Теперь у нас появилась ячейка, в которой будут храниться эти данные. В любой момент мы можем обратиться к ней, чтобы выполнить с данными какие-либо действия.

Так как на выходе Arduino может генерировать значения от 0 до 255, то нужно пропорционально уменьшить значения с потенциометра: уменьшить их в четыре раза. Полученный результат сохраним в новую целочисленную переменную "brightness". А затем значения из этой переменной выставим в качестве второго параметра в функции analogWrite (led, brightness) — теперь на пин, которому мы дали название led, подается напряжение от 0 до 5 вольт, которое пропорционально значения с потенциометра. Задача выполнена!

Пример 1.2: Регулировка яркости светодиода джойстиком

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

Будем считывать значения с джойстика по оси OX, а затем при помощи функции map() преобразуем их в значения для яркости светодиода в качестве параметра функции analogWrite(). Джойстик подключим без использования обвязки, так как в случае с джойстиком помехи в данных будут меньше, а в случае со светодиодом они роли не играют. Но Вы должны помнить об этом на будущее. Контакты с плавным напряжением подключим через резисторы. Схема подключения представлена на картинке ниже:

По такой же логике, как и в примере 1.1 напишем код. Получаем то, что на картинке ниже:

Здесь у нас также 2 устройства, но джойстик в отличие от потенциометра позволяет считывать значения с трех разных контактов (по оси OX, по оси OY и со встроенной кнопки), поэтому введем 4 константы. В остальном — всё то же самое.

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

Заключение первой части

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


Данная статья является собственностью Amperkot.ru. При перепечатке данного материала активная ссылка на первоисточник, не закрытая для индексации поисковыми системами, обязательна.


Поделиться: