Что такое функция millis() в Arduino и как ее использовать. Каковы преимущества millis() перед delay(). Как реализовать неблокирующие задержки с помощью millis(). Какие ошибки следует избегать при работе с millis().
Что такое функция millis() в Arduino
Функция millis() — это встроенная функция Arduino, которая возвращает количество миллисекунд, прошедших с момента запуска микроконтроллера. Она позволяет эффективно измерять и управлять временем в скетче без блокировки выполнения программы.
Основные особенности функции millis():
- Возвращает значение типа unsigned long (беззнаковое длинное целое)
- Точность измерения — 1 миллисекунда
- Переполнение происходит примерно через 50 дней работы
- Не блокирует выполнение программы, в отличие от delay()
Преимущества millis() перед delay()
Использование millis() вместо delay() дает ряд существенных преимуществ:
- Неблокирующее выполнение кода — программа продолжает работать, пока отсчитывается время
- Возможность одновременного выполнения нескольких задач с разными интервалами
- Более точный контроль времени
- Гибкость в управлении временными интервалами
Рассмотрим пример, демонстрирующий разницу между delay() и millis():
Пример с delay()
«`cpp void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); delay(1000); } «`В этом примере программа полностью останавливается на 1 секунду между включением и выключением светодиода. Это не позволяет выполнять другие задачи одновременно.
Пример с millis()
«`cpp unsigned long previousMillis = 0; const long interval = 1000; void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if (currentMillis — previousMillis > = interval) { previousMillis = currentMillis; if (digitalRead(LED_BUILTIN) == LOW) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } } // Здесь можно выполнять другие задачи } «`В этом примере светодиод мигает с тем же интервалом, но программа не блокируется и может выполнять другие задачи между проверками времени.
Как реализовать неблокирующие задержки с помощью millis()
Для реализации неблокирующих задержек с помощью millis() следует придерживаться следующего алгоритма:
- Определить переменную для хранения предыдущего времени выполнения задачи
- Задать интервал выполнения задачи
- В функции loop() получить текущее время с помощью millis()
- Сравнить разницу между текущим и предыдущим временем с заданным интервалом
- Если интервал прошел, выполнить задачу и обновить предыдущее время
Рассмотрим пример реализации нескольких неблокирующих задач:
«`cpp unsigned long previousMillis1 = 0; unsigned long previousMillis2 = 0; const long interval1 = 1000; const long interval2 = 500; void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600); } void loop() { unsigned long currentMillis = millis(); // Задача 1: мигание светодиодом if (currentMillis — previousMillis1 >= interval1) { previousMillis1 = currentMillis; digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); } // Задача 2: вывод сообщения в Serial if (currentMillis — previousMillis2 >= interval2) { previousMillis2 = currentMillis; Serial.println(«Hello, Arduino!»); } // Здесь можно выполнять другие задачи } «`В этом примере реализованы две независимые задачи с разными интервалами выполнения, работающие одновременно без блокировки основного цикла программы.
Ошибки при работе с millis() и как их избежать
При использовании функции millis() следует учитывать некоторые особенности и потенциальные проблемы:
1. Переполнение unsigned long
Переменная типа unsigned long может хранить значения от 0 до 4,294,967,295. После достижения максимального значения происходит переполнение, и счетчик начинается заново с 0. Это может привести к некорректной работе программы.
Решение: использовать правильное сравнение с учетом возможного переполнения:
«`cpp if ((unsigned long)(currentMillis — previousMillis) >= interval) { // Выполнить действие } «`2. Использование delay() вместе с millis()
Применение функции delay() в программе, использующей millis(), может нарушить точность измерения времени и привести к неожиданному поведению.
Решение: полностью отказаться от использования delay() в пользу неблокирующих задержек на основе millis().
3. Неправильный выбор типа данных
Использование типов данных меньшей разрядности (например, int вместо unsigned long) может привести к ошибкам при вычислениях и сравнениях.
Решение: всегда использовать тип unsigned long для работы со значениями времени, возвращаемыми millis().
Расширенные техники использования millis()
Функция millis() позволяет реализовать более сложные алгоритмы управления временем. Рассмотрим несколько продвинутых техник:
1. Реализация таймаута
Таймаут полезен, когда необходимо ограничить время выполнения определенной операции:
«`cpp unsigned long startTime; const unsigned long timeout = 5000; // 5 секунд void someFunction() { startTime = millis(); while (/* условие */) { if (millis() — startTime >= timeout) { // Время вышло, выходим из цикла break; } // Выполнение операции } } «`2. Управление несколькими состояниями
Для реализации сложной логики работы устройства можно использовать конечный автомат с переключением состояний по времени:
«`cpp enum State { STATE_1, STATE_2, STATE_3 }; State currentState = STATE_1; unsigned long stateTimer = 0; void loop() { unsigned long currentMillis = millis(); switch (currentState) { case STATE_1: // Действия для состояния 1 if (currentMillis — stateTimer > = 1000) { currentState = STATE_2; stateTimer = currentMillis; } break; case STATE_2: // Действия для состояния 2 if (currentMillis — stateTimer >= 2000) { currentState = STATE_3; stateTimer = currentMillis; } break; case STATE_3: // Действия для состояния 3 if (currentMillis — stateTimer >= 3000) { currentState = STATE_1; stateTimer = currentMillis; } break; } } «`Альтернативы millis(): micros() и RTOS
Помимо millis(), в Arduino существуют и другие способы управления временем:
Функция micros()
Функция micros() аналогична millis(), но возвращает время в микросекундах. Она полезна для измерения более коротких интервалов времени, но имеет меньший диапазон измерения из-за более быстрого переполнения:
Операционные системы реального времени (RTOS)
Для более сложных проектов на мощных микроконтроллерах (например, ESP32) можно использовать операционные системы реального времени, такие как FreeRTOS. Они предоставляют расширенные возможности многозадачности и управления временем:
«`cpp #includeЗаключение
Функция millis() является мощным инструментом для эффективного управления временем в Arduino-проектах. Ее использование позволяет создавать неблокирующие алгоритмы, выполнять несколько задач параллельно и точно контролировать временные интервалы. Понимание принципов работы millis() и умение применять ее в различных ситуациях значительно расширяет возможности разработчика при создании сложных и отзывчивых устройств на базе Arduino.
Функция millis ардуино
Начнём с того, откуда вообще микроконтроллер знает, сколько проходит времени. Ведь у него нет часов! Для работы микроконтроллера жизненно важен так называемый тактовый генератор, или кварцевый генератор, или он же кварц. Он же oscillator, он же clock. Clock по-английски это часы.
Поиск данных по Вашему запросу:
Функция millis ардуино
Схемы, справочники, даташиты:
Прайс-листы, цены:
Обсуждения, статьи, мануалы:
Дождитесь окончания поиска во всех базах.
По завершению появится ссылка для доступа к найденным материалам.
Содержание:
- Ардуино: параллельное выполнение задач по таймеру
- Arduino — функции — время
- Использование millis() в вложенных циклах
- Как заменить delay() на millis()?
- Arduino delay millis и micros для организации задержки в скетче
- Функция millis () с нажатием кнопки
- Arduino UNO урок 3 — Тайминг
- Arduino:Справочник языка Arduino/Функции/Работа со временем/millis()
- Arduino delay millis и micros для организации задержки в скетче
- Работа с точками останова
ПОСМОТРИТЕ ВИДЕО ПО ТЕМЕ: Arduino millis() function: 5+ things to consider
youtube.com/embed/qn8SP93L3iQ» frameborder=»0″ allowfullscreen=»»/>Ардуино: параллельное выполнение задач по таймеру
Функция millis позволяет считать время, прошедшее с момента запуска текущей программы. По прошествии этого времени отсчет начнется заново. Ниже приведен пример использования функции millis :. В приведенном выше примере, каждую секунду в монитор порта будет отправляться информация о времени, которое прошло с момента запуска программы. Поскольку время измеряется в миллисекундах, то каждое последующие значение будет отличаться на Точность считывания зависит от стабильности кварцевого резонатора Arduino.
Функция micros является аналогом функции millis , разница заключается в точности измерения. С помощью функции micros мы получим время, прошедшее от запуска текущей программы в микросекундах.
Счетчик подсчитанных микросекунд будет сброшен по истечении 70 минут. Ниже приведен пример использования функции micros :. Так же, как и в примере с функцией millis , здесь каждую секунду в монитор порта будет отправляться информация об измеренном времени, разница состоит только в том, что в данном случае время измеряется в микросекундах.
Функция delay позволяет приостановить выполнение текущей программы на указанное в параметре время. Синтаксис команды выглядит следующим образом:. Ниже пример использования команды delay :. В приведенном выше примере, светодиод загорается на 0,5 секунды, затем гаснет на 1 секунду и так далее, пока питание Arduino не будет отключено. Функция delayMicroseconds является разновидностью функции delay. Разница заключается в количестве и точности отсчета времени. Функция delay позволяет отсчитывать время с точностью до 1 миллисекунды, в то время как delayMicroseconds с точностью до 1 микросекунды.
Значение, которое можно указать в параметре, находиться в диапазоне от 0 до Для более длинных временных интервалов следует использовать функцию delay или несколько раз использовать delayMicroseconds. Получать уведомления по электронной почте об ответе на свой комментарий.
Функция millis Функция millis позволяет считать время, прошедшее с момента запуска текущей программы. Цифровой мультиметр AN Отправить сообщение об ошибке.
Добавить комментарий Отменить ответ Ваш электронный адрес не будет опубликован.
Arduino — функции — время
Обратимся к первому уроку , где мы управляли LED. Между включением и выключением которого была секундная задержка. В используемой там программе см. В это время контроллер не может выполнять другие команды в главной функции loop. Первое, что мы сделаем, это внесем небольшие корректировки в функцию loop. Чтобы сделать код более компактным и изящным, заменим 2 пары строчек на одну пару. Теперь мы усовершенствуем функцию delay.
Arduino и переполнение счетчиков — как бороться с переполнением, Обычно, в этих примерах используется функция delay(), которая как бы » замораживает» if (millis() — led_mk_timer > LED_MK_INTERVAL).
Использование millis() в вложенных циклах
Только зарегистрированные пользователи могут участвовать в опросе. Войдите , пожалуйста. Во-первых, по таймеру ограничение по времени не знаю точно про ардуино, я про общий случай — успеть отработать до того, как он вызовется снова. В целом, этого обычно вполне достаточно, чтобы успеть переключить задачу. Во-вторых, вообще есть два пути: либо конечный автомат state machine , либо многопоточность. Первый реализуется без каких-либо таймеров, часто используется во всяких устройствах типа микроволновки. Когда же устройству пора становится умнее, например, обрабатывать нажатия на кнопки и рисовать что-то на экран, первое время костыль вроде вашего smartDelay подойдет, но чем раньше от него отказаться, тем лучше. Благо, многозадачность делается в несколько строк кода.
Как заменить delay() на millis()?
Но это становится настоящим препятствием, когда вы пытаетесь делать другие вещи, например, отслеживать нажатие кнопки. В этом случае необходимо реализовывать своеобразную многозадачность. Да, это добавит немного строк кода в ваши программы, но это, в свою очередь, сделает вас более опытным программистом и увеличит потенциал вашего Arduino. Для этого нужно всего лишь научиться использовать функцию millis.
Доброго всем дня и сегодня речь пойдет о временных функциях millis и delay , о которых вы, наверняка, уже слышали. Данные функции удобны тем, что помогают нам устанавливать небольшие задержки между выполнением определенных задач в коде.
Arduino delay millis и micros для организации задержки в скетче
Table of Contents. Для получения общей информации об отладке, в первую очередь прочитайте главу «Отладка скетча». Все функции, связанные с точками останова, доступны с помощью контекстного меню , которое появляется при щелчке правой кнопкой мыши по маркеру точки останова слева от области кода в окне кода:. Выключенные точки останова останутся в скетче. Даже если точка останова отключена, каждый раз, когда скетч проходит через точку останова, плата взаимодействует с Visual Micro, что немного замедляет выполнение скетча. Вы можете задавать условия для точек останова.
Функция millis () с нажатием кнопки
Обычно, в этих примерах используется функция delay , которая как бы «замораживает» микроконтроллер на время своего выполнения. И если Arduino должен обрабатывать не только задержку при мигании светодиодом например с задержкой в 5 сек. Поскольку, обычно, в скетчах для Ардуино обрабатывается более 2 событий, использовать функцию delay весьма не желательно. Чем и как правильно заменить delay , рассказано ниже. Все примеры, опубликованные в этой статье протестированы на микроконтроллере далее МК Arduino Mega Этот пример служит только для быстрого старта, чтобы бы можно было сразу увидеть результат программирования микроконтроллера, и не сильно вникать в тонкости программирования. Проблемы начинаются тогда, когда от Arduino требуется выполнить несколько действий одновременно — функция delay полностью «зависает» микроконтроллер на время своего выполнения, не позволяя параллельно обрабатывать, например, нажатия кнопок, показания датчиков и т. Для того, чтобы можно было выполнять несколько действий на Ардуино одновременно — следует воспользоваться таймерами.
Функция millis() позволит выполнить задержку без delay на ардуино, тем самым обойти недостатки.
Arduino UNO урок 3 — Тайминг
Функция millis ардуино
Через некоторое время я получаю свой окончательный результат, я хочу, но я не могу использовать задержку, потому что мне нужно другое время для разных полосок, поэтому мне нужно заменить delay на millis в этом коде:. Я вижу, вы используете NeoPixels! Так получилось, что Adafruit имеет несколько отличных руководств по использованию millis и micros для целей синхронизации вместо delay. Они также включают хороший материал на прерываниях, если вы чувствуете амбициозность и хотите полностью отделить свое время от своей основной функции стоящее дело, если у вас есть время и ресурсы.
Arduino:Справочник языка Arduino/Функции/Работа со временем/millis()
ВИДЕО ПО ТЕМЕ: Arduino — Utilizzo della funzione millis()
youtube.com/embed/7wuEEY5G1Lo» frameborder=»0″ allowfullscreen=»»/>Я использую millis для прошивки некоторых огней неопикселей на arduino pro mini. Проблема в том, что я не могу зажечь огни в течение требуемого периода. Вот упрощенная версия того, что я делаю. В цикле у меня есть цикл while назовем его loop 1 , который должен работать в течение мс. Внутри цикла 1 я вызываю функцию flash , которая должна работать в течение 9 секунд! Я поставил еще один цикл цикл 2 после цикла 1, который будет работать в течение 3 секунд.
Первый раз работая с Arduino , вы, возможно, сделали что-то вроде этого:. Он показывает, как при помощи всего нескольких строчек кода создать нечто, способное выполнять задачи в реальном мире.
Arduino delay millis и micros для организации задержки в скетче
Эта функция, как указано в официальной документации останавливает выполнение программы на указанное количество милисекунд. Давайте рассмотрим пример: вы подключили к Arduino кнопку и светодиод; когда вы нажимаете на кнопку, светодиод должен зажечься на 3 секунды. Скетч может выглядеть примерно следующим образом несолько модифицированная версия из оффициального туториала :. Теперь добавим вторую кнопку и второй светодиод и попробуем обновить скетч, чтобы управлять двумя светодиодами, используя при этом функцию delay :. Вероятно, вы уже заметили проблему: когда один светодиод включен, вы не можете включить второй!
Работа с точками останова
Задержки в Ардуино играют очень большую роль. Без них не сможет работать даже самый простой пример Blink, который моргает светодиодом через заданный промежуток времени. Но большинство начинающих программистов мало знают о временных задержках и используют только Arduino delay, не зная побочных эффектов этой команды. В этой статье я подробно расскажу о временных функциях и особенностях их использования в среде разработки Arduino IDE.
ลดการใช้ delay() หันมาใช้ миллис() / микрос() กันดีกว่า!
สวัสดี ท่าน ที่ พึ่ง หัด เขียน โปรแกรม แรก ๆ มัก จะ ได้ เรียน รู้ กัน ไป แล้ว แน่นอน อย่าง น้อย ก็ Пример мига วินาที (MS) หรือ 1 วินาที โปรแกรม จะ ไม่ ทำ งาน บัน บัน ทัด ไป จน กว่า จะ เวลา เวลา 1 วินา ที นั้น
ปัญหา อยู่ ตรง หาก ใน ใน ของ เรา จำเป็น อ่าน อ่าน ค่าเซนเซอร์ อย่าง อย่าง เซนเซอร์ การ ของ เรา จำเป็น อ่าน ค่าเซนเซอร์ บาง อย่าง เซนเซอร์ การ การ เรา จำเป็น อ่าน ค่าเซนเซอร์ อย่าง เอียง ต้องการ ความ ถี่ 50-100 รอบ ต่อ วินาที หาก เรา เขียน โปรแกรม โดย มี Задержка บน Цикл (เช่น ใช้ Задержка หยุด จน ถึง 90 องศา เป็น ต้น) ก็ ไป ขวาง การ ทำ งาน ของ ส่วน อ่าน ค่าเซนเซอร์ ทำ ให้ นั้น เซนเซอร์ ก็ จะ หยุด อัพเดทค่า และ ส่ง ผล ต่อ ของ ของ โดย รวม แน่นอน millis () จึง ถูก ใช้ ใช้ แทน จาก ต้น เพื่อ ให้ แน่นอน แน่นอน แน่นอน Цикл ยัง งาน ต่อ ไป ได้ โดย ไม่ ติด ขัด (не блокирующий) และ ระยะ เวลา ที่ แม่นยำ กว่า ด้วย ครับ ครับ
Миллис () จริง แล้ว ไม่ ฟังก์ชัน หยุด แต่ อย่าง ใด หาก แต่ เป็น การ การ เวลา ตั้ง แต่ เครื่อง อย่าง อย่าง ใด หาก แต่ เป็น การ เวลา ตั้ง แต่ เครื่อง อย่าง อย่าง ใด หาก แต่ เป็น การ นับ เป็น ฟังก์ชัน ที่ return ค่า เป็น มิลลิวินาที ตัว แปร แบบ แบบ แบบ แบบ แบบ ขนาด เรา อาจ ทำ ๆ ได้ ว่า
double time_now = (double)millis()/1000,0;
ซึ่ง แปร แปร แปร เป็น เป็น หน่วย วินาที แต่ โดย ปกติ เรา มัก จะ กำหนด เวลา เป็น เป็น เพราะ จะ ประหยัด คำนวณ ลง ได้ ครับ การ ประยุกต์ ใช้ การ การ การ การ ทำ ทำ ทำ ทำ ทำ ทำ ทำ สามารถ สามารถ สามารถ สามารถ สามารถ สามารถ สามารถ สามารถ สามารถ การ ค่า เวลา การ ทำ งาน ครั้ง ล่า สุด และ รอ จน กว่า เวลา ผ่าน ไป เท่า กับ จำนวน มิลลิวินาที ที่ ต้องการ จึง ทำ งาน ต่อ ไป เก็บ เวลา เวลา ณ ขณะ นั้น อีก ครั้ง นึง ซ้ำ ไป ที่ ณ ณ ณ ณ ที่ ที่ ที่ ที่ ที่ ที่ ที่ นี้ เรื่อย แบบ นี้ โปรแกรม ก็ จะ ไม่ เสีย เวลา บน ฟังก์ชัน ฟังก์ชัน นึง นาน เกิน ไป ครับ เพราะ หาก เวลา ถึง จำนวน ที่ ตั้ง ก็ จะ ไป ทำ อย่าง ก่อน ได้ เลย
ตัวอย่างการใช้ millis()
หากยังไม่สะใจ ลองดูตัวอย่างนี้อีกอัน
หากคิดว่า code ดูยุ่งเหยิง ยาวไป อาจลองใช้ library เพื่อร่นระยะลงได้นะครับ
https : //blog. protoneer.co.nz/arduino-task-scheduler/
นอก จาก millis () ที่ ให้ เวลา ตั้ง แต่ เปิด เครื่อง เป็น หน่วย มิลลิวินาที ยัง มี Micros ()
ที่ ใน หน่วย ไมโครวินาที ไมโครวินาที ไมโครวินาที ไมโครวินาที ไมโครวินาที ไมโครวินาที ไมโครวินาที ไมโครวินาที หน่วย หน่วย หน่วย หน่วย ไมโครวินาที ไมโครวินาที ไมโครวินาที ไมโครวินาที (микросекунды, мкс, мкс) 0,001 0,001 0,000001 932 — 1) ไมโครวินาที หรือประมาณ 70 นาที จากนั้นค่าจะ
overflow กลับมาเป็น 0 อีกครั้งและเพิ่มขึ้นวนไปอย่างนี้เรื่อย ๆ (กรณีของ millis() จะ overflow ที่ประมาณ
49 วัน)
ดังนั้นเราอาจ ไม่ สามารถ ไป ดำเนิน การ ทาง คณิตศาสตร์ กับ ตัว แปร ที่ เป็น เป็น หรือ หรือ ได้ ตรง ตรง
เช่น ที่ มี ความ ละเอียด เป็น นึง ของ ของ ของ ตรง ตรง เพราะ ขนาด ขนาด 32 -битный มี ครึ่ง นึง ทาง ทาง ลบ ลบ ครึ่ง ไป ไป ไป ไป ไป ไป ไป ไป ไป ไป ต่าง จาก Unsigned ที่ มี ค่า ลบ ลบ) การ นำ ค่า สุด ของ ของ และ และ และ ค่า ลบ มา กัน ไม่ ได้ ค่า 0 แต่ จะ ได้ ติด ลบแทน ซึ่ง ต้อง ใน การ การ ค่า Микрос () ลง แปร แปร ลบแทน ต้อง ระมัดระวัง การ การ ค่า ค่า ค่า ค่า ลง แปร ติด. 0003
วิธี ใช้ งาน ก็ จะ เหมือน กับ การ ใช้ ใช้ millis () เช่น อยาก ให้ โปรแกรม ทำ งาน ทุก ๆ 3 วินาที
ก็ เรา เปลี่ยน จาก 3000 เป็น 3000000 เป็น ต้น และ ให้ การ ตัว เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น เป็น ประเภท ประเภท ประเภท ประเภท ประเภท ประเภท ประเภท ประเภท ประเภท
และ เพิ่มเติม อีก นิดหน่อย นิดหน่อย
ฟังก์ชัน Micros () ไม่ ให้ ความ ละเอียด ที่ 0,000001S ทุก ครั้ง ที่ แต่ จะ ตัว คูณ ของ 4
กรณี เป็น บอร์ด บอร์ด เช่น เช่น เช่น เช่น เช่น เช่น เช่น เช่น เช่น เช่น เรา เรา เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ เมื่อ. อ่าน ที่ 100us ครั้ง ไป ที่ เรา อ่าน ต่อ ให้ เรา อ่าน เร็ว สุด เท่า ที่ จะ เป็น ไป ได้ ก็ จะ อ่าน ค่า ไป ได้ ที่
104us, 108us เป็น คูณ ของ ของ 4 แบบ นี้ ไป เรื่อย แต่ มัน ก็ ละเอียด เกิน พอ จะ ใช้ งาน ใหญ่ แล้ว ล่ะ ครับ ครับ มัน เกิน พอ จะ มี ประโยชน์ บ้าง มาก ก็ น้อย ครับ ไม่ ไร กัน มี ประโยชน์ ประโยชน์ บ้าง บ้าง มา มา กัน กัน กัน กัน กัน ได้เลยย
เลี้ยงกาแฟผมสักแก้ว : https://ko-fi.com/modulemore
Wielozadaniowośnie delay, c lizadaniowość, c lizadaniowość!
Na początku gdy zaczynamy naszą zabawę z arduino wykorzystujemy funkcję delay() by opóźnić działanie naszego programu. Lecz załóżmy że chcemy podłączyć do naszego mikrokontrolera dwie diody i chcemy żeby jedna z nich zmieniła swój stan (zaświeciła się lub zgasła) co jedną secundę, a othera z nich co undye. Więc używając funkcji delay() можно записать так: 9= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_2, stan_LED_2); //gasimy lub zapalamy diodę } задержка(1000); //opóźniamy działanie programu } Efekt działania programu
Ale co jeżeli okaże się że potrzebujemy by pierwsza dioda migała szybciej np. = 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_2, stan_LED_2); //gasimy lub zapalamy diodę } задержка(500); //opóźniamy działanie programu } Pierwsza dioda miga dwa razy szybciej
Idąc dalej dołóżmy jeszcze do naszej zabawy trzecią diodę i niech ona miga co 0,25 секунды. No to co przeróbmy cały program i niech działa!
#определить LED_1 2 #определить LED_2 3 #определить LED_3 4 //na początku diody są zgaszone логическое значение stan_LED_1 = ложь; логическое значение stan_LED_2 = ложь; логическое значение stan_LED_3 = ложь; uint8_t лицник_LED_1 = 0; uint8_t лицник_LED_2 = 0; недействительная установка () { //уставные сосны до тех, кто находится под землей, как диоды, как wyjście pinMode(LED_1, ВЫХОД); pinMode(LED_2, ВЫХОД); pinMode(LED_3, ВЫХОД); } недействительный цикл () { //zwiększamy wartość zmiennych o 1 лицник_LED_1++; лицник_LED_2++; если(licznik_LED_1 >= 2){ licznik_LED_1 = 0; //resetujemy licznik stan_LED_1 ^= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_1, stan_LED_1); //gasimy lub zapalamy diodę } если(licznik_LED_2 >= 8){ licznik_LED_2 = 0; //resetujemy licznik stan_LED_2 ^= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_2, stan_LED_2); //gasimy lub zapalamy diodę } stan_LED_3 ^= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_3, stan_LED_3); //gasimy lub zapalamy diodę задержка(250); //opóźniamy działanie programu }Trzecia dioda miga co 250ms
No dobra, po chwili spędzonej z kalkulatorem, nasz program działa poprawnie, diody migają tak jak chcemy. Ale jednak okazuje się że trzecia dioda miga zbyt szybko i chcemy by migała o 100 milisekund wolniej. To co, ponownie bierzemy kalkulator i znów chwila liczenia. Dobra ale jeżeli przyjdzie taka potrzeba by migać dziesięcioma diodami w completnie różnych odstępach czasu? Przecież nie będziemy wiecznie siedzieć i liczyć jaki odstęp czasu dobrać by nasze diody migały tak jak chcemy, a co dopiero gdyby przyszło nam zmienić częstotliwość migania kilku z tych dziesodięciu di? А как микроконтроллер liczył czas za nas? By my nie musielśmy wcale używać kalkulatora? Не ма поздних проблем! С помощью функции Arduino миллис() .
Функция миллис()
Więc co robi funkcja millis() ? Po prostu zwraca nam czas w milisekundach jaki upłynął od uruchomienia się mikrokontrolera do czasu jej wywołania . Dzięki niej możemy lepiej wykorzystać nasz mikrocontroller, zamiast czekać tak jak w przypadku używania funkcji delay(), nasz mikrokontroler może wykonywać inne działania nie marnując czasu na bezczynne czekanie. Funkcja millis() do określania czasu korzysta z wbudowanego w mikrocontroler timera (шутка к coś w rodzaju stopera), dzięki temu odliczania przez nią czasu nie zatrzyma nawet delay(). Funkcja millis() jest zawsze dostępna do użycia w każdym programie, jest tylko korzystamy z frameworku Arduino .
Wartość jaką zwraca funkcja millis() jest typu unsigned long . Zavyczaj używamy typu int (integer) lub jeszcze mniejszych typów zmiennych aby oszczędzać pamięć RAM naszego mikrocontrolera, której nie ma za dużo do dyspozycji. Więc należy uważać przy obliczeniach by liczyć na jednym typeie zmiennych. W przeciwnym wypadku może powodować to błędy w obliczeniach! Więc musimy dać znać kompilatorowi że liczymy na typeie unsigned long dopisując na koncu liczby UL (np. 100UL), lub jаwnie konwertować inną zmienną do odpowiedniego typu dopisując przed nią w nawiasach “(unsigned konwertować przed nią w nawiasach long)”. Należy Pamiętać że type unsigned Long Jest Tylko Wartości Dodatnie (nie przechowuje informacji o znaku liczby), więc należy zwrachać nalemememememememememememehemememememememememememememememememememehemememememememememememem0017 .
Kolejną rzeczą na jaką trzeba zwrócić uwagę to fact że nie ma typów zmiennych które mogłyby przechowywać liczby nieskończenie wielkie . Z tego powodu po jakimś czasie nastąpi overflow (przepełnienie) . Więc co się stanie gdy zostawimy mikrokontroler włączony na bardzo długi czas? Odpowiedź jest bardzo prosta: odliczanie zacznie się od nowa i jeżeli program bedzie dobrze написаны на nie wpłynie на jego działanie. Ale też nie ma się o co martwić bo overflow wystąpi dopiero po niecałych 50 дней управления микроконтроллером .
Na to należy uważać
Możliwe że czasem bedzie nam potrzebne zmienić częstotliwość PWM na niektórych pinach w naszym mikrokontrolerze. Для подключения к микроконтроллеру ATmega328P* необходимо использовать PWM на пинах D5 и D6, чтобы отключить установку прескалера (TCCR0B) и включить функцию блокировки миллисекунд() или задержку()! Odpowiednio zwiększając lub zmniejszając częstotliwość zwiększy lub zmniejszy się szybkość liczenia czasu przez millis() i delay(). Np dla 8 razy wyższej częstotliwości funkcja millis() w czasie 1s zwiększy zwracaną wartość nie o 1000, a o 8000, czyli bedzie liczyć 8 razy szybciej. Analogicznie delay(8000) opóźni działanie programu nie o 8s a o 1s.
*Совместимость с платами с внутренними модулями Arduino Uno, Nano, Pro Mini и т.п. Dla płytek z innym mikrocontrolerem piny oraz timery mogą się różnić.
Мигание без задержки()
Wracając do migania naszymi diodami. Będziemy potrzebować kilku zmiennych aby przechować informację kiedy ostatni raz każda z diod zmieniła swój stan. Программа Więc będzie wyglądać tak:
#определить LED_1 2 #определить LED_2 3 #определить LED_3 4 //na początku diody są zgaszone логическое значение stan_LED_1 = ложь; логическое значение stan_LED_2 = ложь; логическое значение stan_LED_3 = ложь; unsigned long now = 0; //deklarujemy zmienne w których zapamiętamy ostatni czas zmiany stanu diody беззнаковый длинный timer_LED_1 = 0; беззнаковый длинный timer_LED_2 = 0; беззнаковый длинный timer_LED_3 = 0; недействительная установка () { //уставные сосны до тех, кто находится под землей, как диоды, как wyjście pinMode(LED_1, ВЫХОД); pinMode(LED_2, ВЫХОД); pinMode(LED_3, ВЫХОД); } недействительный цикл () { сейчас = миллис(); //zapamiętujemy aktualny czas if(now - timer_LED_1 >= 500UL){ //развернуть закрытие минимум 500 мс timer_LED_1 = сейчас; stan_LED_1 ^= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_1, stan_LED_1); //gasimy lub zapalamy diodę } if(now - timer_LED_2 >= 2000UL){ //распаковка минимум 2 с timer_LED_2 = сейчас; stan_LED_2 ^= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_2, stan_LED_2); //gasimy lub zapalamy diodę } if(now - timer_LED_3 >= 350UL){ //развернуть закрытие минимум 350 мс timer_LED_3 = сейчас; stan_LED_3 ^= 1; //zmieniamy stan zmiennej na przeciwny za pomocą operatora XOR цифровая запись (LED_3, stan_LED_3); //gasimy lub zapalamy diodę } }
Есть ли какие-либо возможности wykorzystać funkcję millis()?
Oczywiście poza tym że dzięki tej funkcji możemy wykonywać pewne fragmenty kodu cyklicznie (nie ogranicza się to tylko do migania diodami), możemy wykorzystać ją między innymi od wyeliminowania skutków drgania styków np przy przyciskach (czyli tak zwanego debouncing’u). Kiedyś sam napisałem taką klasę po to by uprościć sobie obsługę przycisków bez zbędnego opóźnienia wykonywania się reszty kodu programu:
кнопка класса { вывод uint8_t; логическое последнее_состояние; unsigned long timmer, debounce; публичный: Кнопка (uint8_t _pin, unsigned long _debounce = 10) { пин = _пин; дебаунс = _дебаунс; pinMode (пин, INPUT_PULLUP); } логический ключВниз(){ if(millis()-timmer >= debounce){ тиммер = миллис(); bool state_now = !digitalRead(pin); if(last_state == false && state_now == true){ последнее_состояние = состояние_сейчас; вернуть истину; }еще{ последнее_состояние = состояние_сейчас; вернуть ложь; } }еще{ вернуть ложь; } } логический ключВверх(){ if(millis()-timmer >= debounce){ тиммер = миллис(); bool state_now = !digitalRead(pin); if(last_state == true && state_now == false){ последнее_состояние = состояние_сейчас; вернуть истину; }еще{ последнее_состояние = состояние_сейчас; вернуть ложь; } }еще{ вернуть ложь; } } }; //tworzymy obiekt klasy Button podając pin na którym znajduje się przycisk zwierany do masy Кнопка btn1(2); //может подаваться нестандартное время устранения дребезга, домысльный czas до 10мс Кнопка btn2(3, 100); недействительная установка () { } недействительный цикл () { if(btn1.