Как обнулить millis arduino
Перейти к содержимому

Как обнулить millis arduino

  • автор:

Arduino.ru

Всем не равнодушным привет!
Решил реанимировать старый вопрос. Задача такова, нужно что бы отображался остаток времени до включения таймера, в формате чч:мм:cc Не спрашивайте зачем. Пока что выдаю в сериал монитор, там дальше будет видно. Графически себе представляю это примерно так.

Наваял такой не замысловатый код.

uint32_t previousMillis = 0; // время, когда таймер последний раз сработал. const long interval = 1; // цикличность обратного отсчета времени 1 сек. bool triggerActive = false; //переменные для отслеживания, были ли активированы триггеры или нет. uint32_t timer; // Переменные хранения времени uint8_t t1 = 13 // 13 период включения 13 сек. uint8_t t3 = 5 // длительность 5 сек. void loop() < // ############# Вывод остатка времени до включения таймера ############## uint32_t currentMillis = millis() / 1000; // объявляем переменную currentMillis в секундах if (currentMillis - previousMillis >= interval) < uint32_t remains = t1 * 3600 - currentMillis; // переменная остатка в секундах uint8_t H = remains / 3600; // остаток часов uint8_t M = (remains % 3600) / 60; // остаток минут uint8_t S = (remains % 3600) % 60; //остаток секунд if (ledState == "1") // если таймер сработал то выполняем код ниже. < char buffer1[9]; sprintf(buffer1, "%02d:%02d:%02d", H, M, S); Serial.println(buffer1); // отобразим обратный отсчет времени >else < Serial.println("ON"); >previousMillis = currentMillis; > // ################# Собственно сам таймер #################### if (currentMillis - timer >= (ledState ? t3 : t1) && !triggerActive) < timer = currentMillis; ledState = !ledState; Serial.println("timer ON"); >>

Как видим, таймер построен на millis, работает нормально. Но обратный отсчет работает криво. Включаю контроллер пошел обратный отсчет времени. Через заданное время таймер срабатывает и отсчет прекращается, в сериал монитор как и положено выдало статус «ON». По достижению времени отключения таймер отключается и тут снова должен начаться обратный отсчет с нуля, до
следующего включения таймера. Вместо этого начинает казать какое-то левое время. Мне кажется в строке 15 что то криво у меня посчитано. Поможите выйти из штопора затупления?

  • Войдите на сайт для отправки комментариев

Arduino UNO урок 3 — Тайминг

Обратимся к первому уроку, где мы управляли LED. Между включением и выключением которого была секундная задержка. В используемой там программе (см. код ниже) был один очень большой недостаток. Для выдержки паузы между вкл/выкл LED в 1 сек. нами была использована функция delay(). В это время контроллер не может выполнять другие команды в главной функции loop()

/* Мигание LED * ------------ * * Включает и выключает светодиод (LED) подсоединенный * к выходу 13, с интервалом в 2 секунды * */ int ledPin = 13; // LED подсоединен к выводу 13 void setup() < pinMode(ledPin, OUTPUT); // устанавливаем вывод 13 как выход >void loop() < digitalWrite(ledPin, HIGH); // включаем LED delay(1000); // пауза 1 секунда digitalWrite(ledPin, LOW); // выключаем LED delay(1000); // пауза 1 секунда >

Первое, что мы сделаем, это внесем небольшие корректировки в функцию loop(). Чтобы сделать код более компактным и изящным, заменим 2 пары строчек на одну пару. Вместо установки значения в HIGH, а затем обратно в LOW, мы получим текущее значение ledPin и проинвертируем его. Т.е. если оно было HIGH, то станет LOW и наоборот.

void loop() < digitalWrite(ledPin, !digitalRead(ledPin)); // включаем/выключаем LED delay(1000); // задержка 1 сек. >

Отлично! Теперь мы усовершенствуем функцию delay(). Взамен, мы будем использовать функцию millis(). Данная функция возвращает количество миллисекунд, прошедшее с момента запуска текущей программы. Функция переполнится (вернется в нуль) приблизительно через 50 суток работы программы. Альтернативной функцией является micros(), которая возвращает количество микросекунд, прошедшее с момента запуска текущей программы. Функция переполнится (вернется в нуль) приблизительно через 70 минут работы программы. В нашем уроке мы будем использовать функцию millis():

/* Мигание LED Версия 2 * ------------------------ * Включает и выключает светодиод (LED) подсоединенный * к выходу 13, с интервалом в 2 секунды используя функцию millis() * */ int ledPin = 13; // LED подсоединен к выводу 13 unsigned long currentTime; unsigned long loopTime; void setup() < pinMode(ledPin, OUTPUT); // устанавливаем вывод 13 как выход currentTime = millis(); // считываем время, прошедшее с момента запуска программы loopTime = currentTime; >void loop() < currentTime = millis(); // считываем время, прошедшее с момента запуска программы if(currentTime >= (loopTime + 1000)) < // сравниваем текущий таймер с переменной loopTime + 1 секунда digitalWrite(ledPin, !digitalRead(ledPin)); // включаем/выключаем LED loopTime = currentTime; // в loopTime записываем новое значение >// Здесь могут быть другие команды >

В данном примере мы ввели две дополнительные переменные currentTime и loopTime. В функции setup() обе переменные имеют одно и тоже значение. В функции loop(), переменная currentTime каждый раз обновляется в цикле. Когда currentTime больше чем loopTime на 1 секунду (loopTime + 1000), то LED меняет свое состояние, а переменной loopTime присваивается текущее значение currentTime. Обратите внимание, что в данном примере мы не использовали функцию delay() и процессор может выполнять другие операции. Оригинал статьи на английском языке (перевод Колтыков А.В. для сайта cxem.net) Оригинал статьи

Теги:

Колтыков А.В. Опубликована: 2011 г. 0 1

Вознаградить Я собрал 0 0

Оценить статью

  • Техническая грамотность

Arduino.ru

Здравствуйте, возникла острая необходимость обнулить millis по просшествии какого-то времени, которое эта же функция считает. Прост омне нужно чтобы в течении допустим 5 секунд горел светодиод и ультразвуковой датчик проверял расстояние и распределяя его на правильное и не правильное и вот по просшествии 5 секунд принимал решение: если не правильных сигналов больше, то продлить время работы светодиода, а если нет, то переключится на другой светодиод и делать то же самое. Сейчас у меня все на цикле while и много функции delay, но я решил подключить кнопку, чтоб переключать режимы, а из-за delay программа может просто не увидеть нажатие кнопки

  • Войдите на сайт для отправки комментариев

Избавляемся от циклов

Как мигать светодиодом без задержки мы уже обсуждали. А как избавиться от цикла и сделать его асинхронным, чтобы он не блокировал выполнение? Очень просто – цикл заменяется на счётчик и условие. Пусть у нас есть цикл for , выводящий значение счётчика:

for (int i = 0; i

Для избавления от цикла нам нужно сделать свою глобальную переменную-счётчик, поместить всё это дело в loop() и самостоятельно увеличивать переменную и проверять условие:

int counter = 0; void loop() < Serial.println(counter); counter++; if (counter >= 10) counter = 0; >

И всё. А как быть, если в цикле была задержка? Вот пример

for (int i = 0; i < 30; i++) < // например, зажигаем i-ый светодиод delay(100); >

Нужно избавиться и от цикла, и от delay() . Введём таймер на millis() , как в уроке про многозадачность, и будем работать по нему:

int counter = 0; // замена i uint32_t timer = 0; // переменная таймера #define T_PERIOD 100 // период переключения void loop() < if (millis() - timer >= T_PERIOD) < // таймер на millis() timer = millis(); // сброс // действие с counter - наш i-ый светодиод например counter++; // прибавляем счётчик if (counter >30) counter = 0; // закольцовываем изменение > >

Вот собственно и всё! Вместо переменной цикла i у нас теперь свой глобальный счётчик counter , который бегает от 0 до 30 (в этом примере) с периодом 100 мс.

Видео

Полезные страницы

  • Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макросы, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
  • Поддержать автора за работу над уроками
  • Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *