Il multitasking ha portato i computer ad una rivoluzione in cui uno o più programmi possono essere eseguiti contemporaneamente che aumenta l’efficienza, flessibilità, adattabilità e produttività. Nei sistemi embedded, i microcontrollori possono anche gestire il Multitasking ed eseguire due o più attività contemporaneamente senza interrompere le istruzioni correnti.

Qui in questo tutorial impareremo Come Arduino esegue il Multitasking con la funzione Arduino millis. Generalmente una funzione delay() viene utilizzata in Arduino per un compito periodico come il lampeggiamento del LED, ma questa funzione delay() interrompe il programma per un certo tempo definitivo e non consente ad altre operazioni di eseguire. Quindi questo articolo spiega come possiamo evitare l’uso della funzione delay() e sostituirla con millis() per eseguire più attività contemporaneamente e rendere Arduino un controller Multitasking. Prima di entrare nei dettagli iniziamo con la sottovalutazione del Multitasking.

Che cos’è il multitasking?

Multitasking significa semplicemente l’esecuzione di più di un compito o programma contemporaneamente allo stesso tempo. Quasi tutti i sistemi operativi dispongono di multitasking. Questo tipo di sistemi operativi sono noti come MOS (multitasking operating system). Il MOS può essere un sistema operativo per PC mobile o desktop. Il buon esempio di multitasking nei computer sono quando gli utenti eseguono l’applicazione di posta elettronica, browser Internet, lettore multimediale, giochi, allo stesso tempo e se gli utenti non vogliono utilizzare l’applicazione viene eseguito in background se non chiuso. L’utente finale utilizza tutte queste applicazioni allo stesso tempo, ma il sistema operativo prende questo concetto un po ‘ diverso. Discutiamo di come il sistema operativo gestisce il multitasking.

Cos'è il Multitasking in Arduino

Come si vede nell’immagine, la CPU divide il tempo nelle tre parti uguali e assegna ogni parte a ciascuna attività/applicazione. Questo è come il multitasking è fatto nella maggior parte dei sistemi. Il concetto sarà quasi lo stesso per il Multitasking Arduino, tranne che la distribuzione temporale sarà un po ‘ diversa. Dal momento che l’Arduino funziona in bassa frequenza e RAM confrontare al computer portatile / Mobile / PC in modo che il tempo dato ad ogni attività sarà anche diverso. Arduino ha anche una funzione di ritardo() che è ampiamente utilizzato. Ma prima di iniziare, discutiamo del motivo per cui non dovremmo usare la funzione delay() in nessun progetto.

Perché saltare delay () in Arduino?

Se viene considerata la documentazione di riferimento di Arduino, esistono due tipi di funzioni di ritardo, la prima è delay() e la seconda è delayMicroseconds(). Entrambe le funzioni sono identiche in termini di ritardo di generazione. L’unica differenza è che, nella funzione delay (), il parametro integer passato è in millisecondi, cioè se scriviamo delay(1000), il ritardo sarà di 1000 millisecondi, cioè 1 secondo. Allo stesso modo nella funzione delayMicroseconds (), il parametro passato è in microsecondi cioè se scriviamo delayMicroseconds(1000), allora il ritardo sarà di 1000 microsecondi cioè 1 millisecondi.

Ecco che arriva il punto, entrambe le funzioni mettono in pausa il programma per la quantità di tempo trascorso in funzione di ritardo. Quindi, se stiamo dando un ritardo di 1 secondo, il processore non può andare all’istruzione successiva fino a quando non passa 1 secondo. Allo stesso modo, se il ritardo è di 10 secondi, il programma si fermerà per 10 secondi e il processore non permetterà di andare per le istruzioni successive fino a quando non passeranno i 10 secondi. Ciò ostacola le prestazioni del microcontrollore in termini di velocità ed esecuzione delle istruzioni.

Il miglior esempio per spiegare l’inconveniente della funzione di ritardo è l’utilizzo di due pulsanti. Considera che vogliamo alternare due LED usando due pulsanti. Quindi, se viene premuto un pulsante, il LED corrispondente dovrebbe illuminarsi per 2 secondi, allo stesso modo se il secondo viene premuto, il LED dovrebbe illuminarsi per 4 secondi. Ma quando usiamo delay (), se l’utente sta premendo il primo pulsante, il programma si fermerà per 2 secondi e se l’utente preme il secondo pulsante prima di 2 secondi di ritardo, il microcontrollore non accetterà l’input poiché il programma è in fase di arresto.

La documentazione ufficiale di Arduino lo menziona chiaramente nelle sue Note e avvertenze sulla descrizione della funzione delay (). Si può passare attraverso e controllare questo fuori per renderlo più chiaro.

Perché usare millis ()?

Per superare il problema causato dall’utilizzo del ritardo, uno sviluppatore dovrebbe utilizzare la funzione millis() che è facile da usare una volta diventato abituale e utilizzerà il 100% delle prestazioni della CPU senza generare alcun ritardo nell’esecuzione delle istruzioni. millis() è una funzione che restituisce solo la quantità di millisecondi trascorsi da quando la scheda Arduino ha iniziato a eseguire il programma corrente senza congelare il programma. Questo numero di tempo traboccherà (cioè tornerà a zero), dopo circa 50 giorni.

Proprio come Arduino hanno delayMicrosecondi (), ha anche la versione micro di millis () come micros (). La differenza tra micros e millis è che micros () traboccherà dopo circa 70 minuti, rispetto a millis () che è di 50 giorni. Quindi, a seconda dell’applicazione è possibile utilizzare millis() o micros().

Using millis() instead of delay():

Per utilizzare il millis() per la temporizzazione e il ritardo, è necessario registrare e memorizzare l’ora in cui l’azione ha avuto luogo per avviare l’ora e quindi controllare a intervalli se il tempo definito è passato. Quindi, come affermato, memorizza l’ora corrente in una variabile.

unsigned long currentMillis = millis();

Abbiamo bisogno di altre due variabili per scoprire se il tempo richiesto è passato. Abbiamo memorizzato l’ora corrente nella variabile currentMillis, ma dobbiamo anche sapere quando è iniziato il periodo di temporizzazione e quanto è lungo il periodo. Quindi l’Intervallo e il precedentemillis è dichiarato. L’intervallo ci dirà il ritardo temporale e previosMillis memorizzerà l’ultima volta che si è verificato l’evento.

unsigned long previousMillis;unsigned long period = 1000;

Per capire questo, prendiamo un esempio di un semplice LED lampeggiante. Periodo = 1000 ci dirà che il LED lampeggia per 1 secondo o 1000ms.

const int ledPin = 4; // the LED pin number connectedint ledState = LOW; // used to set the LED stateunsigned long previousMillis = 0; //will store last time LED was blinkedconst long period = 1000; // period at which to blink in msvoid setup() { pinMode(ledPin, OUTPUT); // set ledpin as output}void loop() { unsigned long currentMillis = millis(); // store the current time if (currentMillis - previousMillis >= period) { // check if 1000ms passed previousMillis = currentMillis; // save the last time you blinked the LED if (ledState == LOW) { // if the LED is off turn it on and vice-versa ledState = HIGH; } else {ledState = LOW;} digitalWrite(ledPin, ledState);//set LED with ledState to blink again }}

Qui, l’istruzione <se (currentMillis – previousMillis >= periodo)> controlla se il 1000ms è passato. Se 1000 ms è passato, poi il LED lampeggia e di nuovo arriva allo stesso stato. E questo continua. Questo è tutto, abbiamo imparato a usare millis invece di ritardo. In questo modo non fermerà il programma per un intervallo particolare.

Interrupt in Arduino funziona come in altri microcontrollori. La scheda Arduino UNO ha due pin separati per il collegamento di interrupt sui pin GPIO 2 e 3. Abbiamo coperto in dettaglio in Arduino Interrupts Tutorial, dove si può imparare di più su Interrupt e come usarli.

Qui mostreremo Arduino Multitasking gestendo due attività contemporaneamente. Le attività includeranno lampeggiante di due LED in tempo diverso ritardo con un pulsante che verrà utilizzato per controllare lo stato ON/OFF del LED. Quindi tre compiti verranno eseguiti contemporaneamente.

Schema del Circuito per Arduino Multitasking

Componenti

  • Arduino UNO
  • Tre Led(di Qualsiasi Colore)
  • Resistenze (470, 10k)
  • Pullover
  • Breadboard

Schema elettrico

lo schema Del circuito per dimostrare l’uso di Arduino Millis() fuction è molto semplice e non ha componenti di allegare come mostrato di seguito.

Schema elettrico per Arduino Multitasking utilizzando Arduino Millis() Funzione

Programmazione Arduino UNO per Multitasking

Programmazione Arduino UNO per multitasking richiede solo la logica dietro come millis() lavoro che è spiegato sopra. Si consiglia di praticare blink LED utilizzando millis ancora e ancora per rendere la logica chiara e mettersi a proprio agio con millis() prima di iniziare a programmare Arduino UNO per il multitasking. In questo tutorial l’interrupt viene utilizzato anche con millis() contemporaneamente per il multitasking. Il pulsante sarà un interrupt. Così ogni volta che viene generato un interrupt cioè pulsante viene premuto, il LED passa a ON o OFF stato.

La programmazione inizia con la dichiarazione dei numeri pin in cui sono collegati LED e pulsante.

int led1 = 6;int led2 = 7;int toggleLed = 5;int pushButton = 2;

Successivamente scriviamo una variabile per memorizzare lo stato dei LED per un uso futuro.

int ledState1 = LOW;int ledState2 = LOW;

Proprio come spiegato sopra nell’esempio blink, le variabili per period e previousmillis sono dichiarate per confrontare e generare ritardo per i LED. Il primo LED lampeggia dopo ogni 1 secondo e un altro LED lampeggia dopo 200 ms.

unsigned long previousMillis1 = 0; const long period1 = 1000;unsigned long previousMillis2 = 0;const long period2 = 200; 

Un’altra funzione millis verrà utilizzata per generare il ritardo di debounce per evitare le molteplici pressioni del pulsante. Ci sarà un approccio simile come sopra.

int debouncePeriod = 20; int debounceMillis = 0;

Le tre variabili verranno utilizzate per memorizzare lo stato del pulsante come interrupt, toggle LED e push button state.

bool buttonPushed = false;int ledChange = LOW; int lastState = HIGH;

Definisce l’azione del pin che il pin funzionerà come INPUT o OUTPUT.

 pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(toggleLed, OUTPUT); pinMode(pushButton, INPUT);

Ora definire il pin di interrupt collegando interrupt con definizione di ISR e modalità di interrupt. Si noti che si consiglia di utilizzare digitalPinToInterrupt(pin_number) quando si dichiara la funzione attachInterrupt() per tradurre il pin digitale effettivo al numero di interrupt specifico.

attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE); 

La subroutine di interrupt è scritta e cambierà solo il flag buttonPushed. Si noti che, interrupt subroutine dovrebbe essere il più breve possibile, quindi prova a scriverlo e ridurre al minimo le istruzioni extra.

void pushButton_ISR(){ buttonPushed = true; }

Il ciclo inizia con la memorizzazione del valore millis in una variabile currentMillis che memorizzerà il valore del tempo trascorso ogni volta che il ciclo itera.

unsigned long currentMillis = millis();

Ci sono in totale tre funzioni in multitasking, lampeggiare un LED a 1 secondo, lampeggiare secondo LED a 200 ms e Se si preme il pulsante poi spegnere / ON LED. Quindi scriveremo tre parti per fare questo compito.

Il primo è attiva lo stato del LED dopo ogni 1 secondo confrontando i millis trascorsi.

 if (currentMillis - previousMillis1 >= period1) { previousMillis1 = currentMillis; if (ledState1 == LOW) { ledState1 = HIGH; } else { ledState1 = LOW; } digitalWrite(led1, ledState1); }

Allo stesso modo il secondo commuta il LED dopo ogni 200ms confrontando i millis trascorsi. La spiegazione è già spiegata in precedenza in questo articolo.

 if (currentMillis - previousMillis2 >= period2) { previousMillis2 = currentMillis; if (ledState2 == LOW) { ledState2 = HIGH; } else { ledState2 = LOW; } digitalWrite(led2, ledState2); }

Infine, viene monitorato il flag buttonPushed e dopo aver generato un ritardo di debounce di 20ms si attiva solo lo stato del LED corrispondente al pulsante collegato come interrupt.

 if (buttonPushed = true) // check if ISR is called { if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed) // generate 20ms debounce delay to avoid multiple presses { debounceMillis = currentMillis; // save the last debounce delay time if (digitalRead(pushButton) == LOW && lastState == HIGH) // change the led after push button is pressed { ledChange = ! ledChange; digitalWrite(toggleLed, ledChange); lastState = LOW; } else if (digitalRead(pushButton) == HIGH && lastState == LOW) { lastState = HIGH; } buttonPushed = false; } }

Questo termina il Tutorial di Arduino millis (). Si noti che per diventare abituali con millis(), basta esercitarsi a implementare questa logica in alcune altre applicazioni. È inoltre possibile espanderlo per utilizzare motori, servomotori, sensori e altre periferiche. In caso di dubbio allora si prega di scrivere al nostro forum o commento qui sotto.

Codice completo e video per dimostrare l’uso della funzione millis in Arduino è fornito di seguito.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.