Основы программирования, порты ввода-вывода

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

Arduino работает на языке C (Си), адаптированном к данной платформе. Эта статья познакомит вас с основами программирования на C и его практическим использованием на примере портов ввода-вывода.

Базовая структура программы Arduino

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

Внимание! Вы должны это помнить!
Мы помечаем комментарии символами « // ». То есть информация в строке, которая помогает человеку понять программу. Во время компиляции они игнорируются. Если вы хотите добавить более длинный комментарий, включите его / * в такие символы * /.

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

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

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

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

Функции — что они означают

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

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

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

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

Сосредоточимся на основных функциях в программах Arduino.

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

Функция loop (процедура) — это бесконечный цикл. Есть команды, которые следует зациклить (выполнять все время). Перейдем к практическим примерам.

Arduino UNO: выводы

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

Arduino UNO

Темно-зеленым цветом (от 0 до 19) обозначены универсальные цифровые пины (контакты) ввода/вывода (I/O). Когда мы будем использовать их в роли выходов, мы сможем установить на них 0V (логическое 0, низкое состояние) или 5V (логическое 1, высокое состояние). После того, как они настроены в роли входов, они смогут обнаружить контактное соединение с 0V или 5V.

Светло-зеленым цветом отмечены аналоговые входы (A0-A5). Это уникальные пины (контакты), которые позволяют измерять напряжение (в диапазоне от 0 V до 5 V). Как вы можете видеть, нумерация этих входов совпадает с универсальными пинами (номера от 14 до 19). Работа в аналоговом режиме является дополнительной функцией этих контактов.

Помните: аналоговые пины A0-A5 также могут работать как обычные контакты ввода / вывода.

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

  • SDA, SCL — вывод шины I2C, используемой, например: для связи с более продвинутыми датчиками, вывод этих пинов дублируется (они расположены в нижнем левом и верхнем правом углу платы — это точно такие же сигналы),
  • TX, RX — интерфейс UART, в основном используется для связи с компьютером,
  • PWM — выходы, на них можно генерировать прямоугольный сигнал с переменным заполнением. Очень полезная функция, например: при управлении сервоприводами,
  • LED — светодиод, встроенный в Arduino, который подключен к пину № 13.
    Оранжевый цвет-это выводы, которые не программируются. Они в основном отвечают за питание системы. Они будут более подробно обсуждаться, когда придет время их использовать.

Разъемы, описанные на картинке выше, как ICSP используются для прямого программирования двух микроконтроллеров, которые находятся на плате Arduino UNO. Эти разъемы используются в очень специфических случаях, и на этом этапе нет ни малейшей необходимости иметь дело с ними.

Выходы — LED на практике

Теперь разберемся с самым простым, включим светодиод. Согласно описанию выше, мы можем использовать любой пин I/O для этого. Цифровой пин — это выход, который мы можем установить в одно из двух состояний. Низкий или высокий. Для Arduino это будет 5V или 0V.

Схема должна быть подключена в соответствии с приведенным ниже рисунком. Диод соединяем последовательно с резистором (330R). Затем более длинную ножку диода (анод) соединяем с пином № 8. Через резистор с землей, которую мы находим в разъеме питания (описанном как GND). На плате есть 3 вывода, описанные как GND. Мы можем выбрать любой.

ВНИМАНИЕ! Любое подключение большинства периферийных устройств (диоды, зуммеры) к Arduino делайте через резисторы! Без резистора вы можете повредить подключенные компоненты или даже саму плату Arduino!
Подключение диода
Подключение диода к Ардуино

Программа для включения диода очень проста. Подключите Arduino к компьютеру с помощью USB-кабеля. Запустите IDE Arduino и введите приведенный ниже код. Затем загрузите его на плату. Описание загрузки вы найдете в первой статье.

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

Функция pinMode позволяет вам выбрать, является ли пин входом или выходом. Пин может быть числом от 0 до 13, а режим:

  • INPUT,
  • OUTPUT,
  • INPUT_PULLUP.

Если мы хотим управлять выходом, мы всегда используем режим Output. Остальные режимы будут обсуждаться позже.

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

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

В конце каждой команды ставится точкой с запятой!

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

Задержка в программе — светодиод мигает

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

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

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

Задание 1.1

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

Задание 1.2

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

Системные входы на практике — условная инструкция

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

Делать это нужно согласно примеру ниже. Одна сторона кнопки подключена к земле (минус), а другая к пину 7.

Подключение кнопки
Подключение кнопки к Arduino
Внимание! На кнопках, входящих в некоторые комплекты, вместо четырех ножек, 2 ножки. Кнопки с двумя ножками лучше подходят к макетной плате. Не стоит беспокоиться о том, что кнопка на картинке имеет 4 ножки.

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

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

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

Первая часть функции (input) означает, конечно, вход, а вторая часть (pullup) отвечает за включение внутреннего резистора, отвечающего за этот вход.

Теперь нам нужно прописать состояние входа. Для этого требуется функция digitalRead(pin), которая управляет значением HIGH или LOW в зависимости от состояния. В нашей схеме кнопка замыкает вход Arduino с заземлением (LOW).

Отсюда условная функция if (условие). Эта функция очень популярна. С ее помощью мы можем выполнить данную часть кода, если возникли определенные обстоятельства. То есть, например: если нажата кнопка.

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

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

Однако от такой программы мало толку. Зачем нам нужен выключатель света, который работает, только когда мы держим его пальцем? Не лучше ли, если бы светодиод светился какое-то определенное время после нажатия кнопки?

Пример — выключатель света с «таймером»

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

Можете ли вы написать такую программу самостоятельно? Надеемся, что да! В случае проблем вы можете «просмотреть» наш код:

Пример — светофор

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

[…] -> Зеленый -> Желтый -> Красный -> Красный + Желтый […]

Когда кнопка нажата, схема должна начать переключать светодиоды в той последовательности, которую мы определили. Эту программу мы напишем в несколько этапов. Сначала подключите 3 светодиода и кнопку так, как показано на картинке ниже.

Подключение светодиодов и кнопки
Подключение светодиодов и кнопки

Давайте подготовим основу программы, с которой мы будем работать. Наша задача сейчас настроить входы и выходы.

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

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

Цикл While

До сих пор мы использовали только основной обязательный цикл в коде Arduino loop(). Теперь пришло время узнать о цикле, который мы сможем использовать внутри самой программы.

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

Теперь мы обсудим цикл while (), который работает до тех пор, пока условие не будет выполнено. Работа цикла представлена в коде ниже:

Чтобы стало понятно, объясняем, цикл while () выполняет все время только тот код, который помещается между его фигурными скобками, где написано «код выполняется в цикле до тех пор, пока условие не перестанет выполняться». Вся остальная часть кода не выполняется.

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

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

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

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

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

Как это работает:

  1. включаем светодиоды в определенной последовательности,
  2. входим в цикл while (), который находится чуть ниже,
  3. цикл пуст, поэтому программа продолжает вращаться по кругу и… ничего не делает,
  4. только после нажатия кнопки (невыполнение условия) программа выходит из цикла,
  5. загорается еще одна последовательность, и ситуация повторяется.

Давайте проверим работу программы на практике!

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

Как вы помните из первой статьи, процессор выполняет около 16 миллионов операций в секунду. Соответственно, при нажатии кнопки он успеет пройти все состояния нашей программы (и то не один раз…). Это просто эффект случайного «выстрела» в заданную последовательность.

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

Теперь все должно работать правильно!

Стоит отметить, что условия в цикле while () могут быть объединены и значительно расширены, однако мы вернемся к этой теме, когда начнем изучать переменные.

Вывод

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

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

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

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

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