Цикли 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 размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Генератор імпульсів на NE555

Генератор імпульсів на NE555

Генератор імпульсів на NE555 Генератор прямокутних імпульсів на основі популярної мікросхеми NE55..

42.30грн.

Як почати програмувати Arduino та які базові функції використовуються

Як почати програмувати Arduino та які базові функції використовуються

Як почати програмувати Arduino та які базові функції використовуються Arduino — це проста й..

Світлодіод 5мм

Світлодіод 5мм

Світлодіод з діаметром 5мм. LED Максимальний струм 20 мА ..

1.98грн.

Силовий MOSFET транзистор IRF520 N-канальний

Силовий MOSFET транзистор IRF520 N-канальний

MOSFET транзистор 3-го поколінняВикористовується для швидкісної комутації потужних виконавчих механі..

28.43грн.

Розумний дім #4: Розумна розетка на ESP32

Розумний дім #4: Розумна розетка на ESP32

Розумний дім #4: Розумна розетка на ESP32 Розумна розетка — один із найбільш затребуваних е..