Урок №2. Подключение платы к компьютеру, первая программа

Введение

На предыдущем уроке мы узнали что такое Ардуино и сделали краткий обзор «экосистемы».

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

Знакомство с платой

Итак, перед нами – одна из самых распространенных плат ардуино Arduino UNO.

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

Микроконтроллер

Большая многоножка посередине платы – это сердце ардуино, микроконтроллер.

Говоря по-простому, микроконтроллер выполняет 4 основные функции:

  • Выставляет напряжение на своих ножках
  • Считывает (измеряет) напряжение на ножках
  • Запоминает данные
  • Производит вычисления

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

  • Считывать данные с датчиков
  • Воспроизводить звук
  • Вращать моторчики
  • Отправлять и принимать данные и т.д.

В зависимости от модели платы здесь может стоять разный микроконтроллер. В UNO R3, например, стоит Atmega328.

Он может быть в разном корпусе: SMD или DIP.

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

Ножки микроконтроллера называются пинами. Все они выведены на плате ардуино.

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

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

Входное питание

У платы UNO нее есть 2 основных способа питания:

  • USB разъем, для подключения 5V источника питания или подключения к компьютеру
  • Разъем для подключения сетевого источника питания с выходным напряжением от 7 до 12V. Т.е. сюда напрямую можно подключить хоть батарейку крону, хоть питание от светодиодной ленты. Нам он нужен только для того, чтобы ардуино работала без компьютера. Но в ходе обучения, ардуино у нас почти всегда будет подключена к компьютеру. Поэтому этот разъем нам не нужен. А для экспериментов без компьютера проще будет использовать power bank, подключаемый к разъему USB.

Да, у ардуино есть еще 3й способ питания, а для, например, ProMini он является вообще единственным. Это пин VIN (сокращение от «Voltage Input») – альтернативный способ питания, который полезен, например, если ваше устройство будет иметь 2 способа питания: от сети и аккумулятора. Компаратор на плате сам выберет питание с наибольшим напряжением. Диапазон напряжение тоже от 7 до 12V.

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

Настало время подключить плату к компьютеру и написать первую программу.

Подключение к компьютеру

Нам потребуется установить среду программирования Arduino IDE.

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

В ходе установки будут также поставлены драйверы платы. А в случае необходимости, от вас потребуют установить java, поскольку Arduino IDE – кросс-платформенная среда и написана на Java.

Опционально может потребоваться установка драйвера китайской ардуино.

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

Итак, Arduino IDE установлена, плата подключена.

Давайте теперь запустим Arduino IDE. Как только вы запустили программу, перед вами открывается окно с новым пустым скетчем:

Этот скетч не делает ровным счетом ничего, но нам его достаточно, чтобы проверить подключение платы.

Для начала выберем нашу плату, через меню Tools > Board: … :

Я осмелюсь предположить, что у вас Arduino/Genuino Uno или Arduino Nano. 😉

Теперь давайте выберем номер порта к которому подключена Arduino, через меню «Tools > Port:»

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

Теперь давайте сохраним этот пустой скетч:

  • нажмем Ctrl+S,
  • или кнопку со стрелкой вниз,
  • или выберем меню – File > Save.

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

Обратите внимание, что Arduino IDE сохраняет скетч в одноименную папку. Сам скетч имеет расширение «.ino». Если вы попробуете открыть скетч, находящийся в папке с именем, отличным от имени файла скетча, то IDE будет ругаться и попросит пересохранить его.

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

Давайте загрузим нашу пустую программу на плату:

Можно нажать на кнопку со стрелкой вправо , можно выбрать через меню Sketch > Upload,

а лучше просто нажмите Ctrl+U.

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

Если увидели, значит все прекрасно!

Обращу внимание на служебную информацию, в окне протокола:

Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

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

Обратим внимание еще на несколько кнопок:

 — verify, верификация, проверка программы. Эту кнопку вы нажимаете всегда, когда хотите подвести очередную черту под своей программой – проверить и исправить синтаксические ошибки в программе, скомпилировать ее. Но давайте сразу запомним комбинацию Ctrl+R.

 — это монитор последовательного порта. Он нам нужен почти всегда, чтобы отлаживать программу. Ее комбинация – это Ctrl+Shift+M.

Давайте откроем это окно. Пока тут пусто.

Теперь давайте разберем что из себя представляет наш пустой скетч.

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

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

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

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

Почему я сказал, что тело функций пока пустое, хотя там что-то есть? Да потому что

// put your setup code here, to run once: — это не программа, а комментарий, простой текст, который игнорируется компилятором и нужен только для нашего лучшего понимания что делает программа.

С помощью двойного слэша можно не только дать пояснительный текст, но и отключать строки программы, не удаляя их (говорят: «закомментировать код»).

Если же требуется закомментировать сразу большой кусок кода (программы), используются блочный комментарий – /* в начале блока и */ в конце блока комментария, например:

/*
(C) jarduino.ru 2019
Учебный курс Ардуино.
*/ 

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

Используйте типы комментарий правильно: избегайте использование блоков комментариев внутри функций – используйте срочные комментарии, и это упростит вам отключение крупных кусков программы.

Функции setup и loop мы только определяем, но сами не вызываем – их вызывает ардуино:

  • setup – 1 вызывается раз, при инициализации платы; здесь мы инициализируем параметры платы и подключенные устройства
  • loop – вызывается бесконечно, в цикле; сюда вы пишем программу, которая должна выполняться вновь и вновь, например, регулярный опрос датчиков, обновление информации на экране и т.п.

Первая программа

Давайте нашей первой программой традиционно поприветствуем Мир: выведем приветствие через последовательный порт и увидим его на экране компьютера!

Для работы с последовательным портом, в программном ядре ардуино есть глобальный объект Serial.

Объект – это переменная составного типа, которая имеет собственные функции, такие как рассмотренные выше setup и loop, но доступны они только через имя объекта, через точку. Такие функции называются методами объекта.

Итак, сначала мы должны инициализировать последовательный порт. Чтобы это сделать, в функции setup вызываем метод Serial.begin:

Serial.begin(9600); // 9600 – это скорость коммуникации по последовательному порту
// измеряется в бодах (baud, бит в секунду). обычно 9600.

Важно чтобы скорость в мониторе последовательного порта и в программе совпадали.

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

Давайте выведем приветствие в цикле:

void loop() {
   Serial.println(“Привет, Мир! Привет, jarduino.ru!”);
}

println – метод объекта Serial, с помощью которого в последовательный порт выдается строка текста; т.е. курсор после вывода текста переводится на новую строку.

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

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

Поздравляю вас с первой программой!

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

Для этого воспользуемся встроенной функцией delay. Она имеет единственный параметр – это время задержки в миллисекундах. 1 сек. = 2000 мсек. Значит, вызывать надо так:

delay(2000);

А теперь давайте включим счетчик приветствий. Для этого надо разобрать новую концепцию языка – переменные.

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

Чтобы начать использовать переменную, ее необходимо сначала объявить (т.е. задекларировать), вот так:

int nCount;

Здесь int – это тип данных для целых чисел.

nCount – это имя нашей переменной.

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

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

По области действия переменные различают на локальные и глобальные. Дело в том, что программа на C/C++ имеет иерархическую структуру, задаваемую вложенностью фигурных скобок { … }. Переменная доступна только внутри того блока, в котором она была объявлена, включая все вложенные блоки.

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

Объявим переменную nCount как глобальную. Также хорошим тоном является первичная инициализация переменной сразу в момент декларации:

int nCount = 0;

или так:

int nCount{0};

последний вариант является более современным и, в общем случае, более правильным.

= — это оператор присвоения значения переменной. Просьба не путать его с логическим оператором равенства ==.

Обновим нашу функцию loop:

void loop() {
  ++nCount;
  
  Serial.print("Привет, Мир! Привет, jarduino.ru! ");
  Serial.println(nCount);
  
  delay(2000);
}

++ — это оператор инкрементирования, т.е. увеличения значения переменной на 1.

Кстати, знак инкремента можно ставить как до, так и после переменной (nCount++ == ++nCount), и любители в подобных случаях чаще всего ставят именно после. Но с формальной точки зрения, в нашем случае правильнее будет поставить инкремент перед переменной. Что сокращает программу на 1 операцию.

Загружаем обновлённую программу, смотрим результат:

На этом было бы все для первого урока. Но я ведь решил постепенно учить вас писать программы правильно. Поэтом еще пара слов про глобальные переменные.

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

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

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

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

Как же следует поступить в нашем случае со счетчиком приветствий и все-таки избежать объявление глобальной переменной? Вед если мы просто переместим декларацию переменной nCount в loop(), то nCount будет сбрасываться в каждой новой итерации цикла.

Чтобы сбрасывания не происходило, нужно использовать ключевое слово static, сделав переменную nCount статической. Это позволит сохранить значение переменной nCount до следующего вызова loop(), но все-же спрячет эту переменную внутри этой функции.

Т.о. итоговый скетч нашего урока будет следующим:

/**
 * (C) jarduino.ru 2019
 * Изучение ардуино через опыты.
 * 
 * Опыт №1. Привет, Мир!
 * Вывод текста по последовательному порту.
 */

// Инициализация приложения
void setup()
{
  // Инициализировать последовательный порт, установить скорость обмена 9600 бод (бит в сек.).
  Serial.begin(9600);
}

// Главный цикл
void loop()
{
  static int nCount = 1; // инициализировать статический счетчик

  // Вывести по последовательному порту текст:
  Serial.print("Привет, Мир! Привет, jarduino.ru! ");
  Serial.println(nCount);

  ++nCount; // увеличить счетчик на 1

  delay(2000); // Пауза на 2000 милисек. (2 сек.)
}

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

Однако разумное использование static-переменных является широко распространённой техникой как раз для экономии памяти ардуино. Но это тема отдельного урока, посвященного эффективному использованию памяти ардуино.

Заключение

Подведем итоги.

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

  • Разобрали понятие и структур скетча,
  • Познакомились с последовательным портом и научились выдавать отладочную информацию
  • Познакомились с некоторыми ключевыми понятиями языка программирования:
    • Функции
    • Переменные
    • Статические, локальные и глобальные переменные

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

Также, параллельно, мы продолжим изучать программирование на C/C++ для ардуино.

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

Задавайте вопросы и критикуйте в комментариях.

Не забудьте поделиться этим уроком своими друзьями и единомышленниками.

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

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