#3 Эксперимент “Автоматический светильник”
В этом эксперименте мы будем подключать разберёмся с делителями напряжения и аналоговыми сигналами, научимся отправлять данные в последовательный порт компьютера, а заодно соберём простейший автомат, который позволит включать и выключать вашу настольную лампу в зависимости от внешнего освещения.
Перед выполнением эксперимента прочтите:
На прошлом занятии мы научились считывать цифровые сигнал с пинов Arduino. Для этого мы использовали команду:
digitalRead(pin);
Эта команда возвращала значение цифрового сигнала на пине (номер пина прописывается в скобках). При этом, на цифровом пине могло существовать только 2 вида сигнала – HIGH (высокий, питание на пин подано) и LOW (низкий, питания на пине нет). Сегодня мы попробуем прочитать аналоговый сигнал с аналогового пина Arduino. Такие аналоговые пины находятся на противоположной стороне от цифровых и имеют обозначения A0 … A5 (всего 6 пинов). Эти являются по сути цифровыми вольтметрами (вольтметр – физический прибор для измерения напряжения). Эти пины могут регистрировать напряжение от 0 до 5 Вольт, а затем преобразовывают его во входной аналоговый сигнал в диапазоне [0 … 1023], где:
- 0 – соответствует напряжению в 0 Вольт, т.е. напряжение отсутствует;
- 1023 – соответствует напряжению в 5 В, т.е. на пин приходит максимально возможный сигнал.
А что, если на пин придёт сигнал равный 720? Какое напряжение будет на пине? Это очень легко посчитать, для этого нужно максимальное (опорное) напряжение 5 Вольт, разделить на максимальный уровень сигнала 1023 и помножить на фактический сигнал на пине 720, что будет примерно равно напряжению в 3,52 Вольта.
Аналоговый сигнал мы можем получить с аналоговых датчиков, которые подключаются к Arduino по схеме делителя напряжения. Сегодня мы будем подключать к Arduino один из таких датчиков – фоторезистор и попробуем не просто снять с него аналоговый сигнал, но и заставим наш микроконтроллер управлять внешней нагрузкой (лампой) с помощью этого сигнала.
СБОРКА УСТРОЙСТВА НА МАКЕТНОЙ ПЛАТЕ
Нам понадобятся следующие компоненты:
- Arduino Uno;
- USB-кабель для подключения к компьютеру;
- Беспаечная макетная плата;
- 1 фоторезистор;
- 1 реле;
- 1 светодиод;
- 1 резистор, номиналом 220 Ом;
- 1 резистор, номиналом 10 кОм;
- 9 соединительных проводов разных цветов.
Соберите устройство по следующей схеме:
Схема устройства на макетной плате |
![]() |
Принципиальная схема устройства |
![]() |
Обратите внимание:
- Реле имеет по 3 контакта с одной и с другой стороны. Контакты снизу являются управляющими: крайний левый контакт – сигнальный, который мы будем использовать для управления переключением реле, средний контакт – питание (+5 В), а правый – земля (-). Верхние контакты реле служат для подключения внешней нагрузки (в нашем случае это светодиод). Средний контакт – общий, левый – нормально замкнутый (Normally Closed), а правый – нормально открытый (Normally Open). Таким образом, при выключенном реле, нагрузку подключённая к среднему и правому контактам, будет находится по умолчанию в обесточенном состоянии.
- В роли внешней нагрузки, мы будем использовать светодиод. Он подключен напрямую к контактам питания и земли через токоограничительный резистор, номиналом 220 Ом. При этом, провод идущий к питанию – разорван, а в разрыв подключено реле.
- Фоторезистор мы подключили по схеме делителя напряжения. Этот датчик не имеет полярности, поэтому можно не боятся ошибиться с ногами питания и земли. Контакт идущий на землю, подключён через резистор на 10 кОм, с этого-же контакта мы будем снимать аналоговый сигнал.
Наша задача – запрограммировать это устройство таким образом, чтобы при падения уровня освещённости до определённого значения, Arduino автоматически подавал сигнал на реле и замыкал нормально открытые контакты. При этом, светодиод, подключенный через данное реле, должен зажечься. Он будет выполнять роль “дежурного” освещения.
ПРОГРАММИРОВАНИЕ
Давайте посмотрим – какой сигнал приходит с фоторезистора, подключённого к пину Ao. Для этого мы воспользуемся командой, которая может посылать команды в последовательный пор компьютера, через который подключена плата Arduino. В разделе [setup] инициализируем передачу данных через последовательный порт с помощью команды:
Serial.begin(9600);
где:
- 9600 – скорость передачи данных, измеряемая в битах в секунду (бит/с или бод).
Теперь мы можем посылать данные на компьютер, используя команду:
Serial.print();
или
Serial.println();
- в скобках необходимо указать данные, которые нужно послать в порт компьютера;
- окончание ln используется в случае, если после вывода данных нужно перейти на новую строку.
Для того, чтобы получить сигнал с пина Ao, воспользуемся командой:
analogRead(A0);
Таким образом получим программу:
void setup() { Serial.begin(9600); } void loop() { Serial.println(analogRead(A0)); delay(500); }
Задержка [delay] необходима для того, чтобы избежать большого количества выводимых данных. Загрузите программу в плату Arduino и запустите [Монитор порта], нажав на значок в правом верхнем углу Arduino IDE. Теперь вы можете видеть значения аналогового сигнала, приходящего на пин A0. Попробуйте заслонить фоторезистор рукой или посветить на него фонариком. Посмотрите как при этом изменяется величина сигнала.
На картинке выше сигнал со значениями [368 … 365] соответствует обычному дневному освещению, в момент перекрытия фоторезистора рукой сигнал упал до значений [33 … 22], далее, к фоторезистору был поднесён фонарик, который частично перекрыл его (сигнал – [140]), и наконец, фонарик был включён, при этом сигнал значительно вырос [913 … 966]. Можно сделать вывод, что чем больше света попадает на фоторезистор, тем более высокий сигнал появляется на пине, к которому он подключён.
Теперь, зная значения сигнала, которые посылает фоторезистор при разных уровнях освещённости, мы можем управлять какой-либо нагрузкой. Для этого мы будем использовать реле. Реле используют в тех случаях, когда нужно управлять внешней нагрузкой с помощью малых токов и напряжений. Вспомним, Arduino оперирует сигналами в диапазонах от 0 до 5 В и с помощью Arduino мы никак не сможем запустить мотор, который питается от 12 Вольт или зажечь настольную лампу, которая питается от 220 Вольт переменного тока. В нашей схеме, в качестве внешней нагрузки будет выступать светодиод. Обратите внимание: светодиод питается от пина 5V, т.е. мы не будем управлять его свечением с помощью какого-либо из цифровых пинов. Для чистоты эксперимента, светодиод можно запитать от внешнего источника питания, например батарейки.
Для того, чтобы включать и выключать светодиод с помощью реле, мы разорвали провод, ведущий к пину 5V и подключили концы проводов к среднему и крайнему правому контактам реле. Эта пара контактов называется “нормально открытой” (NO), и при отсутствии напряжения на реле эти контакты будут находится в разомкнутом состоянии, т.е. наш светодиод будет погашен. Для того, чтобы зажечь его, на сигнальный контакт реле (нижний левый) следует подать высокий цифровой сигнал. Для этого мы воспользуемся командой:
digitalWrite(8, HIGH);
В скобках указываем 8-й пин, так как именно к нему подключено реле.
Алгоритм работы нашей программы будет очень прост: если сигнал с фоторезистора упадёт до 200 и ниже, мы должны замкнуть реле и включить светодиод. Если сигнал с фоторезистора вырастет до 600 и выше, мы должны будет отключить светодиод. Напишем программу (комментарии будут приводится внутри кода программы):
void setup() { pinMode(8, OUTPUT); // назначаем 8-й пин на выход } void loop() { int lightness=analogRead(A0); // переменная для хранения значения сигнала с фоторезистора if (lightness<200){ // если сигнал ниже 200... digitalWrite(8, HIGH); // ... то подаём на реле высокий сигнал (5 Вольт) } if (lightness>600){ // если сигнал выше 600... digitalWrite(8, LOW); // ... то подаём на реле низкий сигнал (0 Вольт) } }
Программа, которую мы написали проста и не универсальна, т.к. она будет работать корректно лишь при данных жёстко заданных параметрах освещения. Для того, чтобы мы могли использовать наше устройство в любой комнате, нам необходимо производить его калибровку, т.е. каждый раз заново настраивать условия включения и выключения реле. Усовершенствуем программу, заставив её делать калибровку автоматически. Ниже приведён код готовой программы, который мы сейчас подробно разберём:
int calibration=0; // переменная для хранения калибровочной освещённости int lightness_day=0; // переменная для хранения дневной освещённости int lightness_night=0; // переменная для хранения ночной освещённости int lightness=0; // переменная для хранения текущей освещённости void setup() { pinMode(8, OUTPUT); // назначаем 8-й пин на выход calibration=analogRead(A0); //запоминаем текущий сигнал с фоторезистора lightness_day=calibration+120; // устанавливаем значение дневного сигнала lightness_night=calibration+20; // устанавливаем значение ночного сигнала } void loop() { lightness=analogRead(A0); // получаем текущую освещённость с фоторезистора if (lightness<lightness_night){ // если текущий сигнал меньше ночного digitalWrite(8, HIGH); // ... то подаём на реле высокий сигнал (5 Вольт) } if (lightness>lightness_day){ // если больше дневного. digitalWrite(8, LOW); // ... то подаём на реле низкий сигнал (0 Вольт) } }
Большая часть комментариев находится внутри кода, но для полного понимания – разберём его более подробно:
- устройство необходимо включать в тот момент, когда освещение в комнате станет настолько слабым, что понадобится включение лампы;
- после включения устройства, в переменную calibration сохраняется текущий сигнал с фоторезистора. Это и будут калибровочные значения сигнала;
- далее, в переменную lightness_day сохраняется значение сигнала на 120 большее, чем калибровочный. В дальнейшем именно это значение сигнала будет означать, что пора выключать лампу. Это “дневное” значение сигнала;
- в переменную lightness_night помещается сигнал лишь немного больший чем калибровочный (на 20). Это значение мы будем использовать для того, чтобы определить когда следует зажигать лампу. Это “ночное” значение сигнала.
Пример: предположим, что мы включили наше устройство и на пине с фоторезистором появился сигнал 450. Тогда дневной сигнал будет равне 450+120=570, а ночной – 450+20=470. Обратите внимание, что разница между дневным и ночным сигналами составляет: 570-470=100. Т.е. пока на фоторезисторе будет сигнал в диапазоне [470..570], программа не будет делать ничего. Если в это время реле будет включено, то оно так и останется включённым, а если выключено, то так и останется выключенным. Эту область можно назвать областью релаксации и она необходима для того, чтобы избежать ложных срабатываний устройства. Это может произойти тогда, когда реле только-только включилось, а за окном проехал автомобиль с включёнными фарами и блик, попавший на фоторезистор кратковременно может увеличить сигнал, посылаемый им, и только что включённая лампа снова выключится.
- в разделе [loop] находится уже знакомый Вам код. Разница лишь в том, что мы сравниваем текущий сигнал с фоторезистора не с конкретными фактическими значениями, а со значениями дневного и ночного сигналов, которые были получены в ходе калибровки.
Обратите внимание: все переменные вынесены на самый верх и располагаются перед разделом [setup]. Такие переменные называются глобальными, т.е. их можно использовать в любом месте нашей программы. При перезагрузке платы Arduino, все значения снова сбрасываются на 0 и происходит повторная калибровка.
Наша программа готова и при желании, Вы можете заменить светодиод, подключённый к реле на любую другую нагрузку, например свою настольную лампу. Ведь реле может управлять даже высоковольтными нагрузками. Для этого достаточно разорвать один из проводов вашей лампы и подключить их к контактам реле.
Внимание! Данную схему необходимо собирать только вместе с педагогом или родителями, т.к. в ней присутствуют элементы, которые будут находится под высоким напряжением и ошибочно собранная схема может привести к короткому замыканию!
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО ВЫПОЛНЕНИЯ
Задание 1:
Добавьте в схему устройства кнопку и измените программу таким образом, чтобы калибровка устройства происходила лишь при нажатии кнопки.
Задание 2*:
По приведённой ниже схеме соберите измеритель освещённости, состоящий из 5 светодиодов и фоторезистора. Напишите программу, которая будет использовать светодиоды в качестве шкалы, и будет зажигать тем больше светодиодов, чем больше света попадает на фоторезистор.