Счетчик миллисекунд на ардуино

Ардуино задержка: delay и millis без delay

Функции delay(), millis() и delayMicroseconds() Arduino играют важную роль и написание большинства скетчей без этих команд практически невозможно. На нашем сайте вы найдете множество уроков и проектов с millis(), где необходим отсчет времени или с delay(), например, чтобы избежать дребезга контактов у тактовой кнопки. Рассмотрим назначение и применение команд задержки времени в Ардуино программировании.

Ардуино задержка включения / выключения

Для занятия нам потребуется:

  • Arduino Uno / Arduino Nano / Arduino Mega.

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

Ардуино delayMicroseconds()

Команда delayMicroseconds останавливает выполнение программы на заданное количество микросекунд (в 1 секунде 1 000 000 микросекунд). При необходимости задержки в программе более чем на несколько тысяч микросекунд рекомендуется использовать delay(). Продемонстрируем на простом примере использование функции в скетче для мигания встроенным светодиодом на плате Arduino.

Ардуино delay()

Команда delay останавливает выполнение программы на заданное количество миллисекунд (в 1 секунде 1 000 миллисекунд). Во время задержки программы с помощью функции delay(), не могут быть считаны подключенные к плате датчики или произведены другие операции, например, запись в еепром Ардуино данных. В качестве альтернативы следует использовать функцию millis(). Смотри пример далее.

Ардуино millis()

Команда millis возвращает количество прошедших миллисекунд с момента начала выполнения программы. Счетчик времени сбрасывается на ноль при переполнении значения unsigned long (приблизительно через 50 дней). Функция miilis позволяет сделать многозадачность Ардуино, так как выполнение программы не останавливается и можно выполнять параллельно другие операции в скетче.

Arduino команды millis, delay, delaymicroseconds

Используем в Ардуино millis вместо delay

В последнем примере вывод счетчика на мониторе порта прерывается на время задержки в программе delay(1000); — в этом заключается главное отличие этих функций. При подключении датчиков к плате необходимо получать данные от них постоянно, поэтому команду delay заменяют на millis. Как это сделать в скетче для Arduino IDE с мигающим светодиодом — продемонстрируем в следующем примере.

Заключение. Команда millis Arduino не останавливает выполнения программы, а начинает отсчет времени с начала запуска счетчика в миллисекундах. В отличии от этого, delay и delayMicroseconds останавливают выполнение программы на заданное количество миллисекунд или микросекунд соответственно. Применение определенной задержки в скетче Ардуино микроконтроллеров зависит от поставленной задачи.

Источник

Многозадачность в Arduino с помощью функции millis()

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

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

Что такое многозадачность

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

Как показано на представленном рисунке, микропроцессор делит общее время на 3 равные части и в каждой части времени выполняет отдельную задачу. Таким образом реализуется концепция многозадачности в большинстве современных компьютерных систем. Аналогичный подход мы применим и в нашем проекте для Arduino, однако распределение времени на разные задачи будет немного отличаться. Поскольку плата Arduino работает на значительно меньшей частоте чем современные персональные компьютеры и объем оперативной памяти у нее значительно меньше, то и время, выделяемое на каждую задачу, будет различным.

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

Почему стоит воздержаться от использования функции delay() в Arduino

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

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

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

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

Почему стоит использовать функцию millis()

Для преодоления проблем, описанных в предыдущем пункте данной статьи, вызванных использованием функции delay(), можно использовать функцию millis() . Использование данной функции позволит более гибко использовать вычислительные возможности платы Arduino, не прибегая к полному останову программы как в случае использования функции delay(). millis() – это функция, которая возвращает количество миллисекунд, прошедших с момента начала выполнения платой Arduino текущей программы. Никакого останова программы во время использования этой функции не происходит. Счетчик этой функции будет переполняться (то есть сбрасываться в ноль) примерно через 50 дней функционирования программы.

Также как и в случае с функцией delayMicroseconds(), в Arduino имеется аналогичная функция и для функции millis() – это функция micros() . Она работает так же как и millis(), но счет ведет в микросекундах. Ее счетчик переполняется примерно через 70 минут функционирования программы.

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

Источник

Функции времени

Задержки

Простейшей с точки зрения использования функцией времени является задержка: программа “зависает” внутри функции задержки и ожидает указанное время. Задержка позволяет очень удобно и наглядно организовать работу простой “однозадачной” программы, у нас есть два варианта задержек:

  • delay(time)
    • Задержка на указанное количество миллисекунд (мс). 1 секунда = 1’000 мс.
    • time принимает тип данных unsigned long и может приостановить выполнение на срок от 1 до 4 294 967 295 мс (

    50 суток) с разрешением 1 мс.

  • Работает на системном таймере, поэтому не работает внутри прерывания и при отключенных прерываниях.
  • delayMicroseconds(time)
    • Задержка на указанное количество микросекунд (мкс). 1 секунда = 1’000’000 мкс.
    • time принимает тип данных unsigned int и может приостановить выполнение на срок от 4 до 16383 мкс (да, меньше чем максимум для этого типа данных) с разрешением 4 мкс.
    • Работает не на таймере, а на пропуске тактов процессора, поэтому может работать в прерывании и при отключенных прерываниях.
    • Иногда не совсем корректно работает с переменными, поэтому нужно стараться использовать константы ( const или просто число).
    • Часто используется в библиотеках для эмуляции цифровых интерфейсов связи.
  • Задержки использовать очень просто:

    Мышление “задержками” – главная проблема новичков. Организовать работу сложной программы при помощи задержки – невозможно, поэтому дальше рассмотрим более полезные инструменты.

    Функция yield()

    Разработчики Arduino позаботились о том, чтобы функция delay() не просто блокировала выполнение кода, но и позволяла выполнять другой код во время этой задержки. Данный “костыль” получил название yield() и работает следующим образом: если объявить функцию

    то расположенный внутри неё код будет выполняться во время работы любой задержки delay() в программе! Это решение хоть и кажется нелепым, но в то же время позволяет быстро и без написания лишних костылей и таймеров реализовать пару параллельно выполняющихся задач. Это вполне соответствует идеологии Arduino – максимально простая и быстрая разработка прототипа. Рассмотрим простой пример: стандартный мигающий светодиод, но с опросом кнопки:

    Функции счёта времени

    Данные функции возвращают время, прошедшее с момента запуска программы, так называемый аптайм (англ. uptime). Таких функций у нас две:

      millis() – миллисекунды, тип unsigned long , от 1 до 4 294 967 295 мс (

    50 суток), разрешение 1 мс. После “переполнения” отсчёт начинается с нуля.
    micros() – микросекунды, тип unsigned long , от 4 до 4 294 967 295 мкс (

    70 минут), разрешение 4 мкс. После “переполнения” отсчёт начинается с нуля.

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

    millis() в часы и секунды

    Миллисекунды – не самый удобный способ оценить время работы программы. Можно перевести его в более человеческие часы, минуты и секунды при помощи нехитрых математических операций:

    Видео

    Источник

    Arduino — функции — время

    Функция millis()

    Функция millis() позволяет считать время, прошедшее с момента запуска текущей программы. Функция возвращает значение в формате «unsigned long» и позволяет считать значения до 50 дней с момента запуска программы. По прошествии этого времени отсчет начнется заново. Ниже приведен пример использования функции millis():
    [slh lang=»php»] unsigned long time;
    void setup() <
    Serial.begin(9600);
    >
    void loop() <
    Serial.print(«Время включения: «);
    time = millis(); // запомнить значение времени
    Serial.println(time); // отправка информации через последовательный порт
    delay(1000);
    >
    [/slh]

    В приведенном выше примере, каждую секунду в монитор порта будет отправляться информация о времени, которое прошло с момента запуска программы. Поскольку время измеряется в миллисекундах, то каждое последующие значение будет отличаться на 1000. Точность считывания зависит от стабильности кварцевого резонатора Arduino.

    Функция micros()

    Функция micros() является аналогом функции millis(), разница заключается в точности измерения. С помощью функции micros() мы получим время, прошедшее от запуска текущей программы в микросекундах. Счетчик подсчитанных микросекунд будет сброшен по истечении 70 минут. Ниже приведен пример использования функции micros():
    [slh lang=»php»] unsigned long time;
    void setup() <
    Serial.begin(9600);
    >
    void loop() <
    Serial.print(«Время с момента запуска: «);
    time = micros();
    Serial.print(time);
    Serial.println(» мкс «);
    delay(1000);
    >
    [/slh] Так же, как и в примере с функцией millis(), здесь каждую секунду в монитор порта будет отправляться информация об измеренном времени, разница состоит только в том, что в данном случае время измеряется в микросекундах.

    Функция delay()

    Функция delay() позволяет приостановить выполнение текущей программы на указанное в параметре время. Синтаксис команды выглядит следующим образом:
    [slh lang=»php»] //команды
    delay(500); //задержка на 0,5 сек
    //команды
    delay(1000); //задержка на 1с
    [/slh]

    Время указывается в миллисекундах (1 сек = 1000 мс). Данный параметр может иметь тип «unsigned long», который находится в диапазоне от 0 до 4294967295. Ниже пример использования команды delay():
    [slh lang=»php»] #define ledPin 13
    void setup()
    <
    pinMode(ledPin,13);
    >
    void loop()
    <
    digitalWrite(ledPin,HIGH); //включить LED
    delay(500); //подождать 500ms (0,5 сек)
    digitalWrite(ledPin,LOW); //выключить LED
    delay(1000); //подождать 1000 мс (1 сек)
    >
    [/slh]

    В приведенном выше примере, светодиод загорается на 0,5 секунды, затем гаснет на 1 секунду и так далее, пока питание Arduino не будет отключено.

    Функция delayMicroseconds()

    Функция delayMicroseconds() является разновидностью функции delay(). Разница заключается в количестве и точности отсчета времени. Функция delay() позволяет отсчитывать время с точностью до 1 миллисекунды, в то время как delayMicroseconds() с точностью до 1 микросекунды.

    Значение, которое можно указать в параметре, находиться в диапазоне от 0 до 16383. Для более длинных временных интервалов следует использовать функцию delay() или несколько раз использовать delayMicroseconds().
    [slh lang=»php»] #define outPin 8
    void setup()
    <
    pinMode(outPin, OUTPUT); // контакт 8 как выход
    >
    void loop()
    <
    digitalWrite(outPin, HIGH); // контакт 8 высокое состояние
    delayMicroseconds(50); // пауза 50 микросекунд
    digitalWrite(outPin, LOW); // контакт 8 низкое состояние
    delayMicroseconds(50); // пауза 50 микросекунд
    >
    [/slh]

    Этот пример генерирует меандр с периодом 100 микросекунд и заполнением 50%.

    Источник

    Adblock
    detector