«ШКОЛА РОБОТОВ» УРОК № 3

«ШКОЛА РОБОТОВ» УРОК № 3

Наступает вечер. За окном сгущаются сумерки. Но вот на улице зажглись фонари. Кто их включил? А кто выключит их утром, когда взойдет солнце? А как автоматически включается свет в подъездах? Думаете, сидит где-то усатый дяденька, смотрит на часы и щелкает выключателем в нужный момент? Ошибаетесь! Эту работу давно выполняют роботы, но обо всем по порядку…

Первым источником света для человека был огонь: лес, костер, хищники прячутся в окружающей темноте, а люди сидят возле пламени, греются и готовят пищу. Однако с развитием городов и появлением транспорта возникла необходимость в освещении не только собственного жилища, но и улиц. Самые первые городские фонари появились в XV веке в Лондоне. А в начале XVI столетия жителей Парижа обязывали выставлять светильники к окнам, которые выходили на улицу.

В России история городского освещения ведет свое начало с 1706 года, когда в Санкт-Петербурге на фасадах некоторых домов около Петропавловской крепости были вывешены светильники. Первые же стационарные фонари появились на столичных улицах в 1718 году. А «днем рождения» московского освещения считается 25 октября 1730 года, когда магистрат издал указ «О сделании для освещения в Москве стеклянных фонарей».

Впрочем, закончим на этом экскурс в прошлое, поскольку подробный материал о посещении интереснейшего музея «Огни Москвы», где представлены все этапы развития городского освещения, был опубликован в прошлом номере журнала. Лучше сразу перенесемся в 1926 год, когда группа немецких инженеров предложила покрывать внутреннюю поверхность ртутных ламп люминофором — веществом, которое способно поглощать ультрафиолет и переизлучать свет в видимом диапазоне. Так возникла люминесцентная лампа, она же — лампа «дневного света». А в 1960-е годы появились первые промышленно значимые светодиоды. На первых порах это были источники красного (реже — желто-зеленого) света, которые использовались в различных индикаторах. Эффективность их оставляла желать лучшего — всего 1-2 люмена на ватт, что чуть ли не на порядок ниже традиционных ламп накаливания. Тремя десятилетиями позже этот показатель возрос до 30, а к концу тысячелетия — уже до 60 люменов на ватт.

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

Посмотрим еще раз в окно на уличные фонари, которые сами включаются, как только стемнело. Умное освещение — это технология, направленная на увеличение энергоэффективности и комфорта использования искусственных источников света, достигаемое благодаря использованию автоматизированного управления и датчиков освещенности. Первые системы автоматизации внедрялись еще в конце XX века, но появление действительно «умного» освещения можно приурочить лишь к нашему времени, когда началось активное использование LED-ламп (светодиодов). Технология LED позволила не менее чем в пять раз снизить энергозатратность освещения по сравнению с лампами накаливания, а также весьма значительно (до 100 раз) увеличить долговечность одного используемого источника света. Благодаря этим свойствам светодиоды повсеместно вытесняют сегодня даже люминесцентные лампы. А использование с ними датчиков освещенности позволяет реализовать простейшую функцию «умного освещения» — самостоятельно включать и выключать освещение тогда, когда это нужно.

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

ЛАМПОЧКА, ЗАЖГИСЬ!

На прошлых уроках мы работали со светодиодами, а, точнее, освоили, как программно включать и выключать их с заданной периодичностью. Для этого мы пользовались цифровым сигналом, то есть сигналом, который хранит в себе два состояния: 1 — есть напряжение, 2 — нет напряжения. Казалось бы, этого достаточно для того, чтобы управлять различными электронными компонентами. Однако как быть, если необходимо не только включать/выключать светодиод, но и менять его яркость? Или регулировать скорость вращения вала электродвигателя, например? Для этого нужен аналоговый сигнал и широтно-импульсная модуляция (ШИМ). К цифровому сигналу (повторим, у него всего два состояния: есть напряжение (5 В) и нет напряжения (0 В)), добавляется аналоговый — а это уже множество состояний, то есть напряжение меняется от 0 В до 5 В в нашем случае (может быть и другой диапазон).

Схема соединения элементов для режима «пульсации» светодиода
Схема соединения элементов для режима «пульсации» светодиода

Если мы подадим 3 В на светодиод, то он будет светить очень тускло, а если 4 В — ярче. Следовательно, чтобы управлять яркостью светодиода, на него нужно подавать разное напряжение (в пределах рабочего, понятно). Однако микроконтроллер не способен давать «чуть-чуть поменьше» или «чуть-чуть побольше» тока, он умеет работать только с «единицами» и «нулями» — то есть, «есть напряжение» или «нет напряжения», соответственно. Решить данную задачу нам поможет ШИМ. Что это и как работает?

Представим, что светодиод подключен к плате Arduino, одну секунду он горит, другую — гаснет. Такой режим можно назвать миганием — оно заметно глазу. А если светодиод будет выключаться и включаться 40 раз в секунду? Без приборов заметить такое мигание будет практически невозможно — оно сольется в одно действие, как будто светодиод горит «в полнакала». В этом и есть суть ШИМ-сигнала — он управляет промежутком времени включения/ выключения какого-либо вывода (пина) микроконтроллера. А теперь давайте воспользуемся этими знаниями и рассмотрим структуру программы «пульсации» светодиода: его яркость будет увеличиваться до максимума, а потом уменьшаться до минимума.

Вот пример такого скетча:

int bright = 0; //яркость

int change = 5; //значение на которое будет изменяться яркость

int ms = 20; //время задержки

int led = 9; //номер пина к которому подключен светодиод

void setup() {

pinMode(led, OUTPUT);

}

void loop() {

analogWrite(led, bright);

bright = bright + change;

if(bright = 0 || bright = 255){

change = -change;

}

delay(ms);

}

Пройдемся по коду программы сверху вниз, чтобы разобраться, как она работает. В первых четырех строчках мы объявляем переменные. Об этом уже говорилось на предыдущих занятиях. Не понимаете, что означает двойной слэш? Это один из способов написания комментария. Комментарий — это слова, которые не считывает компилятор, а значит, и не загружает их на плату. Комментарии пишутся авторами скетчей для того, чтобы ими мог воспользоваться и изменить другой программист, или же чтобы самому не запутаться в коде при его большом объеме. Существует два вида комментариев:

Однострочный: //комментарий

Многострочный: /*комментарий*/

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

В данном случае в качестве комментариев даны пояснения назначений переменных. Так, например, переменная bright отвечает за яркость свечения светодиода и т.д.:

int bright = 0; //яркость

int change = 5; //значение на которое будет изменяться яркость

int ms = 20; //время задержки

int led = 9; //номер пина к которому подключен светодиод

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

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

analogWrite(номep пина, значение)

Она способна выдавать на пин напряжение от 0 до 5 В с помощью ШИМ-сигнала. Значение напряжения можно указывать в диапазоне 0 — 255, где 0 — это 0 В, 255 — 5 В, а 128 — это половина (то 0 В, то 5 В). Но не каждый пин поддерживает ШИМ. Чтобы понять, какой из них имеет данную функцию, надо на него взглянуть — он помечен символом «~» (тильда).

Схема подсоединения переменного резистора к плате Arduino UNO
Схема подсоединения переменного резистора к плате Arduino UNO

В качестве аргументов функции analogWrite() мы использовали в коде переменную, которая хранит номер пина светодиода, и переменную, которая хранит значение напряжения. И, как уже могли догадаться, мы будем изменять значение bright для того, чтобы увеличивать/уменьшать яркость светодиода:

bright = bright + change;

При каждой итерации loop(), bright увеличится на change. Когда значение дойдет до максимума или минимума, изменим знак числа, хранящегося в переменной change:

change = -change;

Например, если значение дошло до 255, то change должен стать «-5», чтобы bright уменьшался.

Итак, разобрались, как программа будет изменять яркость светодиода. А как она будет отслеживать то, что bright дошла до порога диапазона? В этом поможет оператор if:

if(условие){

}

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

else{

}

Наше условие должно звучать так: если bright равняется 0 (дошел до минимума) или bright равняется 255 (дошел до максимума). Чтобы записать это синтаксически правильно, понадобится оператор сравнения «==» и логический оператор «или» — «||» («дабл бар», «вертикальная палочка», «вертикальный слэш» или «дабл пайп»):

if(bright = 0 || bright = 255) {

change = -change;

}

Осталось только прописать delay(), чтобы все выполнялось не моментально. Вот наша программа и готова.

Мы научились выводить аналоговый сигнал. А что если мы захотим считать его? Для этого понадобится функция analogRead():

analogRead(номер пина)

Но чтобы считывать аналоговый сигнал, нужны пины с аналоговоцифровым преобразователем (АЦП) -это пины с буквой А перед номером. Функция analogRead() возвращает число в диапазоне 0 — 1023, соответствующее напряжению, на считываемом пине (0 В — это 0, 5 В — это 1023). Обратите внимание, что pinMode() для аналоговых входов прописывать не требуется.

Зачем может понадобиться данная функция? Вспомним из школьного курса физики переменные резисторы — это электронные компоненты, которые изменяют свое сопротивление при определенных условиях. Существуют различные типы таких устройств. К примеру, есть потенциометр. Поворачиваем его рукоятку или смещаем «движок», соответственно меняем длину дорожки между выводами: чем она длиннее, тем больше сопротивление. Обычно у потенциометров три ножки, одна из которых — это выход с ползунка. С него и будем считывать изменения напряжения, а другие ножки подключим к пинам 5V и GND.

Схема соединения элементов для макетирования «ночника»
Схема соединения элементов для макетирования «ночника»

Напишем программу, которая при изменении положения ползунка управляет яркостью светодиода:

int pot = Al; //пин потенциометра

int led = 9; //пин светодиода

int val = 0; //значения с потенциометра

void setup(){

pinMode(led, OUTPUT);

}

void loop(){

val = analogRead(pot);

//считываем значение с потенциометра и закидываем в переменную val val = val/4;

/*т.к. мы хотим val использовать в качестве ШИМ-сигнала (0-255), а в нем хранится значение 0-1023 то данное значение нужно поделить на 4 */

analogWrite(led, val);

/*выводим на светодиод ШИМ-сигнап, пропорциональный сигналу с потенциометра */

}

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

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

int photo = A1; //пин фоторезистора

int led = 9; //пин светодиода

void setup(){

pinMode(led, OUTPUT);

}

void loop(){

/*считываем показания фоторезистора сравниваем их со значением принятым за темноту

для примера взято значение 30 */

if(analogRead(photo) > 30) {

// если освещенность низкая, включаем светодиод

digitalWrite(led, HIGH);

}

else{

// иначе светодиод выключен digitalWrite(led, LOW);

}

delay(100);

}

Наш «ночник» будет включатся в сумерках. В темноте фоторезистор имеет сопротивление 100 кОм, а когда освещен — 10 кОм. Соответственно, в пару ему понадобится резистор номиналом 100 кОм.

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

Рекомендуем почитать

  • ЯПОНСКИЕ СВЕРХМАЛЫЕЯПОНСКИЕ СВЕРХМАЛЫЕ
    Вашингтонское морское соглашение 1922 года стало существенным препятствием в нарастающей гонке морских вооружений, начавшейся в годы Первой мировой войны. По этому договору, японский...
  • ТАЧКИ ВСЯКИЕ НУЖНЫТАЧКИ ВСЯКИЕ НУЖНЫ
    Эта тачка была спроектирована (если так можно назвать процесс обдумывания конструкции и прикидок размеров) и изготовлена в течение нескольких часов, после того, как мы с братом получили...
Тут можете оценить работу автора: