Многозадачность на Arduino
Платформы Arduino с ядром Cortex-M0+ и Cortex-M3 позволяют выполнять несколько задач одновременно — микрокотроллер просто переключается с одной задачи на другую. Для многопоточного программирования пригодится библиотека Scheduler, которая включает в себя функции управление между задачами.
Настроим несколько функций для одновременно выполнения с loop(). По итогу на выходе будет несколько независмых loop-функций, не требующих отдельного таймера.
В качестве примера улучшим первый эксперимент из набора матрёшки — маячок. Сделаем три отдельных лампочки с разными задержками мигания.
Что понадобится?
- Платформа Arduino на архитектуре ARM, например Arduino MKR Zero
Как собрать?
В зависимости от управляющей платформы соберите схему проекта.
Схема для плат Arduino MKR
Схема для Arduino M0 и Arduino M0 Pro
Схема для Arduino Due
Пример кода
Для работы примера — установите библиотеку Scheduler из менеджера библиотек.
- scheduler-multiple-blinks.ino
// подключаем библиотеку «Scheduler» для выполнения несколько задач одновременно #include <Scheduler.h> // имена пинов светодиодов #define LED_RED 10 #define LED_GREEN 9 #define LED_BLUE 8 void setup() { // выставляем светодиоды в режим выхода pinMode(LED_RED, OUTPUT); pinMode(LED_GREEN, OUTPUT); pinMode(LED_BLUE, OUTPUT); // добавляем в планировщик функции loop2 и loop3; // loop() всегда запускается по умолчанию: Scheduler.startLoop(loop2); Scheduler.startLoop(loop3); } // задача номер 1: мигать светодиодом с двух секундной задержкой void loop() { // зажигаем светодиод digitalWrite(LED_BLUE, HIGH); // когда запущено несколько задач // delay() переводит задачу в состояние ожидания и передает управление другим задачам // тем самым гарантируя, что они будут выполняться delay(2000); // гасим светодиод digitalWrite(LED_BLUE, LOW); delay(2000); } // задача номер 2: мигать светодиодом каждые 500 мс void loop2() { // зажигаем светодиод digitalWrite(LED_GREEN, HIGH); delay(500); // гасим светодиод digitalWrite(LED_GREEN, LOW); delay(500); } // задача номер 3: мигать светодиодом каждые 200 мс void loop3() { // зажигаем светодиод digitalWrite(LED_RED, HIGH); delay(200); // гасим светодиод digitalWrite(LED_RED, LOW); delay(200); // функцию yield() нужно вызывать постоянно // чтобы передавать управление другим задачам yield(); }
После загрузки кода вы увидите, что каждый «loop» живёт своей жизнью. И задержки функцией «delay» влияют только на свой блок внутри функции.