Diy

Функция задержки Arduino, и почему вы не должны ее использовать

Функция задержки Arduino, и почему вы не должны ее использовать

Когда вы впервые начали изучать, как разрабатывать для Arduino , вы, вероятно, создали продукт, который работает примерно так:

К вашему Arduino будет подключен один светодиод. Это будет включать и выключать каждую секунду или около того, и будет продолжаться, пока Arduino не будет выключен. Это программа «Hello World» от Arduino , которая прекрасно иллюстрирует, как всего несколько строк кода могут создать что-то осязаемое.

Arduino под руководством

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

Как работает Delay ()

Принцип работы функции delay () довольно прост. Он принимает одно целое число (или номер) аргумент. Это число представляет время (измеренное в миллисекундах), в течение которого программа должна дождаться перехода к следующей строке кода.

Но проблема в том, что функция delay () не является хорошим способом заставить вашу программу ждать, потому что это так называемая «блокирующая» функция.

Разница между блокирующими и неблокирующими функциями

Чтобы проиллюстрировать, почему блокирующие функции плохи, я хочу, чтобы вы представили на кухне двух разных поваров: Генри Блокинга и Эдуардо Нон Блокинга . Оба выполняют одну и ту же работу, но совершенно разными способами.

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

Arduino-повар

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

Это глупая аналогия, но она иллюстрирует суть.

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

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

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

Знакомьтесь, Миллис ()

Функция millis () выполняет одну задачу. При вызове возвращает (в виде длинного типа данных) количество миллисекунд, прошедших с момента первого запуска программы. Итак, почему это полезно?

Потому что, используя немного простой математики, вы можете легко «оценить» аспекты вашей программы, не влияя на ее работу. Ниже приведена базовая демонстрация того, как работает millis (). Как вы увидите, программа включает светодиодный индикатор на 1000 миллисекунд (одну секунду), а затем выключает его. Но, что самое важное, он делает это не блокирующим образом.

Теперь давайте посмотрим, как это работает с Arduino.

Arduino-Миллис-пример

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

А поскольку он неблокирующий, любой код, находящийся вне этого первого оператора if, должен работать нормально.

Просто, не правда ли? Обратите внимание, как мы создали переменную currentTime как беззнаковый long. Значение без знака просто означает, что оно никогда не может быть отрицательным; мы делаем это так, чтобы максимальное количество, которое мы можем хранить, было больше. По умолчанию числовые переменные подписаны, что означает, что один «бит» памяти для этой переменной используется для хранения положительного или отрицательного значения. Указав, что оно будет только положительным, у нас есть один дополнительный бит для игры.

Прерывания

До сих пор мы узнали об одном способе приближения времени к нашей программе Arduino, который лучше, чем delay () . Но есть и другой, гораздо лучший способ, но более сложный: прерывания . У них есть то преимущество, что вы можете точно рассчитать время своей программы Arduino и быстро реагировать на внешний вход, но асинхронно .

Это означает, что он работает вместе с основной программой, постоянно ожидая, когда произойдет событие, не прерывая поток вашего кода. Это помогает эффективно реагировать на события, не влияя на производительность процессора Arduino.

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

Микросхема AVR, питающая Arduino, поддерживает только аппаратные прерывания. Это происходит, когда входной контакт переключается с высокого на низкий уровень или срабатывает встроенными таймерами Arduino.

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

Не блокируйся

Использование millis (), по общему признанию, требует немного дополнительной работы по сравнению с использованием delay () . Но поверьте мне, ваши программы будут вам благодарны, и вы не сможете сделать многозадачность на Arduino без нее.

Если вы хотите увидеть пример функции millis (), используемой в реальном проекте Arduino, ознакомьтесь с Arduino Night Light и Sunrise Alarm Джеймса Брюса.

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

Авторы фотографий: Ардуино (Дэниел Спиесс) , шеф-повар (Олли Свенсон)

Похожие посты
Diy

Вещи, которые вы должны иметь в виду, прежде чем брать ноутбук или смартфон в службу технической поддержки

Diy

Как использовать Arduino для съемки красивой скоростной фотографии

DiyLinux

Пять великолепных расширений Raspberry Pi, которые делают его еще более полезным

Diy

Первые шаги с Arduino: пристальный взгляд на печатную плату и структуру программы