Освой Arduino играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Мигаем светодиодом

01.Basics: BareMinimum
01.Basics: Blink
Добавляем свой светодиод (+светодиод)
Мигаем любым светодиодом на любом выводе (+светодиод+резистор+провод+breadboard)
Сигнал SOS
Собственный пример (+провод)
02.Digital: BlinkWithoutDelay (Мигаем светодиодом без delay())

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

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

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

01.Basics: BareMinimum

Приступать к настоящей работе с платой страшновато, вдруг что-то сгорит. Поэтому пока отложим его в сторону от греха подальше и запустим Arduino IDE. Разработчики платы подготовили серию простых примеров, которые следует изучить, чтобы заложить фундамент для будущих проектов. Найти их можно в меню File | Examples. В разделе 01.Basics находятся самые простые примеры. А самый примитивный из них - скетч BareMinimum. Вам даже не понадобится плата.

На языке Arduino проекты с листингом называются скетчами (sketch) и имеют расширение INO.

Давайте изучим первый скетч: File | Examples | 01.Basics | BareMinimum. Откроется окно с следующим кодом:


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

}

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

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

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

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

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

Запоминать код и записывать его в тетрадочку не нужно. Когда вы будете создавать собственный скетч через File | New, то появится точно такой же код. И вы можете создавать свои проекты и сохранять их.

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

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

Запускаем скетч File | Examples | 1.Basics | Blink (Файл | Примеры | 1.Basics | Blink). У вас загрузится готовый пример с кодом. С его помощью мы можем увидеть, что плата работает.

Пример Blink

Выбираем нашу плату - в меню Tools | Board (Сервис | Плата) должна быть отмечена Arduino Uno (как правило по умолчанию она уже отмечена). У вас может быть другая плата. Естественно, вы должны уже подключить плату к компьютеру через USB-порт для загрузки скетча в микроконтроллер.

Теперь нужно выбрать последовательный порт. Опять идём в меню Tools | Serial Port (Сервис | Последовательный порт) и выбираем нужный порт (обычно это COM3 или COM4).

Теперь нам необходимо загрузить открытый пример Blink на микроконтроллер. Просто щёлкните на кнопкуUpload (Загрузить) и внимательно смотрите на плату. Вы увидите, что светодиоды, помеченные как RX и TX будут мигать. После успешной загрузки примера в контроллер, в строке состояния среды разработки появится надпись Done uploading (Загрузка выполнена).

Ещё ниже в области консоли будет выведено сообщение:
Sketch uses 930 bytes (2%) 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.

В сообщение выводится информацию об используемой памяти. Программа настолько проста, что почти ничего не потребляет (0% оперативной памяти и 2% постоянной памяти).

Через несколько секунд после загрузки, вы можете увидеть, что светодиод, помеченный на плате как 13 (L), будет мигать оранжевым цветом. Поздравляю, вы успешно установили среду разработки и запустили свою первую программу!

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


// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {
    // initialize the digital pin as an output.
	pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)
	delay(1000);              // wait for a second
	digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
	delay(1000);              // wait for a second
}

Сравните с текущей версией.


// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Теперь вместо создания отдельной переменной led используется встроенная константа LED_BUILTIN. Это удобно, так как в разных платах используются разные значения для встроенного светодиода и таким образом программа получилась универсальной.

Возвращаемся к первой программе BareMinimum. Откройте скетч и сделайте сначала первую вещь - нажмите на кнопку Verify (первый значок с галочкой). Среда разработки переводит ваш код в машинный код, т.е. компилирует. Если в вашем коде есть ошибка, то компилятор выведет сообщение. Это полезно, чтобы не тратить зря время на загрузку заведомо неработающей программы. Давайте сознательно сделаем ошибку - напишем код в функции setup().


void setup() {
  // put your setup code here, to run once:
  int cat = "Я люблю котиков";
}

С точки зрения кошатника, здесь всё написано правильно. Предложение написано без ошибок, есть даже точка с запятой в конце строки - всё как положено.

Проверим. Нажимаем кнопку Verify и видим сообщения с красным текстом. Его текст приводить не буду, сами убедитесь. Если программа с ошибкой, то нет смысла её загружать на плату. Даже если вы очень упрямый и всё-равно нажмёте кнопку Upload, то получите ту же ошибку. Иными словами, Upload сначала самостоятельно выполняет операцию Verify и при отсутствии ошибки загружает скетч.

Разбор примера

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

Изучим код шаг за шагом.

В функции setup() мы видим три строчки:


// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

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


// инициализируем цифровой порт как вывод

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


pinMode(LED_BUILTIN, OUTPUT);

В старых версиях код был немного другим:


// очень старый вариант
pinMode(13, OUTPUT);

// обновлённый вариант
pinMode(led, OUTPUT);

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


// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

Комментарий можно перевести как:


// Порт 13 в большинстве плат Arduino соединён со светодиодом

Сейчас код обновили, и вместо переменной led используют константу LED_BUILTIN. Такой подход удобен, так как не все платы Arduino имеют встроенный светодиод на порту 13. Если у вас две разные платы и одна из них имеет нестандартный номер, то вам не придётся переписывать пример под каждую плату.

Нам встретилась новая функция pinMode(), которая устанавливает режим для портов. Функция состоит из двух параметров. В первом параметре указывается порт, с которым мы собираемся работать. Во втором параметре мы сообщаем, как должен работать указанный порт: работать на выход (OUTPUT) или вход (INPUT). В нашем примере, вывод под номером 13 (или другой порт, используемый встроенным светодиодом) должен выводить информацию (посылать сигнал), то есть давать указание мигать светодиоду.

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


// Старый вариант
// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

// Современный вариант
// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Здесь мы видим уже четыре строчки кода. Первая строчка включает светодиод при помощи функции digitalWrite(). В первом параметре мы указываем номер порта, с которым собираемся работать, а во второй указываем константу HIGH. Забегая вперёд, могу сказать что константа HIGH равна 1, и можно было написать digitalWrite(13, 1). Но такая запись не очень удобна, так мельтешение цифр в большом проекте затрудняет чтение кода. А здесь вы сразу видите, что на порту под номером 13 включается светодиод.

Далее идёт команда, отвечающая за паузу - delay(), которая имеет один параметр - количество времени в миллисекундах. В нашем примере мы сделали паузу в одну секунду (1000 миллисекунд = 1 секунда).

Следом идёт уже знакомая нам функция digitalWrite(), но уже с параметром LOW, который выключает светодиод (значение константы LOW равно 0).

И последняя строчка снова делает паузу в одну секунду.

Посмотрим, как работает программа. Когда мы загружаем программу в микроконтроллер, то Arduino активирует порт 13 в режиме выхода (функция setup()), а затем начинает последовательно выполнять четыре строчки из функции loop(): включает диод-пауза-выключает диод-пауза. Когда эти четыре строчки будут выполнены, то они снова будут вызваны и будут повторяться до тех пор, пока мы не выдернем кабель.

Что мы можем изменить в данной программе? По большому счету ничего - мы можем установить только собственные значения пауз. Поэкспериментируйте с этим. Другие изменения результата не принесут - нет смысла, например, сейчас использовать другой порт или использовать режим INPUT.

Добавляем свой светодиод (+светодиод)

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

Светодиод

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

В светодиодах короткую ножку («минус») светодиода нужно соединять с землёй (GND). Светодиод не рассчитан на большой ток. Чтобы не повредить светодиод, используйте с ним резистор. Он позволяет уменьшить силу тока. В противном случае светодиод прослужит недолго или просто сгорит. Полярность резисторов не важна. Сам резистор можно подключать как до светодиода, так и после него. Я привык сначала ставить резистор, а потом светодиод по направлению от источника питания к земле.

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

LED

Запускаем снова программу Blink. Теперь будут мигать два светодиода: встроенный и наш. Красота!

Вернёмся к светодиодам. Как правило, в цепи идёт слишком большой ток для светодиодов. Чтобы уменьшить силу тока, используют токопонижающие резисторы (сопротивления). У светодиодов есть важные характеристики: ток питания и напряжение падения (Forward voltage). Невероятно, но факт - светодиоды разных цветов используют разные значения напряжения падения. Максимальный ток для светодиодов колеблется в районе 20 миллиампер. Для вычисления значения сопротивления используют формулу: из напряжения питания вычитаем напряжение падения и результат делим на силу тока в светодиоде в амперах. В документации обычно рекомендуют использовать резистор от 220 ohm до 1K ohm. На практике, можно использовать и 100 ом. Если поставите меньше, то будет риск спалить светодиод. При выполнении опытов с несколькими светодиодами вы можете установить разные резисторы, чтобы увидеть разницу.

Мигаем любым светодиодом на любом выводе (+светодиод+резистор+провод+breadboard)

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

Специально для этих целей была придумана макетная плата Breadboard. Когда я впервые взял её в руки, то растерялся. Интуитивно-понятным интерфейсом здесь и не пахло. Множество дырочек, красные и синие полосочки, буковки, циферки... Радиолюбители на форумах говорят, что это примитивная штука, не требующая объяснений. Но, когда впервые сталкиваешься с таким предметом, то так не думаешь. Чтобы ненароком не сжечь свою плату, мне пришлось просмотреть множество картинок и видео и просто повторять один в один показываемые примеры. Чуть позже я разобрался с этой штуковиной. Вы тоже поймёте, что к чему.

Breadboard

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

На моей доске доступно 830 контактов. Четыре рельсы по бокам предназначены для подключения питания и земли. Между ними — 126 групп соединённых между собой контактов. Схематично доску можно представить так (взято у Амперки):

Схема Breadboard

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

Давайте соберём нашу первую схему на Breadboard. Нам понадобятся плата Arduino, Breadboard, светодиод, резистор и перемычки (или провода). Начнём с Breadboard. Вставляем в него светодиод следующим образом - длинную ножку вставляем в один из выводов, например, A5, а короткую ножку в отверстие синей рельсы, т.е. минус.

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

Далее необходимо соединить Breadboard с платой Arduino. Располагаем их рядышком и соединяем их с помощью перемычек. Первая перемычка вставляется так - на Breadboard ножка перемычки вставляется в свободное отверстие красной рельсы, а вторая ножка втыкается на Arduino в порт вывода с меткой 5V. Вторую перемычку ставим так - первая ножка вставляется на Breadboard в отверстие синей рельсы, а вторая ножка вставляется на Arduino в порт вывода с меткой GND (на плате несколько меток GND, подойдёт любой).

Подключаем плату к компьютеру. Если все сделано правильно, то светодиод должен загореться. Ура, получилось!

Учимся читать схему

Посмотрим, что мы сделали. Мы последовательно соединили светодиод с резистором к источнику питания на 5 Вольт. По этой схеме ток течёт из вывода с меткой 5V, далее проходит через резистор, потом через светодиод и попадает в вывод с меткой GND.

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

Каждый электронный компонент имеет свой графический символ. Например, для резистора используется следующий символ (используется в США, в России и Европе используется другой символ):

Символ резистора

Как видите, символ резистора симметричен, как и сам компонент.

Светодиод обозначается символом:

Символ светодиода

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

Плюс (слева) и минус (справа) питания также имеют символы:

Попробуем соединить все описанные детали вместе, чтобы изобразить нашу цепь.

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

Усложняем схему

Мы создали примитивную схему, которой нельзя управлять. Ток течёт через резистор и светодиод, минуя порты ввода/вывода.

Изменим схему следующим образом. Сейчас у нас резистор соединяется с выводом 5V. Давайте соединим его теперь с выводом 13. Вытащим ножку резистора из вывода 5V и вставим его в отверстие на Breadboard таким образом, чтобы оно находилось на одной линии с другой ножкой резистора. Далее соединяем перемычкой вывод 13 на Arduino и соседнее отверстие рядом с ножкой резистора. Светодиод оставляем на месте.

На схеме это будет выглядеть следующим образом.

Откройте предыдущую программу с миганием встроенного светодиода и запустите её. У вас теперь будут мигать два светодиода одновременно, так как они оба использует выход 13.

Для закрепления материала перебросим перемычку на вывод с меткой 12. Схема теперь выглядит так:

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


int ledPin = 12;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  digitalWrite(ledPIn, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Сигнал SOS

После примера с мигалкой просто напрашивается написать пример с сигналом SOS. Напомню, что знак в азбуке Морзе выглядит как ...---.... В Википедии даётся информация о длительности точек, тире, паузах между знаками или словами. Вот и повторим, у нас всё по взрослому. Единицей времени для точки возьмём 150 миллисекунд, от этой величины и будем плясать (интересно девки пляшут).


/*
   SOS

   Если этот код работает, его написал Александр Климов,
   а если нет, то не знаю, кто его писал.

   За единицу времени принимается длительность одной точки.
   Длительность тире равна трём точкам.
   Пауза между элементами одного знака — одна точка,
   между знаками в слове — 3 точки,
   между словами — 7 точек. (Википедия)
*/

int ledPin = 10;

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // 3 dots ...
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
  }

  delay(450);

  // 3 dashes ---
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    delay(450);
    digitalWrite(ledPin, LOW);
    delay(150);
  }

  delay(450);

  // 3 dots ...
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
  }

  // Pause and repeat again
  delay(1050);
}

Собственный пример (+провод)

Если вы хотите что-то исправить в готовой программе из примеров, то лучше это делать в новом проекте. Создайте свой скетч и скопируйте код из примера Blink. Для начала измените значения микросекунд для паузы. Теперь попробуем написать свою собственную программу на её основе. Вам понадобится обычный провод. Один конец вставляем в порт под номером 7, а второй в порт с надписью GND.

Задумка следующая. Порт может не только принимать сигнал (работать на выход), но и посылать сигнал. Фактически порт пускает через себя ток. В этом случае режим устанавливается как INPUT или INPUT_PULLUP. Если через порт идёт ток, то заставим светодиод мигать быстро-быстро. Если движение тока прервано, то мигание будет редким.


int ledPin = 13;
int switchPin = 7;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
}

void loop()
{
  if(digitalRead(switchPin) == LOW)
  { 
    flashLed(100);
  }
  else
  {
    flashLed(500);
  }
}
  
void flashLed(int delayPeriod)
{
  digitalWrite(ledPin, HIGH);
  delay(delayPeriod);
  digitalWrite(ledPin, LOW);
  delay(delayPeriod);
}

Часть кода нам уже знакома. Смотрим на новый код. Для опытов мы используем порт 7, поэтому завели новую переменную switchPin. В функции setup() мы устанавливаем для него режим на вход в особом режиме INPUT_PULLUP (подтягивающий резистор). Его особенность состоит в том, что при соединении с землёй он будет выдавать значение LOW, а при разрыве - HIGH

В функции loop() мы реализуем условие с проверкой. Считываем значение с порта 7. Если ток идёт, то значение будет LOW светодиод будет мигать часто. В противном случае светодиод будет мигать редко.

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

Запустив проект, убедимся, что светодиод мигает часто. Вытащим один конец провода и увидим, что светодиод стал мигать медленно. Опять вставляем провод на место и снова светодиод будет мигать часто. Чудеса!

INPUT_PULLUP

Когда мы подключаем плату Arduino к компьютеру через USB-порт, то можем обмениваться между ними информацией с помощью сообщений, которые отображаются в Serial Monitor. О Serial Monitor мы поговорим позже в других статьях, пока поверхностно познакомимся с ним. Допустим, у нас сгорел светодиод и он не сможет нам показать своим миганием, есть ли соединение или нет. Уберём из кода строки, относящиеся к светодиоду, и напишем код для обмена сообщениями.


//int ledPin = 13;
int switchPin = 7;

void setup()
{
  //pinMode(ledPin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop()
{
  if(digitalRead(switchPin) == LOW)
  { 
    //flashLed(100);
    Serial.println("Connected");
  }
  else
  {
    //flashLed(500);
    Serial.println("Not connected");
  }
}

Лишний код закомментирован, а функция flashLed() даже удалена. Как пользоваться программой? Запустите скетч снова, затем в Arduino IDE нажмите на значок Serial Monitor в виде лупы. Откроется новое окно, в котором будут быстро мелькать строки Connected с новой строки. Выдерните провод и в окне сообщения сменятся на Not connected. Таким образом, плата посылает информацию компьютеру.

02.Digital: BlinkWithoutDelay (Мигаем светодиодом без delay())

Рассмотрим урок BlinkWithoutDelay из меню File | Examples | 02.Digital.

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

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

Для демонстрации нужен светодиод с резистором и кнопка.


const int ledPin =  LED_BUILTIN;// встроенный вывод 13

int ledState = LOW;             // состояние светодиода

// Используйте тип "unsigned long" для переменных, работающих со временем
// Так как значение очень быстро становится слишком большим для типа int
unsigned long previousMillis = 0;        // храним время последнего переключения светодиода

const long interval = 1000;           // интервал между миганиями (миллисекунды)

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  // проверяем не прошёл ли нужный интервал
  // вычисляется разница между текущим временем и временем последнего мигания.
  // если разница больше, то
  if (currentMillis - previousMillis >= interval) {
    // сохраняем время последнего переключения
    previousMillis = currentMillis;

    // если светодиод не горит, то включаем его, и наоборот
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
	// устанавливаем состояние светодиода
    digitalWrite(ledPin, ledState);
  }
}

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

Реклама