Home News

Arduino delay и millis - Как реализовать задержку в ардуино без delay

27.08.2018

видео Arduino delay и millis - Как реализовать задержку в ардуино без delay

Уроки Arduino #4 - временные функции

Задержки в Ардуино играют очень большую роль. Без них не сможет работать даже самый простой пример Blink, который моргает светодиодом через заданный промежуток времени. Но большинство начинающих программистов мало знают о временных задержках и используют только Arduino delay, не зная побочных эффектов этой команды. В этой статье я подробно расскажу о временных функциях и особенностях их использования в среде разработки Arduino IDE.


Урок 16.2|Программирование и схемотехника|Arduino|Millis Таймер

Функции времени в Ардуино

В Arduino cуществует несколько различных команд, которые отвечают за работу со временем и паузы:

delay() delayMicroseconds() millis() micros()

Они отличаются по точности и имеют свои особенности, которые стоит учитывать при написании кода.


Прерывание по таймеру в Arduino стили

Использование функции arduino delay

Синтаксис

Ардуино delay является самой простой командой и её чаще всего используют новички. По сути она является задержкой, которая приостанавливает работу программы, на указанное в скобках число миллисекунд. (В одной секунде 1000 миллисекунд.)  Максимальное значение может быть 4294967295 мс, что примерно ровняется 50 суткам. Давайте рассмотрим простой пример, наглядно показывающий работу этой команды.

void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); // подаем высокий сигнал на 13 пин delay(10000); // пауза 10000мс или 10 секунд digitalWrite13, LOW); // подаем низкий сигнал на 13 пин delay(10000); // пауза 10000мс или 10 секунд }

В методе  setup прописываем, что пин 13 будет использоваться, как выход. В основной части программы сначала на пин подается высокий сигнал, затем делаем задержку в 10 секунд. На это время программа как бы приостанавливается. Дальше подается низкий сигнал и опять задержка и все начинается сначала. В итоге мы получаем, что на пин поочередно подается, то 5 В, то 0.

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

Пример delay с миганием светодиодом

Пример схемы для иллюстрации работы функции delay.

Можно построить схему со светодиодом и резистором. Тогда у нас получится стандартный пример – мигание светодиодом. Для этого на пин, который мы обозначили как выходной, необходимо подключить светодиод плюсовым контактом. Свободную ногу светодиода через резистор приблизительно на 220 Ом (можно немного больше) подключаем на землю.  Определить полярность можно, если посмотреть на его внутренности. Большая чашечка внутри соединена с минусом, а маленькая ножка с плюсом. Если ваш светодиод новый, то определить полярность можно по длине выводов: длинная ножка — плюс, короткая – минус.

Функция delayMicroseconds

Данная функция является полным аналогом delay за исключением того, что единицы измерения у нее не миллисекунды, а микросекунды (в 1 секунде – 1000000 микросекунд). Максимальное значение будет 16383, что равно 16 миллисекундам. Разрешение равно 4, то есть число будет всегда кратно четырем. Кусочек примера будет выглядеть следующим образом:

digitalWrite(2, HIGH); // подаем высокий сигнал на 2 пин delayMicroseconds(16383); // пауза 16383мкс digitalWrite(2, LOW); // подаем низкий сигнал на 2 пин delayMicroseconds(16383); // пауза 16383мкс

Проблема с delayMicroseconds точно такая же, как у delay — эти функции полностью «вешают» программу и она на некоторое время буквально замирает. В это время невозможна работа с портами, считывание информации с датчиков и произведение математических операций.  Для мигалок данный вариант подходит, но опытные пользователи не используют её для больших проектов, так как там не нужны такие сбои. Поэтому, гораздо лучше использовать функции, описанные ниже.

Функция millis вместо delay

Функция millis() позволит выполнить задержку без delay на ардуино, тем самым обойти недостатки предыдущих способов. Максимальное значение параметра millis такое же, как и у функции delay (4294967295мс или 50 суток). При переполнении значение просто сбрасывается в 0, не забывайте об этом.

С помощью millis мы не останавливаем выполнение всего скетча, а просто указываем, сколько времени ардуино должна просто «обходить» именно тот блок кода, который мы хотим приостановить. В отличие от delay millis сама по себе ничего не останавливает. Данная команда просто возвращает нам от встроенного таймера микроконтроллера количество миллисекунд, прошедших с момента запуска. При каждом вызове loop Мы сами измеряем время, прошедшее с последнего вызова нашего кода и если разница времени меньше желаемой паузы, то игнорируем код. Как только разница станет больше нужной паузы, мы выполняем код, получаем текущее время с помощью той же millis и запоминаем его — это время будет новой точкой отсчета. В следующем цикле отсчет уже будет от новой точки и мы опять будем игнорировать код, пока новая разница millis и нашего сохраненного прежде значения не достигнет вновь желаемой паузы.

Задержка без delay с помощью millis требует большего кода, но с ее помощью можно моргать светодиодом и ставить на паузу скетч, не останавливая при этом систему. 

Вот пример, наглядно иллюстрирующий работу команды:

unsigned long timing; // Переменная для хранения точки отсчета void setup() { Serial.begin(9600); } void loop() { /* В этом месте начинается выполнение аналога delay() Вычисляем разницу между текущим моментом и ранее сохраненной точкой отсчета. Если разница больше нужного значения, то выполняем код. Если нет - ничего не делаем */ if (millis() - timing > 10000){ // Вместо 10000 подставьте нужное вам значение паузы timing = millis(); Serial.println ("10 seconds"); } }

Сначала мы вводим переменную timing, в ней будет храниться количество миллисекунд. По умолчанию значение переменной равно 0. В основной части программы проверяем условие: если количество миллисекунд с запуска микроконтроллера минус число, записанное в переменную timing больше, чем 10000, то выполняется действие по выводу сообщения в монитор порта и в переменную записывается текущее значение времени. В результате работы программы каждые 10 секунд в монитор порта будет выводиться надпись 10 seconds. Данный способ позволяет моргать светодиодом без delay.

Функция micros вместо delay

Данная функция так же может выполнить задержку, не используя команду delay. Она работает точно так же, как и millis, но считает не миллисекунды, а микросекунды с разрешением в 4мкс. Её максимальное значение 4294967295 микросекунд или 70 минут. При переполнении значение просто сбрасывается в 0, не забывайте об этом.

Резюме

Платформа Arduino предоставляет нам несколько способов выполнения задержки в своем проекте. С помощью delay вы можете быстро поставить на паузу выполнение скетча, но при этом заблокируете работу микроконтроллера. Использование команды millis позволяет обойтись в ардуино без delay, но для этого потребуется чуть больше программировать. Выбирайте лучший способ в зависимости от сложности вашего проекта. Как правило, в простых скетчах и при задержке меньше 10 секунд используют delay. Если логика работы сложнее и требуется большая задержка, то вместо delay лучше использовать millis.

rss