Код для поиска

Урок 14/31-2: Пример 2 программирования Arduino с millis() и событием

Урок 14/31-2: Пример 2 программирования Arduino с millis() и событием

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

Собранный автомобиль Sunfounder

Вот несколько практических примеров того, как вы можете использовать этот шаблон в своих проектах:

  • Отложенная активация: Включение вентилятора или насоса только после того, как система проработала заданное время.
  • Блокировки безопасности: Требование удерживать кнопку нажатой в течение определённого времени перед выполнением опасного действия, например, запуска двигателя.
  • Уведомления на основе времени: Запуск сигнала тревоги или уведомления, если показания датчика не изменились в течение определённого окна времени.
  • Неблокирующие таймеры: Создание «сторожевого» таймера, который сбрасывает устройство, если оно перестаёт отвечать.

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

Необходимое оборудование

  • Плата Arduino (Uno, Nano, Mega и т. д.)
  • Кнопка
  • Соединительные провода

Схема подключения

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

  • Подключите одну ножку кнопки к контакту GND на Arduino.
  • Подключите другую ножку кнопки к цифровому контакту 2 на Arduino.

Поскольку в коде используется INPUT_PULLUP, контакт будет считывать HIGH, когда кнопка не нажата, и LOW, когда она нажата, соединяя контакт с землёй. (на видео в 08:29)

Понимание кода

Этот код демонстрирует простой таймер на основе событий. Программа непрерывно выводит текущее значение millis() в монитор последовательного порта. Когда кнопка нажата и удерживается, и Arduino работает не менее 5 секунд, программа выведет «Take action» в монитор последовательного порта. Ключевой момент в том, что проверка millis() не останавливает непрерывный вывод времени.

Давайте разберём настраиваемые пользователем части кода:

unsigned long event = 5000;// 5 секунд

Это самая важная переменная для настройки. Она определяет продолжительность вашего «события» в миллисекундах. В этом примере она установлена на 5000, что равно 5 секундам. Чтобы изменить задержку, просто измените это число. Например, установка значения 10000 приведёт к запуску действия через 10 секунд. Крайне важно использовать тип данных unsigned long, так как значение millis() может стать очень большим и в конечном итоге превысит максимальное значение стандартной переменной int, что вызовет ошибки при сравнении. (на видео в 05:46)

pinMode(2,INPUT_PULLUP);

Эта строка настраивает цифровой контакт 2 как вход и активирует его внутренний подтягивающий резистор. Это ключевой шаг конфигурации, который позволяет подключить кнопку без внешнего резистора. Контакт будет считывать HIGH по умолчанию и перейдёт в состояние LOW при нажатии кнопки, соединяя его с землёй. Если вы хотите использовать другой контакт, измените число 2 здесь и в строке digitalRead(2) внутри цикла. (на видео в 08:46)

Логика внутри loop() проста. Она считывает состояние кнопки. Если кнопка нажата (pb == LOW), то проверяется, больше ли или равно текущее время (millis()) вашему заданному времени event. Если оба условия истинны, выводится сообщение о действии. Остальная часть цикла, которая выводит время, продолжает выполняться без перерыва, демонстрируя преимущество millis() перед delay().

В этом примере время отсчитывается с момента запуска Arduino. Третий пример в серии видео развивает эту идею, записывая время первого нажатия кнопки и запуская действие только в том случае, если второе нажатие происходит как минимум через 5 секунд. Эта логика рассматривается в Уроке 14/31-3: Пример 3 Arduino coding millis() с кнопкой.

Демонстрация работы проекта

После загрузки кода и открытия монитора последовательного порта (со скоростью 9600 бод) вы увидите непрерывный поток чисел, представляющих миллисекунды с момента включения платы. Если вы нажмёте и удержите кнопку до истечения 5 секунд, ничего не произойдёт. Однако, если вы нажмёте и удержите кнопку после отметки в 5 секунд, вы увидите сообщение «Take action» в мониторе последовательного порта. Действие будет продолжать выводиться, пока кнопка удерживается. Это демонстрирует неблокирующий таймер, который позволяет другому коду (выводу) выполняться без помех. (на видео в 10:52)

Связанные проекты из этого видео

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

Главы

  • [00:00] Введение в millis() и набор SunFounder
  • [01:19] Что такое millis() и почему использовать её вместо delay()?
  • [03:06] Практическая демонстрация: вывод значения millis()
  • [05:46] Создание события с millis() и unsigned long
  • [08:29] Подключение и кодирование кнопки с INPUT_PULLUP
  • [10:52] Запуск примера события с кнопкой
  • [12:14] Предпросмотр примера 3: обнаружение второго нажатия кнопки
  • [17:20] Введение в функцию map()
  • [19:47] Кодирование и демонстрация функции map() с светодиодом

Изображения

Sunfounder car assembled
Sunfounder car assembled
Sunfounder car assembled
Sunfounder car assembled
917-Lesson 14/31-2: Arduino coding millis() example 2 with event
Язык: C++
/*
Lesson 14/31: Arduino coding millis() example 2 with event
Get this code and watch video Download and resource page https://robojax.com/RJT597
YouTube video https://www.youtube.com/watch?v=lqgzQohNiIM
 
  
 * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been download from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


unsigned long event = 5000;// 5 seconds
void setup() {
  Serial.begin(9600);//initialize serial monitor
  Serial.println("Introduction to millis");
  pinMode(2,INPUT_PULLUP);
  


}

void loop() {
  // Robojax.com millis() example 1
  Serial.println(millis());
  int pb = digitalRead(2);// read pin 2
  if(pb ==LOW)
  {
      if(millis() >= event)
      {
        Serial.println("Take action");
      }// if end
  }// if end
  
}// loop end

Вещи, которые могут вам понадобиться

Файлы📁

Руководство пользователя