- Шта је мултитаскинг?
- Зашто прескочити кашњење () у Ардуину?
- Зашто користити милис ()?
- Компоненте потребне
- Кружни дијаграм
- Програмирање Ардуино УНО за мултитаскинг
Мултитаскинг је довело рачунаре до револуције у којој један или више програми могу покренути истовремено чиме се повећава ефикасност, флексибилност, прилагодљивост и продуктивност. У уграђеним системима микроконтролери такође могу да се баве мултитаскингом и истовремено извршавају два или више задатака без заустављања тренутних упутстава.
Овде ћемо у овом упутству научити како Ардуино изводи мултитаскинг са функцијом Ардуино миллис. Генерално функција одлагања () се користи у Ардуину за периодични задатак попут ЛЕД-а који трепће, али ова функција одлагања () зауставља програм на одређено време и не дозвољава обављање других операција. Дакле, овај чланак објашњава како можемо да избегнемо употребу функције делаи () и заменимо је милисом () за истовремено извршавање више задатака и да Ардуино учинимо мултитаскинг контролером. Пре него што улазимо у детаље, кренимо са подцењивањем вишезадаћности.
Шта је мултитаскинг?
Мултитаскинг једноставно значи извршавање више задатака или програма истовремено. Готово сви оперативни системи имају вишезадаћност. Ова врста оперативних система позната је под називом МОС (мултитаскинг оперативни систем). МОС може бити мобилни или оперативни систем за стони рачунар. Добар пример мултитаскинга на рачунарима је када корисници истовремено покрећу апликацију за е-пошту, интернет прегледач, медијски плејер, игре и ако корисници не желе да користе апликацију која се покреће у позадини ако није затворена. Крајњи корисник истовремено користи све ове апликације, али ОС схвата овај концепт мало другачије. Хајде да разговарамо о томе како ОС управља мултитаскингом.
Као што се види на слици, ЦПУ дели време на три једнака дела и сваки део додељује сваком задатку / апликацији. Тако се обавља мултитаскинг у већини система. Концепт ће бити готово исти за Ардуино Мултитаскинг, осим што ће расподела времена бити мало другачија. Будући да Ардуино ради на ниским фреквенцијама и РАМ меморија се упоређује са Лаптоп / Мобиле / ПЦ тако да ће и време дато сваком задатку бити другачије. Ардуино такође има функцију одлагања () која се широко користи. Али пре почетка, разговарајмо о томе зашто не бисмо требали користити функцију делаи () у било ком пројекту.
Зашто прескочити кашњење () у Ардуину?
Уколико се сматра референтна документација Ардуино онда постоји два типа функција кашњење, прва је кашњење () а други је делаиМицросецондс (). Обе функције су идентичне у смислу генерисања кашњења. Једина разлика је у томе што се у функцији делаи () цео број параметра предаје у милисекундама, тј. Ако напишемо делаи (1000) тада ће кашњење бити 1000 милисекунди, односно 1 секунда. Слично функцији делаиМицросецондс (), прослеђени параметар је у микросекундама, тј. Ако напишемо делаиМицросецондс (1000), тада ће кашњење бити 1000 микросекунди, односно 1 милисекунди.
Овде долази ствар, обе функције паузирају програм за време проведено у функцији одлагања. Дакле, ако дајемо кашњење од 1 секунде, процесор не може да пређе на следећу инструкцију док не прође 1 секунда. Слично томе, ако је кашњење 10 секунди, програм ће се зауставити на 10 секунди, а процесор неће дозволити да следи следећа упутства док не прође 10 секунди. Ово омета перформансе микроконтролера у погледу брзине и извршавања упутстава.
Најбољи пример за објашњење недостатка функције одлагања је коришћење два тастера. Узмите у обзир да желимо да пребацимо две ЛЕД диоде помоћу два тастера. Дакле, ако се притисне један тастер, тада би одговарајућа ЛЕД лампица требало да светли 2 секунде, слично ако се притисне друга, ЛЕД би требало да светли 4 секунде. Али када користимо делаи (), ако корисник притисне прво дугме, програм ће се зауставити на 2 секунде, а ако корисник притисне друго дугме пре одлагања од 2 секунде, тада микроконтролер неће прихватити улаз као што је програм у фази заустављања.
Званична документација Ардуина то јасно помиње у опису функције Напомене и упозорења о одлагању (). Можете то проћи и проверити да бисте то учинили јаснијим.
Зашто користити милис ()?
Да би превазишао проблем узрокован коришћењем кашњења, програмер би требало да користи милис () функцију која је једноставна за употребу након што постанете уобичајена и користиће 100% перформансе процесора без генерисања било каквог одлагања у извршавању упутстава. миллис () је функција која само враћа количину милисекунди протеклих од тренутка када је Ардуино плоча почела да изводи тренутни програм без замрзавања програма. Овај временски број ће се прелити (тј. Вратити на нулу), након приближно 50 дана.
Баш као што Ардуино има делаиМицросецондс (), он такође има микро верзију миллис () као мицрос (). Разлика између микро и милиса је у томе што ће се микро () прелити након приближно 70 минута, у поређењу са милисом () што је 50 дана. Дакле, у зависности од апликације можете да користите милисекунде () или микро ().
Употреба милиса () уместо одлагања ():
Да бисте милис () користили за мерење времена и кашњење, потребно је да забележите и сачувате време у коме се одвијала радња да бисте започели време, а затим у интервалима проверавали да ли је дефинисано време прошло. Дакле, како је наведено, тренутно време сачувајте у променљивој.
унсигнед лонг цуррентМиллис = миллис ();
Потребне су нам још две променљиве да бисмо сазнали да ли је потребно време прошло. Тренутно време смо ускладиштили у променљиву цуррентМиллис, али такође морамо знати када је почео временски период и колико је дуг период. Тако је проглашен Интервал и превиоусМиллис . Интервал ће нам рећи временско кашњење, а превиосМиллис ће сачувати последњи пут када се догађај догодио.
унсигнед лонг превиоусМиллис; непотписан дуги период = 1000;
Да бисмо то разумели, узмимо пример једноставног трепћућег ЛЕД-а. Период = 1000 ће нам рећи да ће ЛЕД трептати 1 секунду или 1000 мс.
цонст инт ледПин = 4; // ЛЕД пин број повезан инт ледСтате = ЛОВ; // користи се за постављање ЛЕД стања непотписано лонг превиоусМиллис = 0; // чуваће се последњи пут трептање ЛЕД-а цонст лонг период = 1000; // период у којем треба трептати у мс воид сетуп () { пинМоде (ледПин, ОУТПУТ); // постављамо ледпин као излаз } воид лооп () { унсигнед лонг цуррентМиллис = миллис (); // чување тренутног времена иф (цуррентМиллис - превиоусМиллис> = период) {// проверити да ли је прошло 1000мс превиоусМиллис = цуррентМиллис; // сачувајте последњи пут када сте трепнули ЛЕД ако (ледСтате == ЛОВ) {// ако је ЛЕД искључен, укључите га и обрнуто ледСтате = ХИГХ; } елсе { ледСтате = ЛОВ; } дигиталВрите (ледПин, ледСтате); // подесимо ЛЕД да ледСтате поново трепће } }
Ево, изјава
Прекиди у Ардуину раде исто као и код других микроконтролера. Ардуино УНО табла има два одвојена пина за причвршћивање прекида на ГПИО пину 2 и 3. Детаљно смо то покрили у Водичу за прекиде Ардуино, где можете сазнати више о прекидима и како их користити.
Овде ћемо приказати Ардуино Мултитаскинг обрађивањем два задатка истовремено. Задаци ће укључивати трептање две ЛЕД диоде у различитим временским кашњењима, заједно са дугметом који ће се користити за управљање ОН / ОФФ стањем ЛЕД диоде. Тако ће се истовремено обављати три задатка.
Компоненте потребне
- Ардуино УНО
- Три ЛЕД (било које боје)
- Отпори (470, 10к)
- Скакачи
- Бреадбоард
Кружни дијаграм
Шема кола за демонстрацију употребе фукције Ардуино Миллис () врло је једноставна и нема пуно компонената за причвршћивање, као што је приказано доле.
Програмирање Ардуино УНО за мултитаскинг
Програмирање Ардуино УНО-а за мултитаскинг захтијеваће само логику рада милиса () која је горе објашњена. Пре него што почнете да програмирате Ардуино УНО за мултитаскинг, препоручује се изнова и изнова вежбати ЛЕД за трептање помоћу милиса да бисте логику учинили јасном и пријатнијом за милис (). У овом упутству, прекид се користи и са милисом () истовремено за мултитаскинг. Дугме ће бити прекид. Дакле, кад год се генерише прекид, односно притисне тастер, ЛЕД ће се пребацити у стање УКЉУЧЕНО или ИСКЉУЧЕНО.Програмирање започиње декларисањем бројева пинова где су повезане ЛЕД и тастер.
инт лед1 = 6; инт лед2 = 7; инт тогглеЛед = 5; инт пусхБуттон = 2;
Даље напишемо променљиву за чување статуса ЛЕД диода за будућу употребу.
инт ледСтате1 = ЛОВ; инт ледСтате2 = ЛОВ;
Баш као што је горе објашњено у примеру трептања, променљиве за период и превиоусмиллис су декларисане да упоређују и генеришу кашњење за ЛЕД диоде. Прва ЛЕД лампица трепће након сваке 1 секунде, а друга ЛЕД лампица трепери након 200 мс.
унсигнед лонг превиоусМиллис1 = 0; цонст дуги период1 = 1000; унсигнед лонг превиоусМиллис2 = 0; цонст дуги период2 = 200;
Још једна милис функција ће се користити за генерисање кашњења звука како би се избегло вишеструко притискање тастера. Биће сличан приступ као горе.
инт дебоунцеПериод = 20; инт дебоунцеМиллис = 0;
У три варијабле ће се користити за чување статус тастера у као прекида, ЛЕД и кнопочного државе искључи.
боол буттонПусхед = фалсе; инт ледЦханге = ЛОВ; инт ластСтате = ВИСОКО;
Дефинишите акцију пин-а онај који ће радити као ИНПУТ или ОУТПУТ.
пинМоде (лед1, ИЗЛАЗ); пинМоде (лед2, ИЗЛАЗ); пинМоде (тогглеЛед, ОУТПУТ); пинМоде (пусхБуттон, ИНПУТ);
Сада дефинишите пин за прекидање тако што ћете приложити прекид са дефиницијом ИСР-а и начина прекида. Имајте на уму да је препоручљиво користити дигиталПинТоИнтеррупт (пин_нумбер) приликом проглашавања функције аттацхИнтеррупт () за превођење стварног дигиталног пин-а на одређени број прекида.
аттацхИнтеррупт (дигиталПинТоИнтеррупт (пусхБуттон), пусхБуттон_ИСР, ЦХАНГЕ);
Подпрограм прекида је написан и само ће променити заставицу буттонПусхед. Имајте на уму да потпрограм прекида треба да буде што краћи, зато покушајте да га напишете и да смањите додатна упутства.
воид пусхБуттон_ИСР () { буттонПусхед = труе; }
Лооп започиње чувањем милис вредности у променљивој цуррентМиллис која ће сачувати вредност протеклог времена сваки пут када се петља понови.
унсигнед лонг цуррентМиллис = миллис ();
У мултитаскингу постоје укупно три функције, трепћући једну ЛЕД диоду за 1 секунду, треперећу другу ЛЕД диоду за 200 мс и ако се притисне дугме, искључите / укључите ЛЕД. Тако ћемо написати три дела за овај задатак.
Први је пребацује ЛЕД стање након сваке 1 секунде упоређивањем Миллис прошло.
иф (цуррентМиллис - превиоусМиллис1> = период1) { превиоусМиллис1 = цуррентМиллис; ако (ледСтате1 == ЛОВ) { ледСтате1 = ХИГХ; } елсе { ледСтате1 = ЛОВ; } дигиталВрите (лед1, ледСтате1); }
Слично томе, друго, пребацује ЛЕД након сваких 200 мс упоређивањем протеклих милисекунди. Објашњење је већ објашњено раније у овом чланку.
иф (цуррентМиллис - превиоусМиллис2> = период2) { превиоусМиллис2 = цуррентМиллис; ако (ледСтате2 == ЛОВ) { ледСтате2 = ХИГХ; } елсе { ледСтате2 = ЛОВ; } дигиталВрите (лед2, ледСтате2); }
И на крају, надгледа се заставица буттонПусхед и након генерисања кашњења од 20мс, само се пребацује стање ЛЕД-а одговара дугмету који је причвршћен као прекид.
иф (буттонПусхед = труе) // проверити да ли се позива ИСР { иф ((цуррентМиллис - дебоунцеМиллис)> дебоунцеПериод && буттонПусхед) // генерише 20мс кашњења пропуштања да би се избегло вишеструко притискање { дебоунцеМиллис = цуррентМиллис; // сачувамо последње време кашњења прекида (иф) (ДигиталРеад (пусхБуттон) == ЛОВ && ластСтате == ХИГХ) // променимо лед након притиска дугмета { ледЦханге =! ледЦханге; дигиталВрите (тогглеЛед, ледЦханге); ластСтате = ЛОВ; } елсе иф (дигиталРеад (пусхБуттон) == ХИГХ && ластСтате == ЛОВ) { ластСтате = ХИГХ; } буттонПусхед = фалсе; } }
Овим је завршен водич за Ардуино миллис (). Имајте на уму да да бисте навикли на милисе (), само вежбајте да примените ову логику у неким другим апликацијама. Такође га можете проширити тако да користи моторе, серво моторе, сензоре и другу периферну опрему. У случају било какве сумње, молимо пишите на наш форум или коментаришите доле.
Комплетни код и видео за демонстрацију употребе милис функције у Ардуину су наведени у наставку.