(продолжение, начало см. Урок 2. ArduinoIDE)
В предыдущем уроке мы даже толком не разобрали текст нашего скетча "Blink". Присмотримся к нему повнимательнее:
Поспешу оговориться: если вы уже программировали на C/С++, разобраться не составит труда. Остальным придется потрудиться, но помните: язык создавался с оглядкой на дизайнеров (людей гуманитарного склада ума), что вынудило авторов сто раз думать о простоте и понятности, прежде чем вводить новый оператор в синтаксис.
Первым делом, отбросим комментарии. Это такой произвольный текст пояснительного характера, который программист вставляет в текст программы, дабы не запамятовать, что же он там понаделал три года назад. Справедливости ради - есть масса других способов этого добиться, например правильно называть переменные.
Пока что запомните: если в строке встретилось два слеша //, то они, вместе со всеми символы правее, до конца этой строки компилятору глубоко безразличны. Если в комментарий надо превратить сразу несколько строк, то его начинают с /* и заканчивают */. Таким образом, вышеприведенный код для компилятора будет значительно проще и короче:
Кстати, комментирование применяют и для отладки, чтобы временно "выключить" фрагмент скетча. В ArduinoIDE для этого есть горячая клавиша Ctrl+/, которая позволяет быстро закомментировать или раскомментировать выделенный фрагмент текста.
Итак, первая строка скетча:
Это объявление переменной с именем ledPin. Компилятор забронирует в памяти микроконтроллера пару байт для хранения целого числа, позволяя вам начиная с этого места обращаться к нему по имени 'ledPin'. Заодно он присвоит ему начальное значение 13.
Следующая конструкция обязательно должна присутствовать в любом сектче:
Забегая вперед - это определение функции. Однако, функция setup особенная: она исполняется один раз после старта скетча (по включению питания Arduino или после сброса). Туда можно смело вынести все действия, которые должны выполниться один раз, например - настройка скорости последовательного порта или выбор режима работы универсальных пинов (на ввод или на вывод). Все эти действия должны быть вписаны между открывающей и закрывающей фигурными скобками { }.
И, кстати, сейчас там только одна строчка:
Оператор языка Wiring 'pinMode' устанавливает для одного из указанных пинов режим ввода или вывода. В данном случае номер пина берется из переменной ledPin (напоминаю, что там было число 13, а следовательно - речь про digital13, к которому подключен тестовый светодиод L), режим задается константой OUTPUT, что логически подготавливает нас к тому, что через этот пин будет что-то выводиться.
Если понадобится сделать из тринадцатого пина вход, используйте константу INPUT. Но по умолчанию все цифровые пины после старта скетча и так уже находятся в режиме ввода. И еще одно важное замечание: режим вход/выход можно переключать в процессе работы скетча, сколько угодно раз! Главное, чтобы схема была для этого предназначена.
Функция loop также должна быть в любом скетче - она вызывается сразу после завершения setup, а потом снова и снова... до бесконечности. Может быть, это покажется вам немного странным, но в применении к микроконтроллерам вообще и к Ардуино в частности, встречается довольно часто: надо постоянно опрашивать кнопки и датчики, давать команды на моторы или реле, выводить данные на дисплей. Собственно, именно поэтому однократно исполняемые действия и вынесены в setup - если что-то надо сделать один раз, сделайте именно в ней.
Разберем, из чего состоит тело loop:
Это еще один оператор языка Wiring, который переключает состояние пина в одно из двух возможных. HIGH соответствует логической единице (она же - напряжение питания микроконтроллера, для Duemilanova это +5 Вольт), LOW - логическому нулю, это меньше +0,5 В.
Светодиод L подключен в Arduino следующим образом:
Анатомию этой схемы мы разберем позже, пока стоит запомнить, что если на пине Ардуино установить напряжение 5В, светодиод начнет светиться - как говорят, он "откроется" и через него потечет ток. Если же на этом входе будет меньше 1,5В, то этого напряжения не хватит для его открывания, и онобидится светиться не будет.
Итак, оператор digitalWrite(ledPin, HIGH) формирует +5В на выходе 13 и зажигает таким образом светодиод L.
Эта команда delay заставляет микроконтроллер остановиться и ничего не делать целую 1000 миллисекунд - безумно много! Кстати, 1000 мс = 1 с ;)
Этой командой светодиод отключается (см. выше).
Дальше снова происходит задержка в одну секунду.
А потом... тело loop заканчивается, но поскольку он вызывается беспрерывно, то управление снова переходит на начало - исполняется digitalWrite(ledPin, HIGH), и так далее.
Визуально можно представить так:
Если бы у нас под руками был специальный прибор осциллограф, то подключив его к digital13 мы увидели бы примерно такую картину:
Говоря строгим языком, мы добились на этом выходе колебаний с частотой 0,5 Гц ( 1 Гц соответствует одному полному колебанию в секунду). Меняя две величины задержки в delay, можно добиваться другой частоты мигания, а если они начать менять их отношение, то изменится скважность сигнала (сейчас мы получили то, что обычно называют меандр).
Но чтобы пользоваться Arduino все это знать необязательно. Все мигает, как и задумано, не так ли? ;)
В качестве домашнего задания: попробуйте поправить скетч таким образом, чтобы светодиод мигал не равномерно, как сейчас, а периодически подмигивал 3-х кратными вспышками. Какая задержка должна быть между вспышками, чтобы глаз их все еще различал?
В следующем уроке мы подробнее разберем основные конструкции языка Wiring.
/* Blink Turns on an LED on for one second, then off for one second, repeatedly. The circuit: * LED connected from digital pin 13 to ground. * Note: On most Arduino boards, there is already an LED on the board connected to pin 13, so you don't need any extra components for this example. Created 1 June 2005 By David Cuartielles http://arduino.cc/en/Tutorial/Blink based on an orginal by H. Barragan for the Wiring i/o board */ int ledPin = 13; // LED connected to digital pin 13 // The setup() method runs once, when the sketch starts void setup() { // initialize the digital pin as an output: pinMode(ledPin, OUTPUT); } // the loop() method runs over and over again, // as long as the Arduino has power void loop() { digitalWrite(ledPin, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(ledPin, LOW); // set the LED off delay(1000); // wait for a second }
Поспешу оговориться: если вы уже программировали на C/С++, разобраться не составит труда. Остальным придется потрудиться, но помните: язык создавался с оглядкой на дизайнеров (людей гуманитарного склада ума), что вынудило авторов сто раз думать о простоте и понятности, прежде чем вводить новый оператор в синтаксис.
Первым делом, отбросим комментарии. Это такой произвольный текст пояснительного характера, который программист вставляет в текст программы, дабы не запамятовать, что же он там понаделал три года назад. Справедливости ради - есть масса других способов этого добиться, например правильно называть переменные.
Пока что запомните: если в строке встретилось два слеша //, то они, вместе со всеми символы правее, до конца этой строки компилятору глубоко безразличны. Если в комментарий надо превратить сразу несколько строк, то его начинают с /* и заканчивают */. Таким образом, вышеприведенный код для компилятора будет значительно проще и короче:
int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }
Кстати, комментирование применяют и для отладки, чтобы временно "выключить" фрагмент скетча. В ArduinoIDE для этого есть горячая клавиша Ctrl+/, которая позволяет быстро закомментировать или раскомментировать выделенный фрагмент текста.
Итак, первая строка скетча:
int ledPin = 13;
Это объявление переменной с именем ledPin. Компилятор забронирует в памяти микроконтроллера пару байт для хранения целого числа, позволяя вам начиная с этого места обращаться к нему по имени 'ledPin'. Заодно он присвоит ему начальное значение 13.
Следующая конструкция обязательно должна присутствовать в любом сектче:
void setup() { }
Забегая вперед - это определение функции. Однако, функция setup особенная: она исполняется один раз после старта скетча (по включению питания Arduino или после сброса). Туда можно смело вынести все действия, которые должны выполниться один раз, например - настройка скорости последовательного порта или выбор режима работы универсальных пинов (на ввод или на вывод). Все эти действия должны быть вписаны между открывающей и закрывающей фигурными скобками { }.
И, кстати, сейчас там только одна строчка:
pinMode(ledPin, OUTPUT);
Оператор языка Wiring 'pinMode' устанавливает для одного из указанных пинов режим ввода или вывода. В данном случае номер пина берется из переменной ledPin (напоминаю, что там было число 13, а следовательно - речь про digital13, к которому подключен тестовый светодиод L), режим задается константой OUTPUT, что логически подготавливает нас к тому, что через этот пин будет что-то выводиться.
Если понадобится сделать из тринадцатого пина вход, используйте константу INPUT. Но по умолчанию все цифровые пины после старта скетча и так уже находятся в режиме ввода. И еще одно важное замечание: режим вход/выход можно переключать в процессе работы скетча, сколько угодно раз! Главное, чтобы схема была для этого предназначена.
void loop() { }
Функция loop также должна быть в любом скетче - она вызывается сразу после завершения setup, а потом снова и снова... до бесконечности. Может быть, это покажется вам немного странным, но в применении к микроконтроллерам вообще и к Ардуино в частности, встречается довольно часто: надо постоянно опрашивать кнопки и датчики, давать команды на моторы или реле, выводить данные на дисплей. Собственно, именно поэтому однократно исполняемые действия и вынесены в setup - если что-то надо сделать один раз, сделайте именно в ней.
Разберем, из чего состоит тело loop:
digitalWrite(ledPin, HIGH);
Это еще один оператор языка Wiring, который переключает состояние пина в одно из двух возможных. HIGH соответствует логической единице (она же - напряжение питания микроконтроллера, для Duemilanova это +5 Вольт), LOW - логическому нулю, это меньше +0,5 В.
Светодиод L подключен в Arduino следующим образом:
Анатомию этой схемы мы разберем позже, пока стоит запомнить, что если на пине Ардуино установить напряжение 5В, светодиод начнет светиться - как говорят, он "откроется" и через него потечет ток. Если же на этом входе будет меньше 1,5В, то этого напряжения не хватит для его открывания, и он
Итак, оператор digitalWrite(ledPin, HIGH) формирует +5В на выходе 13 и зажигает таким образом светодиод L.
delay(1000);
Эта команда delay заставляет микроконтроллер остановиться и ничего не делать целую 1000 миллисекунд - безумно много! Кстати, 1000 мс = 1 с ;)
digitalWrite(ledPin, LOW);
Этой командой светодиод отключается (см. выше).
Дальше снова происходит задержка в одну секунду.
А потом... тело loop заканчивается, но поскольку он вызывается беспрерывно, то управление снова переходит на начало - исполняется digitalWrite(ledPin, HIGH), и так далее.
Визуально можно представить так:
Если бы у нас под руками был специальный прибор осциллограф, то подключив его к digital13 мы увидели бы примерно такую картину:
Говоря строгим языком, мы добились на этом выходе колебаний с частотой 0,5 Гц ( 1 Гц соответствует одному полному колебанию в секунду). Меняя две величины задержки в delay, можно добиваться другой частоты мигания, а если они начать менять их отношение, то изменится скважность сигнала (сейчас мы получили то, что обычно называют меандр).
Но чтобы пользоваться Arduino все это знать необязательно. Все мигает, как и задумано, не так ли? ;)
В качестве домашнего задания: попробуйте поправить скетч таким образом, чтобы светодиод мигал не равномерно, как сейчас, а периодически подмигивал 3-х кратными вспышками. Какая задержка должна быть между вспышками, чтобы глаз их все еще различал?
В следующем уроке мы подробнее разберем основные конструкции языка Wiring.
с частотой 2 герца, не 0.5
ОтветитьУдалитьНе согласен ;) Перечитайте википедию на эту тему, что ли ;)
УдалитьМне кажется, автор недооценивает (не понимает?) значение комментариев. Самодокументируемый код (с "правильными" названиями переменных) может сообщить лишь, ЧТО делает программа, а комментарии нужны, чтобы сообщить - ЗАЧЕМ.
ОтветитьУдалить