В микропроцесорната технология задачите, изпълняващи се паралелно, се наричат нишки. Това е много удобно, тъй като често е необходимо да се извършват няколко операции едновременно. Възможно ли е да накарате микроконтролера Arduino да изпълнява няколко задачи наведнъж, като истински процесор? Да видим.
Необходимо е
- - Arduino;
- - 1 светодиод;
- - 1 пиезо зумер.
Инструкции
Етап 1
Най-общо казано, Arduino не поддържа истинска паралелизация или многопоточност.
Но можете да кажете на микроконтролера да провери дали е дошло времето да изпълни някаква допълнителна, фонова задача при всяко повторение на цикъла "loop ()". В този случай на потребителя ще изглежда, че няколко задачи се изпълняват едновременно.
Например, да премигнем светодиод с дадена честота и паралелно да издаваме звуци, които се издигат и падат като сирена от пиезоелектричен излъчвател.
Неведнъж сме свързвали както LED, така и пиезоизлъчвателя към Arduino. Нека сглобим веригата, както е показано на фигурата. Ако свързвате светодиод към цифров щифт, различен от "13", не забравяйте да имате резистор за ограничаване на тока от около 220 ома.
Стъпка 2
Нека напишем скица като тази и да я качим в Arduino.
След зареждане на дъската можете да видите, че скицата не се изпълнява точно така, както ни е необходимо: докато сирената не заработи напълно, светодиодът няма да мига и ние бихме искали светодиодът да мига ПО време на звука на сирената. Какъв е проблемът тук?
Факт е, че този проблем не може да бъде решен по обичайния начин. Задачите се изпълняват от микроконтролера строго последователно. Операторът "delay ()" забавя изпълнението на програмата за определен период от време и докато това време изтече, следните програмни команди няма да бъдат изпълнени. Поради това не можем да зададем различна продължителност на изпълнение за всяка задача в "цикъла ()" на програмата.
Следователно трябва по някакъв начин да симулирате многозадачност.
Стъпка 3
Вариантът, при който Arduino ще изпълнява задачи в псевдопаралел, се предлага от разработчиците на Arduino в статията
Същността на метода е, че при всяко повторение на цикъла "loop ()" проверяваме дали е време да премигнем LED (за изпълнение на фонова задача) или не. И ако се случи, тогава инвертираме състоянието на светодиода. Това е вид заобикаляне на оператора "delay ()".
Съществен недостатък на този метод е, че кодовата секция пред LED контролния блок трябва да се изпълнява по-бързо от мигащия интервал от време на LED "ledInterval". В противен случай мигането ще се случва по-рядко от необходимото и няма да постигнем ефекта на паралелно изпълнение на задачите. По-специално, в нашата скица продължителността на промяната на звука на сирената е 200 + 200 + 200 + 200 = 800 msec и ние задаваме интервала на мигане на LED на 200 msec. Но светодиодът ще мига с период от 800 msec, което е 4 пъти по-различно от това, което сме задали. По принцип, ако в кода се използва операторът "delay ()", тогава е трудно да се симулира псевдопаралелизъм, така че е препоръчително да се избягва.
В този случай би било необходимо единицата за управление на звука на сирената също да провери дали е дошло времето или не и да не използва "delay ()". Но това би увеличило количеството код и ще влоши четливостта на програмата.
Стъпка 4
За да разрешим този проблем, ще използваме прекрасната библиотека ArduinoThread, която ви позволява лесно да създавате псевдопаралелни процеси. Той работи по подобен начин, но ви позволява да не пишете код, за да проверите времето - дали трябва да изпълните задачата в този цикъл или не. Това намалява количеството код и подобрява четливостта на скицата. Нека проверим библиотеката в действие.
Преди всичко изтеглете архива на библиотеката от официалния сайт https://github.com/ivanseidel/ArduinoThread/archive/master.zip и го разархивирайте в директорията "библиотеки" на IDE на Arduino. След това преименувайте папката "ArduinoThread-master" на "ArduinoThread".
Стъпка 5
Схемата на свързване ще остане същата. Ще се промени само програмният код. Сега ще бъде същото като в страничната лента.
В програмата създаваме два потока, всеки изпълнява своя собствена операция: единият мига със светодиод, а вторият контролира звука на сирената. Във всяка итерация на цикъла, за всяка нишка проверяваме дали е дошло времето за нейното изпълнение или не. Ако пристигне, той се стартира за изпълнение с помощта на метода "run ()". Основното нещо е да не използвате оператора "delay ()".
По-подробни обяснения са дадени в кода.
Нека заредим кода в паметта на Arduino, стартирайте го. Сега всичко работи точно както трябва!