Шрифт:
Интервал:
Закладка:
Поэтому я упрощу задачу. Индикатором в нашем устройстве будет маленький желтый светодиод на плате Arduino. Представим себе, что этот индикатор является комнатным обогревателем, который включается, когда холодно, и выключается, когда тепло.
Гистерезис
Предположим, мы нагреваем теплицу, температура в которой должна составлять 30 °C. Допустим, напряжение комбинации «терморезистор-резистор» при этой температуре составляет 2,3 В. Отыщите его на графике (см. рис. 5.89), и вы увидите, что АЦП внутри микроконтроллера преобразует это напряжение в числовое значение около 470.
Таким образом, наш порог – 470. Если значение снижается до 469, мы включаем нагрев (или имитируем его включением светодиода). Если значение возрастает до 471, мы выключаем нагрев.
Однако, постойте. Имеет ли это смысл? Ведь даже самое небольшое повышение температуры, воспринимаемое терморезистором, будет включать светодиод, а незначительное понижение будет выключать его. Система будет все время включаться и выключаться.
Обычный термостат не реагирует на небольшие изменения температуры, когда кто-то открывает или закрывает дверь. Когда он включается, он остается включенным до тех пор, пока температура не станет чуть выше установленного значения. Затем, когда он прекращает нагрев, он остается выключенным, пока температура не опустится немного ниже указанного значения.
Такое поведение называется гистерезисом, и я расскажу о нем более детально в связи с компонентом, который называется компаратором, в моей следующей книге – продолжении данной: Make: More Electronics.
Как мы можем реализовать гистерезис в программе для микроконтроллера? Нам необходим более широкий диапазон значений, чем числа от 469 до 471. Программа могла бы описывать следующее: «Если светодиод включен, пусть он остается в этом состоянии, пока значение температуры не превысит 490. Затем его следует выключить». А также: «Если светодиод выключен, пусть он будет в таком состоянии, пока значение температуры не упадет ниже 460. Затем его надо включить».
Сможем ли мы это сделать? Да, очень легко. Программа, представленная в листинге 5.1, функционирует именно так. Протестировав эту программу, я сделал снимок экрана в среде Arduino IDE, и поэтому у меня есть веские основания полагать, что она работает.
Листинг 5.1
Эта программа содержит также некоторые новые понятия – но для начала введите ее в среду IDE. Не обязательно включать все строки комментариев, которые я добавил только для пояснения.
В более коротком варианте программы (листинг 5.2) строки комментариев опущены.
Листинг 5.2
Выполните проверку/компиляцию вашей программы и при необходимости исправьте опечатки (возможно, вы где-либо пропустили точку с запятой – это самая распространенная ошибка).
Подключите плату Arduino, загрузите программу, и если температура вашего терморезистора ниже 30 °C, должен зажечься желтый светодиод.
Нагрейте терморезистор, зажав его между пальцами, как будто температура в помещении увеличилась. Спустя несколько секунд светодиод погаснет. Теперь отпустите терморезистор, и он остынет, но светодиод еще продолжит гореть некоторое время, потому что гистерезис в данной системе заставляет выждать, пока температура не станет достаточно низкой. В конечном счете, светодиод загорится снова. Получилось!
Но как же работает эта программа?
Строка за строкой
В программе существует такое понятие, как переменная. Это небольшая область памяти микроконтроллера, где может храниться числовое значение. Вы можете представить ее как «ячейку памяти». Из программы можно обратиться к ячейке при помощи имени переменной. Внутри ячейка содержит числовое значение.
Строка int digitemp = 0; означает, что объявил переменную с именем digitemp. Она является целочисленной (целым числом) и принимает значения начиная с нуля.
В строке int ledstate = 0; я объявил еще одну целочисленную переменную, чтобы отслеживать состояние светодиода на плате (включен или выключен). Нельзя попросить микроконтроллер посмотреть на светодиод и сказать, в каком он состоянии, поэтому я должен самостоятельно предусмотреть все требуемые действия.
Команда pinMode (13, OUTPUT) в секции setup сообщает микроконтроллеру о том, что следует сконфигурировать контакт 13 как выход. Задавать режим работы контакта А0 в качестве входа нет необходимости, потому что аналоговые выводы являются входами по умолчанию.
Теперь перейдем к основной части программы, К циклу. Сначала я задал команду analogRead, чтобы микроконтроллер прочитал состояние аналогового порта. Какого? Я указал 0, что означает аналоговый порт А0. В него вставлен проводник от моей макетной платы.
Что я собираюсь делать с информацией от АЦП после того, как она будет считана с порта? Есть только одно разумное место ее размещения: в переменной digitemp, которую я создал для этой цели.
Теперь, когда переменная digitemp содержит значение, я могу проверить ее. Если нагреватель включен (светодиод горит) И значение digitemp больше 490, то пора выключить нагреватель. Условие «если» проверяется следующим образом:
if (ledstate == 1 && digitemp > 490)
Двойной знак равенства (==) означает «выполнить сравнение и выяснить, одинаковы ли эти два значения». Одиночный знак равенства означает другую операцию: «назначить данное значение переменной».
Двойной символ & – это «логическое И». Да, здесь у нас применяется булева логика, как и в логическом элементе И. Но вместо того чтобы подключать микросхему, мы просто пишем строку кода.
Символ > означает «больше, чем».
Проверка условия «если» помещена в круглые скобки. Если утверждение в круглых скобках истинно, то микроконтроллер выполняет процедуру, расположенную между фигурными скобками. В этой процедуре с помощью команды ledstate = 0 записан тот факт, что светодиод будет выключен. Команда digitalWrite (13, LOW); в действительности выключает светодиод.
Вторая проверка условия «если» очень похожа, за исключением того, что она применяется, если светодиод выключен, а температура сильно снизилась. Тогда мы зажигаем светодиод.
Наконец, введена задержка на десятую долю секунды, поскольку нам не нужно проверять температуру чаще.
Вот и все.
Нюансы программирования
Я объяснил здесь лишь некоторые синтаксические структуры, например, проверку условия «если» и двойной знак равенства, а также логический оператор && без перечисления всего списка конструкций, которые есть в языке С. Необходимые дополнительные сведения вы всегда сможете найти онлайн.
Запомните несколько моментов, относящихся к программе:
• Строки набраны с отступами, чтобы улучшить восприятие логической структуры программы. Компилятор игнорирует дополнительные пробелы, поэтому вы можете спокойно добавлять их в любом количестве.
• Для удобства среда IDE выделяет ошибки в тексте программы цветом.
• Когда вы присваиваете имя переменной, допустимо любое сочетание букв,