Πώς να εκτελέσετε παράλληλες εργασίες (νήματα) σε ένα πρόγραμμα Arduino

Πίνακας περιεχομένων:

Πώς να εκτελέσετε παράλληλες εργασίες (νήματα) σε ένα πρόγραμμα Arduino
Πώς να εκτελέσετε παράλληλες εργασίες (νήματα) σε ένα πρόγραμμα Arduino

Βίντεο: Πώς να εκτελέσετε παράλληλες εργασίες (νήματα) σε ένα πρόγραμμα Arduino

Βίντεο: Πώς να εκτελέσετε παράλληλες εργασίες (νήματα) σε ένα πρόγραμμα Arduino
Βίντεο: ❓ Обязательно к просмотру начинающему в Arduino IDE (ошибка компилятора) 2024, Νοέμβριος
Anonim

Στην τεχνολογία μικροεπεξεργαστή, οι εργασίες που εκτελούνται παράλληλα ονομάζονται Νήματα. Αυτό είναι πολύ βολικό, επειδή είναι συχνά απαραίτητο να εκτελούνται πολλές ενέργειες ταυτόχρονα. Είναι δυνατόν να κάνετε τον μικροελεγκτή Arduino να εκτελεί πολλές εργασίες ταυτόχρονα, όπως ένας πραγματικός επεξεργαστής; Ας δούμε.

Παράλληλες ροές σε ένα πρόγραμμα Arduino
Παράλληλες ροές σε ένα πρόγραμμα Arduino

Είναι απαραίτητο

  • - Arduino;
  • - 1 LED.
  • - 1 πιεζοπιεστής.

Οδηγίες

Βήμα 1

Σε γενικές γραμμές, το Arduino δεν υποστηρίζει την αληθινή παραλληλοποίηση ή το multithreading.

Αλλά μπορείτε να πείτε στον μικροελεγκτή να ελέγξει αν έχει έρθει η ώρα να εκτελέσετε κάποια πρόσθετη, εργασία στο παρασκήνιο σε κάθε επανάληψη του κύκλου "loop ()". Σε αυτήν την περίπτωση, φαίνεται στον χρήστη ότι εκτελούνται ταυτόχρονα πολλές εργασίες.

Για παράδειγμα, ας αναβοσβήσουμε μια λυχνία LED σε μια δεδομένη συχνότητα και, παράλληλα, εκπέμπουμε ήχους που ανεβαίνουν και πέφτουν σαν σειρήνα από πιεζοηλεκτρικό πομπό.

Έχουμε συνδέσει τόσο το LED όσο και το piezo emitter στο Arduino περισσότερες από μία φορές. Ας συναρμολογήσουμε το κύκλωμα όπως φαίνεται στο σχήμα. Εάν συνδέετε ένα LED σε έναν ψηφιακό πείρο εκτός του "13", θυμηθείτε να έχετε μια τρέχουσα περιοριστική αντίσταση περίπου 220 ohms.

Διάγραμμα καλωδίωσης για βομβητή και LED στο Arduino
Διάγραμμα καλωδίωσης για βομβητή και LED στο Arduino

Βήμα 2

Ας γράψουμε ένα σκίτσο σαν αυτό και ανεβάστε το στο Arduino.

Αφού φορτώσετε την πλακέτα, μπορείτε να δείτε ότι το σκίτσο δεν εκτελείται ακριβώς όπως το χρειαζόμαστε: έως ότου η σειρήνα τεθεί σε πλήρη λειτουργία, η λυχνία LED δεν θα αναβοσβήνει και θα θέλαμε να αναβοσβήνει η λυχνία LED ΚΑΤΑ ΤΗ διάρκεια της σειρήνας. Ποιο είναι το πρόβλημα εδώ;

Το γεγονός είναι ότι αυτό το πρόβλημα δεν μπορεί να λυθεί με τον συνηθισμένο τρόπο. Οι εργασίες εκτελούνται από τον μικροελεγκτή αυστηρά διαδοχικά. Ο χειριστής "καθυστέρηση ()" καθυστερεί την εκτέλεση του προγράμματος για ένα καθορισμένο χρονικό διάστημα και έως ότου λήξει αυτή η ώρα, οι ακόλουθες εντολές προγράμματος δεν θα εκτελεστούν. Εξαιτίας αυτού, δεν μπορούμε να ορίσουμε διαφορετική διάρκεια εκτέλεσης για κάθε εργασία στο "loop ()" του προγράμματος.

Επομένως, πρέπει να προσομοιώσετε κατά κάποιο τρόπο το multitasking.

Έλεγχος Beeper και LED σε σειρά
Έλεγχος Beeper και LED σε σειρά

Βήμα 3

Η επιλογή με την οποία το Arduino θα εκτελεί εργασίες σε ψευδο-παράλληλο προτείνεται από τους προγραμματιστές του Arduino στο άρθρο

Η ουσία της μεθόδου είναι ότι με κάθε επανάληψη του βρόχου "loop ()", ελέγχουμε αν είναι καιρός να αναβοσβήνει η λυχνία LED (για να εκτελέσετε μια εργασία φόντου) ή όχι. Και αν συμβαίνει αυτό, τότε αντιστρέφουμε την κατάσταση των LED. Αυτό είναι ένα είδος παράκαμψης του τελεστή "delay ()".

Ένα σημαντικό μειονέκτημα αυτής της μεθόδου είναι ότι το τμήμα κώδικα μπροστά από τη μονάδα ελέγχου LED πρέπει να εκτελεστεί γρηγορότερα από το χρονικό διάστημα που αναβοσβήνει του LED "ledInterval". Διαφορετικά, η αναλαμπή θα συμβεί λιγότερο συχνά από ό, τι είναι απαραίτητο και δεν θα έχουμε το αποτέλεσμα της παράλληλης εκτέλεσης εργασιών. Συγκεκριμένα, στο σκίτσο μας, η διάρκεια της αλλαγής ήχου σειρήνας είναι 200 + 200 + 200 + 200 = 800 msec και ορίζουμε το διάστημα αναβοσβήματος LED στα 200 msec. Αλλά το LED θα αναβοσβήνει με μια περίοδο 800 msec, η οποία είναι 4 φορές διαφορετική από αυτήν που ορίζουμε. Σε γενικές γραμμές, εάν ο χειριστής "delay ()" χρησιμοποιείται στον κώδικα, τότε είναι δύσκολο να προσομοιωθεί ο ψευδο-παραλληλισμός, επομένως συνιστάται να το αποφύγετε.

Σε αυτήν την περίπτωση, θα ήταν απαραίτητο για τη μονάδα ελέγχου ήχου σειρήνας να ελέγξει επίσης αν έχει έρθει η ώρα ή όχι, και να μην χρησιμοποιήσει το "delay ()". Αλλά αυτό θα αύξανε την ποσότητα του κώδικα και θα επιδεινώσει την αναγνωσιμότητα του προγράμματος.

Ο χειριστής αναβοσβήνει χωρίς καθυστέρηση ()
Ο χειριστής αναβοσβήνει χωρίς καθυστέρηση ()

Βήμα 4

Για να λύσουμε αυτό το πρόβλημα, θα χρησιμοποιήσουμε την υπέροχη βιβλιοθήκη ArduinoThread, η οποία σας επιτρέπει να δημιουργείτε εύκολα ψευδο-παράλληλες διαδικασίες. Λειτουργεί με παρόμοιο τρόπο, αλλά σας επιτρέπει να μην γράφετε κώδικα για να ελέγξετε την ώρα - αν πρέπει να εκτελέσετε την εργασία σε αυτόν τον βρόχο ή όχι. Αυτό μειώνει την ποσότητα του κώδικα και βελτιώνει την αναγνωσιμότητα του σκίτσου. Ας δούμε τη βιβλιοθήκη σε δράση.

Πρώτα απ 'όλα, κατεβάστε το αρχείο της βιβλιοθήκης από τον επίσημο ιστότοπο https://github.com/ivanseidel/ArduinoThread/archive/master.zip και αποσυμπιέστε το στον κατάλογο "βιβλιοθήκες" του Arduino IDE. Στη συνέχεια, μετονομάστε το φάκελο "ArduinoThread-master" σε "ArduinoThread".

Εγκατάσταση της βιβλιοθήκης ArduinoThread
Εγκατάσταση της βιβλιοθήκης ArduinoThread

Βήμα 5

Το διάγραμμα σύνδεσης θα παραμείνει το ίδιο. Μόνο ο κωδικός προγράμματος θα αλλάξει. Τώρα θα είναι το ίδιο με το sidebar.

Στο πρόγραμμα, δημιουργούμε δύο ροές, η καθεμία εκτελεί τη δική της λειτουργία: η μία αναβοσβήνει με LED, η δεύτερη ελέγχει τον ήχο της σειρήνας. Σε κάθε επανάληψη του βρόχου, για κάθε νήμα, ελέγχουμε αν έχει έρθει η ώρα για την εκτέλεση του ή όχι. Εάν φτάσει, ξεκινά για εκτέλεση χρησιμοποιώντας τη μέθοδο "run ()". Το κύριο πράγμα δεν είναι να χρησιμοποιήσετε τον τελεστή "delay ()".

Πιο αναλυτικές εξηγήσεις δίνονται στον κώδικα.

Ας φορτώσουμε τον κώδικα στη μνήμη Arduino, τρέξτε τον. Τώρα όλα λειτουργούν ακριβώς όπως πρέπει!

Συνιστάται: