- Çoklu Görev nedir?
- Arduino'da neden delay () atlanmalı?
- Millis () neden kullanılmalı?
- Gerekli Bileşenler
- Devre şeması
- Arduino UNO'nun Çoklu Görev için Programlanması
Çoklu görev verimliliği, esneklik, uyum ve üretkenliği artırır bir veya birden fazla program aynı anda çalıştırabilirsiniz bir devrim bilgisayarları yol açmıştır. Gömülü sistemlerde, mikro denetleyiciler aynı zamanda Çoklu Görevleri de gerçekleştirebilir ve mevcut talimatları durdurmadan iki veya daha fazla görevi aynı anda gerçekleştirebilir.
Bu eğitimde Arduino'nun Arduino millis fonksiyonu ile Çoklu Görevleri nasıl gerçekleştirdiğini öğreneceğiz. Genellikle Arduino'da LED Yanıp Sönme gibi periyodik bir görev için bir delay () işlevi kullanılır, ancak bu delay () işlevi programı belirli bir süre için durdurur ve diğer işlemlerin gerçekleştirilmesine izin vermez. Bu nedenle, bu makale, aynı anda birden fazla görevi gerçekleştirmek ve Arduino'yu Çoklu Görev denetleyicisi yapmak için delay () işlevinin kullanımından nasıl kaçınabileceğimizi ve bunu millis () ile nasıl değiştirebileceğimizi açıklamaktadır. Ayrıntılara girmeden önce Çoklu Görev'i anlamaya başlayalım.
Çoklu Görev nedir?
Çoklu görev, aynı anda birden fazla görevi veya programı aynı anda yürütmek anlamına gelir. Hemen hemen tüm işletim sistemleri çoklu görev özelliğine sahiptir. Bu tür işletim sistemleri MOS (çok görevli işletim sistemi) olarak bilinir. MOS, mobil veya masaüstü PC İşletim Sistemi olabilir. Bilgisayarlarda çoklu görev yapmanın güzel bir örneği, kullanıcıların e-posta uygulamasını, internet tarayıcısını, medya oynatıcıyı, oyunları aynı anda çalıştırması ve kullanıcılar uygulamayı kullanmak istemezse, kapatılmamışsa arka planda çalışır. Son kullanıcı tüm bu uygulamaları aynı anda kullanıyor ancak işletim sistemi bu kavramı biraz farklı alıyor. İşletim sisteminin çoklu görevi nasıl yönettiğini tartışalım.
Resimde görüldüğü gibi CPU, zamanı üç eşit parçaya böler ve her parçayı her bir göreve / uygulamaya atar. Sistemlerin çoğunda çoklu görev bu şekilde yapılır. Arduino Çoklu Görev için konsept neredeyse aynı olacak, ancak zaman dağılımı biraz farklı olacak. Arduino, Dizüstü Bilgisayar / Mobil / PC ile karşılaştırıldığında düşük frekansta ve RAM'de çalıştığından, her göreve verilen süre de farklı olacaktır. Arduino ayrıca yaygın olarak kullanılan bir delay () fonksiyonuna da sahiptir. Ancak başlamadan önce , herhangi bir projede neden delay () fonksiyonunu kullanmamamız gerektiğini tartışalım .
Arduino'da neden delay () atlanmalı?
Arduino'nun referans dokümantasyonu dikkate alınırsa, iki tür gecikme işlevi vardır, birincisi delay () ve ikincisi delayMicroseconds (). Her iki işlev de gecikme oluşturma açısından aynıdır. Tek fark, delay () fonksiyonunda geçirilen parametre tamsayısının milisaniye cinsinden olmasıdır, yani eğer gecikme (1000) yazarsak, gecikme 1000 milisaniye yani 1 saniye olacaktır. Aynı şekilde delayMicroseconds () fonksiyonunda da geçen parametre mikrosaniye cinsindendir, yani eğer delayMicroseconds (1000) yazarsak gecikme 1000 mikrosaniye yani 1 milisaniye olacaktır.
İşte nokta geliyor, her iki işlev de geciktirme işlevinde geçen süre kadar programı duraklatıyor. Yani 1 saniyelik bir gecikme veriyorsak, işlemci 1 saniye geçene kadar bir sonraki talimata gidemez. Benzer şekilde, gecikme 10 saniye ise, program 10 saniye duracak ve işlemci 10 saniye geçene kadar sonraki talimatlara geçmesine izin vermeyecektir. Bu, mikro denetleyicinin performansını hız ve talimatların yürütülmesi açısından engeller.
Gecikme işlevinin dezavantajını açıklamak için en iyi örnek, iki düğme kullanmaktır. İki düğmeyi kullanarak iki LED'i değiştirmek istediğimizi düşünün. Bu nedenle, bir düğmeye basıldığında ilgili LED 2 saniye yanmalıdır, benzer şekilde ikinci basıldığında LED 4 saniye yanmalıdır. Ancak delay () 'i kullandığımızda, kullanıcı birinci butona basarsa program 2 saniye durur ve eğer kullanıcı ikinci butona 2 saniye gecikmeden basarsa mikrokontrolör girişi program olduğu için kabul etmez. durma aşamasında.
Arduino'nun resmi dokümantasyonu, bunu Notlar ve Gecikme Uyarıları () işlev açıklamasında açıkça belirtmektedir. Daha net hale getirmek için bunu inceleyebilir ve kontrol edebilirsiniz.
Millis () neden kullanılmalı?
Gecikme kullanımının neden olduğu sorunun üstesinden gelmek için, bir geliştirici, alışkanlık haline geldiğinizde kullanımı kolay olan ve komutların yürütülmesinde herhangi bir gecikme oluşturmadan% 100 CPU performansını kullanacak olan millis () işlevini kullanmalıdır. millis (), Arduino kartının programı dondurmadan mevcut programı çalıştırmaya başlamasından bu yana geçen milisaniye miktarını döndüren bir işlevdir. Bu zaman sayısı yaklaşık 50 gün sonra aşacaktır (yani sıfıra dönecektir).
Tıpkı Arduino'nun delayMicroseconds () özelliğine sahip olması gibi, ayrıca micros () olarak millis () 'in mikro versiyonuna da sahiptir . Mikrolar ve millis arasındaki fark, micros () 'nin 50 gün olan millis () ile karşılaştırıldığında yaklaşık 70 dakika sonra taşmasıdır. Dolayısıyla, uygulamaya bağlı olarak, millis () veya micros () kullanabilirsiniz.
Delay () yerine millis () kullanma:
Zamanlama ve gecikme için millis () işlevini kullanmak için, zamanı başlatmak üzere eylemin gerçekleştiği zamanı kaydetmeniz ve kaydetmeniz ve ardından belirli aralıklarla tanımlanan zamanın geçip geçmediğini kontrol etmeniz gerekir. Belirtildiği gibi, geçerli saati bir değişkende saklayın.
işaretsiz uzun currentMillis = millis ();
Gereken sürenin geçip geçmediğini anlamak için iki değişkene daha ihtiyacımız var. Güncel saati currentMillis değişkeninde sakladık, ancak zamanlama döneminin ne zaman başladığını ve dönemin ne kadar uzun olduğunu da bilmemiz gerekiyor. Böylece Interval ve previousMillis bildirildi. Aralık bize zaman gecikmesini söyleyecek ve previosMillis olayın en son meydana geldiği zamanı kaydedecektir.
imzasız uzun previousMillis; imzasız uzun dönem = 1000;
Bunu anlamak için basit bir yanıp sönen LED örneğini ele alalım. Periyot = 1000 bize LED'in 1 saniye veya 1000ms yanıp söneceğini söyleyecektir.
const int ledPin = 4; // bağlı LED pin numarası int ledState = LOW; // LED durumunu işaretsiz uzun bir süre önce ayarlamak için kullanılır previousMillis = 0; // LED'in en son yanıp söndüğü zamanı kaydedecek const long period = 1000; // ms'de yanıp sönme süresi void setup () { pinMode (ledPin, OUTPUT); // ledpin'i çıktı olarak ayarla } void loop () { unsigned long currentMillis = millis (); // geçerli zamanı sakla if (currentMillis - previousMillis> = period) {// 1000 ms'nin geçip geçmediğini kontrol et previousMillis = currentMillis; // if (ledState == LOW) {// LED kapalıysa onu açın ve tersi ledState = HIGH if (ledState == LOW) {// } else { ledState = LOW; } digitalWrite (ledPin, ledState); // ledState ile LED'i tekrar yanıp sönmeye ayarlayın } }
İşte ifade
Arduino'daki kesintiler diğer mikrodenetleyicilerde olduğu gibi çalışır. Arduino UNO kartının GPIO pin 2 ve 3'teki kesintileri eklemek için iki ayrı pimi vardır. Kesintiler ve bunların nasıl kullanılacağı hakkında daha fazla bilgi edinebileceğiniz Arduino Kesintileri Eğitimi'nde detaylı olarak ele aldık.
Burada , aynı anda iki görevi yerine getirerek Arduino Çoklu Görevini göstereceğiz . Görevler, LED'in AÇIK / KAPALI durumunu kontrol etmek için kullanılacak bir düğme ile birlikte farklı zaman gecikmelerinde iki LED'in yanıp sönmesini içerecektir. Böylece aynı anda üç görev gerçekleştirilecektir.
Gerekli Bileşenler
- Arduino UNO
- Üç LED (Herhangi Bir Renk)
- Dirençler (470, 10k)
- Süveter
- Breadboard
Devre şeması
Arduino Millis () işlevinin kullanımını göstermek için devre şeması çok kolaydır ve aşağıda gösterildiği gibi eklenecek çok fazla bileşeni yoktur.
Arduino UNO'nun Çoklu Görev için Programlanması
Arduino UNO'nun çoklu görev için programlanması yalnızca, yukarıda açıklanan millis () işlevinin nasıl çalıştığının arkasındaki mantığı gerektirir. Arduino UNO'yu çoklu görev için programlamaya başlamadan önce mantığı netleştirmek ve millis () ile kendinizi rahat ettirmek için yanıp sönen LED'i tekrar tekrar milis kullanarak pratik yapmanız önerilir . Bu eğitimde, kesme aynı zamanda çoklu görev için millis () ile de kullanılır. Düğme bir kesinti olacaktır. Dolayısıyla, bir kesinti oluşturulduğunda, yani basma düğmesine basıldığında, LED AÇIK veya KAPALI durumuna geçecektir.Programlama, LED'lerin ve Basma Düğmesinin bağlandığı pin numaralarının bildirilmesiyle başlar.
int led1 = 6; int led2 = 7; int toggleLed = 5; int pushButton = 2;
Daha sonra, ileride kullanmak üzere LED'lerin durumunu saklamak için bir değişken yazıyoruz.
int ledState1 = DÜŞÜK; int ledState2 = DÜŞÜK;
Yukarıda yanıp sönme örneğinde açıklandığı gibi, dönem ve önceki millik değişkenler, LED'leri karşılaştırmak ve geciktirmek için beyan edilir. İlk LED her 1 saniyede bir yanıp söner ve 200 ms sonra başka bir LED yanıp söner.
işaretsiz uzun previousMillis1 = 0; const uzun dönem1 = 1000; işaretsiz uzun previousMillis2 = 0; const uzun period2 = 200;
Düğmeye birden fazla basılmasını önlemek için geri çevrilme gecikmesini oluşturmak için başka bir milis işlevi kullanılacaktır. Yukarıdakine benzer bir yaklaşım olacaktır.
int debouncePeriod = 20; int debounceMillis = 0;
Üç değişken kesme olarak düğme durumunu saklamak için kullanılacak LED ve düğme durumuna geçiş.
bool buttonPushed = false; int ledChange = DÜŞÜK; int lastState = YÜKSEK;
Hangi pinin GİRİŞ veya ÇIKIŞ olarak çalışacağı pinin hareketini tanımlayınız.
pinMode (led1, OUTPUT); pinMode (led2, OUTPUT); pinMode (toggleLed, OUTPUT); pinMode (pushButton, INPUT);
Şimdi, ISR ve kesme Modu tanımıyla interrupt ekleyerek interrupt pinini tanımlayın. Gerçek dijital pini belirli kesme numarasına çevirmek için attachInterrupt () işlevini bildirirken digitalPinToInterrupt (pin_number) kullanılması tavsiye edilir.
attachInterrupt (digitalPinToInterrupt (pushButton), pushButton_ISR, CHANGE);
Interrupt alt rutini yazılır ve sadece buttonPushed bayrağını değiştirir. Unutmayın, interrupt alt yordamı olabildiğince kısa olmalıdır, bu yüzden yazmaya çalışın ve ekstra talimatları en aza indirin.
void pushButton_ISR () { buttonPushed = true; }
Döngü, milis değerini bir currentMillis değişkeninde depolamakla başlar; bu, döngü her yinelendiğinde geçen zamanın değerini saklayacaktır.
işaretsiz uzun currentMillis = millis ();
Çoklu görevde toplam üç fonksiyon vardır, 1 saniyede bir LED yanıp söner, 200ms'de ikinci LED yanıp söner ve eğer butona basılırsa LED'i KAPAT / AÇ. Yani bu görevi yapmak için üç bölüm yazacağız.
İlk Millis karşılaştırarak, her 1 saniye sonra durum LED geçiş yapar geçen olup.
eğer (currentMillis - previousMillis1> = period1) { previousMillis1 = currentMillis; eğer (ledState1 == LOW) { ledState1 = HIGH; } else { ledState1 = DÜŞÜK; } digitalWrite (led1, ledState1); }
Benzer şekilde ikincisi, geçen milleri karşılaştırarak her 200 ms sonra LED'i değiştirir. Açıklama, bu makalenin önceki bölümlerinde zaten açıklanmıştır.
eğer (currentMillis - previousMillis2> = period2) { previousMillis2 = currentMillis; eğer (ledState2 == LOW) { ledState2 = HIGH; } else { ledState2 = DÜŞÜK; } digitalWrite (led2, ledState2); }
Son olarak, buttonPushed bayrağı izlenir ve 20ms'lik bir geri çevrilme gecikmesi oluşturduktan sonra, sadece kesinti olarak takılan butona karşılık gelen LED'in durumunu değiştirir.
if (buttonPushed = true) // ISR'nin çağrılıp çağrılmadığını kontrol edin { if ((currentMillis - debounceMillis)> debouncePeriod && buttonPushed) // birden fazla basmayı önlemek için 20 ms geri çevrilme gecikmesi oluşturun { debounceMillis = currentMillis; // eğer (digitalRead (pushButton) == LOW && lastState == HIGH) // son geri çevrilme gecikme süresini kaydedin // düğmeye basıldıktan sonra led'i değiştirin { ledChange =! ledChange; digitalWrite (toggleLed, ledChange); lastState = DÜŞÜK; } else if (digitalRead (pushButton) == HIGH && lastState == LOW) { lastState = HIGH; } buttonPushed = false; } }
Bu, Arduino millis () Öğreticisini bitirir. Millis () ile alışkanlık kazanmak için , bu mantığı diğer bazı uygulamalarda uygulamak için pratik yapın. Ayrıca motorları, servo motorları, sensörü ve diğer çevre birimlerini kullanmak için genişletebilirsiniz. Herhangi bir şüpheniz varsa lütfen forumumuza yazın veya aşağıya yorum yapın.
Arduino'da millis fonksiyonunun kullanımını göstermek için eksiksiz kod ve Video aşağıda verilmiştir.