Цикли 7 — Цикли та затримки

Вступ

В Arduino часто використовується функція delay() для створення пауз. Проте у неї є суттєвий недолік: під час виконання delay() програма повністю зупиняється і не може виконувати інші завдання. Це призводить до «зависання» пристрою, якщо потрібна одночасна робота з кількома процесами.

Чому delay() блокує виконання

Функція delay() просто «заморожує» виконання коду на вказану кількість мілісекунд. Поки йде затримка, мікроконтролер не виконує жодних інших команд, включаючи обробку сенсорів, кнопок чи інших подій.

Як замінити delay() на millis()

Для реалізації неблокуючих затримок використовується функція millis(), яка повертає кількість мілісекунд з моменту запуску програми. Порівнюючи поточний час з моментом останньої дії, можна виконувати код лише тоді, коли минув потрібний інтервал, при цьому не блокуючи виконання інших завдань.


// Приклад неблокуючого коду блимання
unsigned long previousMillis = 0;
const long interval = 1000;

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    // Дія, яку потрібно повторювати
  }
}
  

Практика

Переписування блимання з delay на millis


const int ledPin = 13;
unsigned long previousMillis = 0;
const long interval = 500;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}
  

Одночасне виконання кількох дій


const int led1 = 8;
const int led2 = 9;
const int led3 = 10;

unsigned long prev1 = 0, prev2 = 0, prev3 = 0;
const long int1 = 300;
const long int2 = 500;
const long int3 = 700;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - prev1 >= int1) {
    prev1 = currentMillis;
    digitalWrite(led1, !digitalRead(led1));
  }
  if (currentMillis - prev2 >= int2) {
    prev2 = currentMillis;
    digitalWrite(led2, !digitalRead(led2));
  }
  if (currentMillis - prev3 >= int3) {
    prev3 = currentMillis;
    digitalWrite(led3, !digitalRead(led3));
  }
}
  

Проєкт: «Світломузика»

Три світлодіоди блимають з різною частотою без блокувань, створюючи ефект світломузики. Такий підхід можна розширити, додавши реакцію на музику через мікрофон або датчик звуку.


const int redLed = 3;
const int greenLed = 4;
const int blueLed = 5;

unsigned long prevRed = 0, prevGreen = 0, prevBlue = 0;
const long redInterval = 200;
const long greenInterval = 400;
const long blueInterval = 600;

void setup() {
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - prevRed >= redInterval) {
    prevRed = currentMillis;
    digitalWrite(redLed, !digitalRead(redLed));
  }
  if (currentMillis - prevGreen >= greenInterval) {
    prevGreen = currentMillis;
    digitalWrite(greenLed, !digitalRead(greenLed));
  }
  if (currentMillis - prevBlue >= blueInterval) {
    prevBlue = currentMillis;
    digitalWrite(blueLed, !digitalRead(blueLed));
  }
}
  

Висновок

Використання millis() замість delay() дозволяє створювати більш складні та чутливі програми. Неблокуючий код — основа багатозадачності в Arduino, особливо при роботі з датчиками та кількома виконавчими пристроями одночасно.

Цикли 8 — Оптимізація циклів

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Контроль виконання програми Arduino

Контроль виконання програми Arduino

Контроль виконання програми ArduinoЦя стаття присвячена опису структур, що використовуються для упра..

Arduino бігаюча доріжка з світлодіодів

Arduino бігаюча доріжка з світлодіодів

Arduino бігаюча доріжка з світлодіодівРобимо бігаючу доріжку з світлодіодів на Arduino. В даному вип..

Шестерня для зубчатого ременю на 30 зубців під вісь 5 мм

Шестерня для зубчатого ременю на 30 зубців під вісь 5 мм

Використовується для передачі та редукції обертаючого моменту від двигуна до вісі 5 ммКількість зубц..

79.88грн.

Калькулятори для електронщиків та радіоаматорів

Калькулятори для електронщиків та радіоаматорів

Онлайн-калькулятори для розрахунку напруги, струму, опору, дільника напруги, резистора для світлодіо..

Джойстик двохосьовий з кнопкою

Джойстик двохосьовий з кнопкою

Двохосьовий джойстик з кнопкою — це зручний модуль керування для проєктів на Arduino, ESP32 та інших..

44.72грн.