UART — связь с ПК, переменные

UARTРассматриваемая нами плата Arduino позволяет использовать множество интерфейсов связи. Благодаря им, созданные конструкции и проекты могут связываться с другими системами, датчиками или компьютером.

В этой статье мы будем иметь дело с UART. Это простой и очень популярный последовательный интерфейс, особенно, при общении с компьютером.

Как работает UART? Немного теории

Принцип работы UART основан на последовательной отправке битов, которые затем объединяются в информацию. Один кадр (байт) данных передается в следующей форме:

Пример передачи UART
Пример передачи UART

Передача начинается со стартового бита, обозначенного на рисунке как BS. Это всегда логический нулевой бит. Затем, в зависимости от конфигурации, 7, 8 или 9 битов данных (здесь обозначенных как B0-B7) следуют друг за другом, что является информацией, которая должна быть отправлена. Стоп-бит (обозначенный здесь как бит BK) является логическим единичным битом — он сообщает об окончании передачи.

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

При использовании UART в Arduino нас интересуют два контакта:

  • Tx для отправки данных (вывод 1 на Arduino),
  • Rx для приема данных (вывод 0 на Arduino).

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

Если вы хотите узнать больше о UART, прочтите также статью: COM-порт и интерфейс USART — связь с ПК.

Компьютер, с которым мы хотим установить связь, также должен быть оснащен соответствующим интерфейсом. К сожалению, производители ПК перестали выводить последовательный порт в стандарте RS-232, который использовался в большинстве компьютеров несколько лет назад.

Остается общение по USB. К сожалению, это довольно сложная задача. Поэтому чаще всего любители используют преобразователи UART <-> USB, которые значительно упрощают работу. При использовании Arduino вам не о чем беспокоиться. Такой преобразователь уже встроен в эту плату.

Возможность подключения по USB
Возможность подключения по USB

Поэтому нам достаточно подключить компьютер к Arduino через USB-кабель (тот самый, который используется при программировании).

Перейдем к практическим примерам. Наши две программы потребуют только подключение Arduino через USB к компьютеру.

Первая программа на Ардуино

Цель следующей программы — регулярно отправлять текст на ваш компьютер:

После закачивания указанной выше программы ничего не произойдет. Чтобы увидеть ее работу, в меню Arduino выберите: Инструменты -> Монитор порта. Это откроет новое окно. Окно называется терминал. На этом этапе мы можем наблюдать, что отправляется в / из Arduino через COM-порт, то есть через наш UART.

Важно, чтобы терминал работал с правильной скоростью на COM-порту, к которому подключен Arduino! Настройки скорости можно найти в правом нижнем углу терминала.

Работа программы на практике:

Текст отправлен в терминал
Текст отправлен в терминал

Перейдем к анализу программы. Первое, что нужно сделать, это установить скорость передачи. Для этого используется функция Serial.begin (скорость), где определяем скорость передачи. В данном случае это 9600 б/сек. А функция — Serial.println (val) используется для отправки строки, где val — это строка или число.

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

Мы также можем наблюдать работу передачи на диодах, встроенных в Arduino (обозначенных как Tx и Rx)! Они светятся, когда данные передаются на / с нашу плату.

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

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

Взаимодействие с программой

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

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

Используя ранее полученные знания, вы можете написать программу, которая включает светодиод при открытом окне. Но попробуем расширить нашу программу. Мы оснастим Arduino кнопкой (имитирующей датчик в оконной раме) и двумя светодиодами (зеленым и красным).

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

Когда окно закрыто (кнопка нажата), загорается зеленый светодиод. Когда мы разрываем цепь (перестаем нажимать кнопку), должен загореться красный светодиод, а в терминале должно читаться сообщение «Внимание! Тревога! Окно открыто!».

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

Можем ли мы улучшить что-то еще в приведенном выше коде? Исправлять нельзя, но, конечно, можно сделать изящнее.

#define

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

На помощь приходит директива #define. Она позволяет нам определить символ, который будет заменен перед компиляцией в любом месте программы. Например:

Поставив в начале программы строку: # define ledPin 8, мы делаем так, чтобы перед компиляцией каждое вхождение строки ledPin было преобразовано в 8. Конечно, заменяемое имя может быть другим, важно, чтобы оно было уникальным и помогало вам при написании длинных программ.

После строки, начинающиеся с #define, точка с запятой не ставится!

Ниже представлена ​​окончательная, измененная версия программы нашего оконного оповещателя:

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

Переменные, как универсальные ящики

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

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

Вот список наиболее важных типов данных:

Максимальные значения, которые мы можем записать в переменную, зависят от схемы, которую мы программируем. Вышеуказанные значения относятся к Arduino UNO. Особое внимание уделяется переменным типа long и float .

Чаще всего вы будете использовать такие переменные, как:

  • boolean
  • int
  • string

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

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

String — это строка символов, говоря простыми словами, мы сможем хранить строки в переменных этого типа. Слова, предложения, сообщения.

Переменная на практике

Чтобы использовать переменную, мы должны объявить ее, т.е. сообщить компилятору ее тип и имя. К счастью, нам не нужно беспокоиться о выделении под него определенного места в памяти микроконтроллера. Однако, если вам интересно, как все работает внутри, обязательно прочтите статью: Микроконтроллер AVR- все о его работе.

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

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

Два вышеуказанных метода должны дать одинаковый результат. Однако первый вариант более безопасен, поскольку он присваивает переменной начальное значение сразу после ее создания. Второй метод теоретически должен также создавать переменную с начальным значением, равным нулю. В 99,99% случаев так и будет. Однако рекомендуется вручную устанавливать начальные значения прямо в объявлениях.

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

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

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

создаем переменную:

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

Самое главное, чтобы программа была удобочитаемой.

Кстати, имена переменных не могут содержать пробелов!

Использование переменных

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

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

  1. Переход в область памяти, которую мы объявили как переменную счетчика, а затем отправляется найденное там значение через UART.
  2. Увеличивается текущее значение счетчика переменных на 1.
  3. Ожидает 100 мс (для лучшей видимости) и возвращается к началу цикла.

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

С математической точки зрения, знак «=» означает равенство, указанная выше строка не должна работать. Однако в программировании знак «=» указывает на назначение. На практике под приведенным выше кодом следует понимать следующую операцию:

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

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

Запуск первой программы с переменной
Работа программы с переменной

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

Что произойдет, если вы переместите объявление переменной счетчика в loop () ?

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

Как уже упоминалось, у переменных есть свои ограничения. Измените объявление счетчика переменных с int на byte, которое может содержать числа в диапазоне 0-255. Что произойдет, если это значение будет превышено? Внимательно проследите за отображаемыми результатами!

Двусторонняя передача с Arduino

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

Задача первой программы — «прислушаться» к нашему имени. Когда мы его отправляем, Arduino должен приветствовать нас сообщением «Hello Name!», куда, конечно же, будем писать свое имя.

В начале, мы объявляем receivedData переменную, в которой будет скопирована последовательность принятых символов. Встречаем новую функцию: Serial.available (). Эта функция возвращает количество байтов, которые были получены и ожидают обработки Arduino.

В случае, когда данные будут доступны (их будет больше 0) — они начнут записываться в переменную receiveData. Это делается с помощью функции Serial . readStringUntil, которая копирует данные из буфера до тех пор, пока не встретится знак завершения (в данном случае «\ n» — символ новой строки).

Введите свое имя и нажмите ОтправитьЧерез некоторое время нам ответит Ардуино
Введите свое имя и нажмите ОтправитьЧерез некоторое время нам ответит Ардуино

Взаимодействие со схемой — управление диодами через UART

Мы будем использовать возможность отправки текста в Arduino для управления светодиодами. Для этого подключите два светодиода, как показано на рисунке ниже (светодиоды на контактах 8 и 9).

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

Задача нашей программы — включить зеленый или красный светодиод на 1 секунду, при отправке соответствующей команды на Arduino. Готовая программа выглядит так:

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

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

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

Домашнее задание 2.5*

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

Вывод

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

Прочитав эту статью, каждый сможет написать программу, которая легко будет взаимодействовать с компьютером. Данная статья получилась относительно простой, но не торопитесь. Делайте все задания — ОБЯЗАТЕЛЬНО!

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

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