UART, сервоприводы (продолжение)

МикросервоприводВ этой статье мы рассмотрим несколько тем. Сначала, мы вернемся на мгновение к UART, а затем обсудим новые функции управления. Наконец, найдем практическое применение сервоприводу.

Перед чтением убедитесь, что вы знакомы с основами, изложенными в предыдущих статьях на нашем сайте, посвященным Arduino!

Представление чисел в терминале

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

Информация, отображаемая в термине, удобочитаема, поскольку Arduino преобразует ее в коды ASCII . Фактически, четные числа отправляются как текст.

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

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

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

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

Точность неполных чисел

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

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

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

Выберите монитор порта, выполнение указанной выше программы должно иметь следующий эффект:

Точность отображаемых чисел
Точность отображаемых чисел

Как видите, если мы отправляем число, дополнительным параметром может быть цифра, которая определяет точность, с которой должны отображаться отображаемые значения. Следует помнить, что переменные типа float представлены не более чем 7 цифрами — независимо от того, сколько знаков находится за десятичной точкой и перед ней. Например:

  • float number1 = 0.123456 — правильно
  • float number2 = 12345.6 — правильно
  • float number3 = 123.456 — правильно
  • float number4 = 1234567.8 — неверно
Для большей точности (15 цифр) используйте переменные типа double!

Вернемся на мгновение к указанной выше программе, а именно к этой строке:

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

Однако ВНИМАНИЕ! Здесь может быть очень серьезная опасность!

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

К нашему удовлетворению, на экране появится очень точное значение:

3,1415927410125732421875

Но вернемся к максимальной точности, которую предлагают нам микроконтроллеры, оказывается, что константа PI имеет свойства переменной float, т.е. занимает всего 7 цифр! Каждое последующее неверно, потому что наиболее точная двоичная запись нецелых чисел не дает соответствующего «истинного числа Пи».

Список ниже — это отображаемое нами число и реальный Пи:

3.141592 74101257324218750
+3,14159265358979323846264

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

Текст в одну строчку

До сих пор каждое значение, отображаемое в терминале, отображалось с новой строки. Это было ясно, но не всегда полезно. Что, если мы хотим отобразить несколько переменных и текстов рядом друг с другом? Здесь двойная функция println — это print (без окончания ln).

Она имеет те же значения, что и println, использовавшийся до этого. За исключением того, что каждое отправленное значение отображается в новой строке. Пример:

Программа не впечатляет своей работой, но демонстрирует самое главное (без новой строки):

Текст без новой строки
Текст без новой строки

Как мы можем перейти на новую строку в выбранном месте? Есть три способа:

Последний, безусловно, самый интересный. Появится новый символ \n. Он встречается не только в Arduino и знаменует переход на новую строку. Как видите, это очень удобно, т.к. позволяет в любой момент разорвать линию.

Есть ли другие полезные символы этого типа? Да! Возможность использования табуляции (отступы, большие пробелы) также могут быть полезны для форматирования отображаемого текста. Если вы хотите перейти вправо, вместо неудобного ввода нескольких пробелов следует использовать символ \t — tab.

Новая информация о UART на практике

Пришло время применить изложенную выше информацию на практике. Цель нашей программы — измерить напряжение на выводе A5 и затем отобразить его на выводе. Однако, на этот раз недостаточно вывести число в десятичном формате. Дополнительно — в одну строку — выводятся значения в HEX, OCT и BIN. Конечно, все должно быть красиво отформатировано!

Для начала нужно собрать простую схему. Мы использовали потенциометр, чтобы изменить напряжение. Впрочем, здесь можно поставить делитель напряжения с фоторезистором. Если вы не помните, как это сделать, читайте статью «UART — связь с ПК, переменные«.

Потенциометр подключен к выходу A5
Потенциометр подключен к выходу A5

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

После запуска программы в терминале мы должны наблюдать красиво отформатированные значения с АЦП, показанные в различных системах исчисления:

Arduino - другое представление чисел
Arduino — другое представление чисел

Мы призываем вас поэкспериментировать самостоятельно. Это идеальная возможность попрактиковаться в ручном преобразовании чисел в разные системы. На этом мы заканчиваем часть UART, и нам пора двигаться дальше.

Домашнее задание 5.1

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

«Фоторезистор 1: XXX, фоторезистор: XXX, потенциометр: XXX, кнопка нажата XX раз»

Где, конечно, вместо X появляются правильные значения.

Оператор управления переключением

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

Чтобы понять оператор switch, мы будем использовать пример, который затем будет решен двумя способами — традиционным и новым. Допустим, мы хотим написать программу, которая считывает значение с АЦП и затем отправляет его нам в виде десятичного, шестнадцатеричного, восьмеричного или двоичного числа. Все зависит от нашего выбора.

Обладая полученными знаниями, мы могли бы написать программу, используя следующие условия:

Выполнимо? Да. Комфортно? Не очень, особенно если условий было намного больше или внезапно необходимо было бы изменить условия. На помощь приходит новая функция по управлению switch-case. Она выглядит следующим образом:

Вначале мы пишем ключевое слово switch, затем в скобках указываем переменную, которую хотим проверить. В примере, аналогичном предыдущему, это будет:

Затем открываем фигурные скобки. Внутри них мы можем ввести любое количество условий, которые будут последовательно проверяться. Мы делаем это, написав слово case, и после пробела вставляем значение, которое должно быть равно проверяемой переменной. Все завершаем знаком двоеточия «:».

Если условие выполнено, то код будет выполняться с момента условия до ближайшего слова break, которое приведет к выходу из всего коммутатора. Когда условие не выполняется, часть кода игнорируется, и микроконтроллер переходит к проверке следующего условия (case).

Оператор switch-case полезен, когда мы хотим проверить, равны ли значения!

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

Предупреждение: оператор управления switch работает только путем сравнения чисел. Следовательно, в этом примере, буквы, которыми мы управляем: d, h, o, b, должны рассматриваться не как буквы, а как коды ASCII . Написание буквы в одинарных апострофах рядом с регистром приводит к тому, что они рассматриваются как коды ASCII.

Более того, вместо ранее использовавшейся функции чтения данных:

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

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

Домашнее задание 5.2

Вернитесь к домашнему заданию 2.4, которое находится в этой статье, и переделайте программу на этот раз с помощью оператора switch.

Сервопривод на практике — световой индикатор

Пришло время обещанного использования сервопривода на практике. В настоящее время все больше и больше информации отображается в цифровом виде, то есть на дисплее.

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

Аналоговые индикаторы
Аналоговые индикаторы

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

Схема сборки готового устройства следующая:

Схема сборки
Схема сборки аналогового солнечного индикатора

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

Будьте осторожны при подключении сервопривода и аккумулятора, чтобы ничего не повредить!

Вторая часть схемы предназначена для подключения резистора и фоторезистора в делителе напряжения. Более подробную информацию по этому поводу можно найти в статье про АЦП в разделе Arduino.

Механическая часть проекта

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

Неаккуратное использование термоклея может привести к выходу из строя сервопривода!
Циферблат без указателяВид сзади
Аналоговый циферблат без указателяАналоговый циферблат вид сзади

Качество изготовления не самое высокое, но это всего лишь эксперимент, а главное — чтобы все работало:

Аналоговый индикатор
Готовый аналоговый индикатор

Программа относительно проста. Ее задача — периодически измерять свет, падающий на фоторезистор, и контролировать отклонение сервопривода. Для этого использовались ранее известные функции:

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

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

Каждый должен откалибровать программу для своих условий!
(описание ниже)

Программа очень простая, поэтому механизмов автокалибровки нет. Следовательно, через UART он отправляет текущее значение, считанное с датчика освещенности, на компьютер. Самая быстрая калибровка может заключаться в том, какое наименьшее и наибольшее значение наблюдается при закрытии и освещении датчика. Затем включите их в эту строку:

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

Аналоговый индикатор на Arduino
Аналоговый индикатор с использованием Arduino

Мы рекомендуем вам изменить настройки и протестировать новые программы. Однако мы не советуем начинать подачу света слишком быстро. Это может вызвать проблемы или повредить относительно хрупкий сервопривод. Мы предлагаем не опускаться ниже 300 мс, установленных в этой строке:

Домашнее задание 5.3

Настройте схему аналогового индикатора. Попробуйте добавить механизм калибровки. Найдите еще одно практическое применение такому макету!

Вывод

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

С Уважением, МониторБанк

Оставьте комментарий

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