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

Πηγαίνοντας πέρα από StandardFirmata - Επανάληψη: 5 βήματα
Πηγαίνοντας πέρα από StandardFirmata - Επανάληψη: 5 βήματα

Βίντεο: Πηγαίνοντας πέρα από StandardFirmata - Επανάληψη: 5 βήματα

Βίντεο: Πηγαίνοντας πέρα από StandardFirmata - Επανάληψη: 5 βήματα
Βίντεο: Το πλήρες επόμενο μάθημα js - Μάθετε Nextjs σε 2 ώρες! | React SSR + timecodes 2024, Ιούλιος
Anonim
Going Beyond StandardFirmata - Επανεξετάστηκε
Going Beyond StandardFirmata - Επανεξετάστηκε

Πριν από λίγο, επικοινώνησα με τον Δρ Martyn Wheeler, χρήστης του pymata4, για καθοδήγηση στην προσθήκη υποστήριξης για τον αισθητήρα υγρασίας/θερμοκρασίας DHT22 στη βιβλιοθήκη pymata4. Η βιβλιοθήκη pymata4, σε συνδυασμό με το αντίστοιχο Arduino, FirmataExpress, επιτρέπει στους χρήστες να ελέγχουν και να παρακολουθούν τις συσκευές τους Arduino από απόσταση. Μέσα σε λίγους γύρους ανταλλαγών email, ο Δρ Wheeler ήταν επιτυχής στην τροποποίηση τόσο του pymata4 όσο και του FirmataExpress. Ως αποτέλεσμα, η υποστήριξη για τους αισθητήρες DHT22 και DHT11 αποτελεί πλέον ένα τυπικό μέρος των pymata4 και FirmataExpress.

Τον Μάιο του 2014, έγραψα ένα άρθρο για την προσθήκη υποστήριξης στο Firmata για επιπλέον συσκευές. Αναλογιζόμενος αυτό το άρθρο μου, συνειδητοποίησα πόσο πολύ έχει αλλάξει από τότε που έγραψα το χαρτί για αυτό το άρθρο. Εκτός από αυτό το άρθρο, ο Δρ Wheeler τεκμηρίωσε τις προσπάθειές του και ίσως θελήσετε να το ελέγξετε και αυτό.

Το FirmataExpress βασίζεται στο StandardFirmata και η δομή καταλόγου StandardFirmata έχει εξελιχθεί. Επιπλέον, το pymata4 API είναι επίσης αρκετά διαφορετικό από το αρχικό PyMata API του 2014. Νόμιζα ότι αυτή θα ήταν η τέλεια στιγμή για επανεξέταση και ενημέρωση αυτού του άρθρου. Χρησιμοποιώντας τη δουλειά του Δρ Wheeler ως βάση, ας διερευνήσουμε πώς να επεκτείνουμε τη λειτουργικότητα του pymata4/FirmataExpress.

Πριν ξεκινήσουμε - Μερικές πληροφορίες για το Arduino/Firmata

Τι είναι λοιπόν το Firmata; Απόσπασμα από την ιστοσελίδα της Firmata, "Το Firmata είναι ένα γενικό πρωτόκολλο επικοινωνίας με μικροελεγκτές από λογισμικό σε έναν κεντρικό υπολογιστή."

Το Arduino Firmata χρησιμοποιεί μια σειριακή διεπαφή για τη μεταφορά πληροφοριών εντολών και αναφορών μεταξύ ενός μικροελεγκτή Arduino και ενός υπολογιστή, συνήθως χρησιμοποιώντας μια σειριακή σύνδεση/σύνδεση USB που έχει οριστεί σε 57600 bps. Τα δεδομένα που μεταφέρονται σε αυτόν τον σύνδεσμο είναι δυαδικά και το πρωτόκολλο υλοποιείται σε μοντέλο πελάτη/διακομιστή.

Η πλευρά του διακομιστή μεταφορτώνεται σε έναν μικροελεγκτή Arduino με τη μορφή ενός σκίτσου Arduino. Το σκίτσο StandardFirmata, που περιλαμβάνεται στο Arduino IDE, ελέγχει τις καρφίτσες εισόδου/εξόδου Arduino, σύμφωνα με τις εντολές του πελάτη. Αναφέρει επίσης αλλαγές καρφιτσών εισόδου και άλλες πληροφορίες αναφοράς πίσω στον πελάτη. Το FirmataExpress είναι μια εκτεταμένη έκδοση του StandardFirmata. Λειτουργεί με σειριακή ταχύτητα σύνδεσης 115200 bps.

Ο πελάτης Arduino που χρησιμοποιείται για αυτό το άρθρο είναι το pymata4. Είναι μια εφαρμογή Python που εκτελείται σε υπολογιστή. Και στέλνει εντολές και λαμβάνει αναφορές από τον διακομιστή Arduino. Επειδή το pymata4 υλοποιείται σε Python, τρέχει σε υπολογιστές Windows, Linux (συμπεριλαμβανομένου του Raspberry Pi) και υπολογιστές macOS.

Γιατί να χρησιμοποιήσετε το Firmata;

Οι μικροελεγκτές Arduino είναι υπέροχες μικρές συσκευές, αλλά οι πόροι επεξεργαστή και μνήμης είναι κάπως περιορισμένοι. Για εφαρμογές που απαιτούν επεξεργαστή ή μνήμη, υπάρχει συχνά μικρή επιλογή από το να εκφορτώσετε τη ζήτηση πόρων σε έναν υπολογιστή για να είναι επιτυχής η εφαρμογή.

Αλλά αυτός δεν είναι ο μόνος λόγος για τη χρήση του StandardFirmata. Κατά την ανάπτυξη ελαφρύτερων εφαρμογών Arduino, ένας υπολογιστής μπορεί να παρέχει εργαλεία και δυνατότητες εντοπισμού σφαλμάτων που δεν είναι άμεσα διαθέσιμα σε μικροελεγκτή Arduino. Η χρήση ενός "σταθερού" προγράμματος -πελάτη και διακομιστή συμβάλλει στον περιορισμό της πολυπλοκότητας της εφαρμογής σε έναν υπολογιστή, ο οποίος διαχειρίζεται πιο εύκολα. Μόλις τελειοποιηθεί η εφαρμογή, μπορεί να μεταφραστεί σε ένα προσαρμοσμένο, αυτόνομο σκίτσο Arduino.

Γιατί να χρησιμοποιήσω το pymata4;

Όντας ο συγγραφέας του, φυσικά, είμαι προκατειλημμένος. Τούτου λεχθέντος, είναι ο μόνος πελάτης Firmata με έδρα την Python που διατηρείται συνεχώς τα τελευταία χρόνια. Παρέχει ένα διαισθητικό και εύκολο στη χρήση API. Εκτός από τα σκίτσα που βασίζονται σε StandardFirmata, υποστηρίζει Firmata μέσω WiFi για συσκευές όπως το ESP-8266 όταν χρησιμοποιείτε το σκίτσο StandardFirmataWifI.

Επίσης, το pymata4 σχεδιάστηκε για να επεκτείνεται εύκολα από έναν χρήστη για να υποστηρίζει επιπλέον αισθητήρες και ενεργοποιητές που δεν υποστηρίζονται επί του παρόντος από το StandardFirmata.

Βήμα 1: Κατανόηση του πρωτοκόλλου Firmata

Κατανόηση του πρωτοκόλλου Firmata
Κατανόηση του πρωτοκόλλου Firmata

Το πρωτόκολλο επικοινωνίας Arduino Firmata προέρχεται από το πρωτόκολλο MIDI, το οποίο χρησιμοποιεί ένα ή περισσότερα bytes 7 bit για την αναπαράσταση δεδομένων.

Το Firmata σχεδιάστηκε για να είναι επεκτάσιμο από το χρήστη. Ο μηχανισμός που παρέχει αυτήν την επεκτασιμότητα είναι το πρωτόκολλο ανταλλαγής μηνυμάτων System Exclusive (SysEx).

Η μορφή ενός μηνύματος SysEx, όπως ορίζεται από το πρωτόκολλο Firmata, εμφανίζεται στην παραπάνω εικόνα. Ξεκινά με ένα byte START_SYSEX με σταθερή τιμή δεκαεξαδικό 0xF0 και ακολουθείται από ένα μοναδικό byte εντολής SysEx. Η τιμή του byte εντολής πρέπει να είναι στην περιοχή του δεκαεξαδικού 0x00-0x7F. Στη συνέχεια, το byte εντολής ακολουθείται από έναν απροσδιόριστο αριθμό byte δεδομένων 7 bit. Τέλος, το μήνυμα τερματίζεται με ένα byte END_SYSEX, με σταθερή τιμή δεκαεξαδικό 0xF7.

Κωδικοποίηση/αποκωδικοποίηση δεδομένων Firmata

Δεδομένου ότι το τμήμα δεδομένων χρήστη ενός μηνύματος SysEx αποτελείται από μια σειρά 7 byte, μπορείτε να αναρωτηθείτε πώς αντιπροσωπεύει το ένα τιμή μεγαλύτερη από 128 (0x7f); Το Firmata κωδικοποιεί αυτές τις τιμές αποσυναρμολογώντας τις σε πολλαπλά κομμάτια 7-bit byte προτού τα δεδομένα μεταφερθούν στο σύνδεσμο δεδομένων. Το λιγότερο σημαντικό byte (LSB) ενός στοιχείου δεδομένων αποστέλλεται πρώτα, ακολουθούμενο από όλο και πιο σημαντικά στοιχεία του στοιχείου δεδομένων κατά σύμβαση. Το πιο σημαντικό byte (MSB) του στοιχείου δεδομένων είναι το τελευταίο στοιχείο δεδομένων που στάλθηκε.

Πως λειτουργεί αυτό?

Ας υποθέσουμε ότι επιθυμούμε να ενσωματώσουμε μια τιμή 525 στο τμήμα δεδομένων ενός μηνύματος SysEx. Δεδομένου ότι μια τιμή 525 είναι σαφώς μεγαλύτερη από μια τιμή 128, πρέπει να τη χωρίσουμε ή να την αποσυναρμολογήσουμε σε "κομμάτια" 7-bit byte.

Εδώ είναι πώς γίνεται αυτό.

Η τιμή 525 σε δεκαδικό ισοδυναμεί με την δεκαεξαδική τιμή 0x20D, μια τιμή 2 byte. Για να λάβουμε το LSB, καλύπτουμε την τιμή ΚΑΙ το κάνουμε με 0x7F. Και οι δύο εφαρμογές "C" και Python εμφανίζονται παρακάτω:

// Υλοποίηση "C" για απομόνωση του LSB

int max_distance_LSB = max_distance & 0x7f; // μάσκα του χαμηλότερου byte # Υλοποίηση Python για απομόνωση LSB max_distance_LSB = max_distance & 0x7F # κάλυψη του χαμηλότερου byte

Μετά την κάλυψη, το max_distance_LSB θα περιέχει 0x0d. 0x20D & 0x7F = 0x0D.

Στη συνέχεια, πρέπει να απομονώσουμε το MSB για αυτήν την τιμή των 2 byte. Για να γίνει αυτό, θα μετακινήσουμε την τιμή 0x20D προς τα δεξιά, 7 θέσεις.

// Υλοποίηση "C" για απομόνωση MSB αξίας 2 byte

int max_distance_MSB = max_distance >> 7; // μετατόπιση υψηλής τάξης byte # Python υλοποίηση σε ισοβολία MSB 2 byte τιμή max_distance_MSB = max_distance >> 7 # shift για να αποκτήσετε το ανώτερο byte Μετά τη μετατόπιση, η max_distance_MSB θα περιέχει μια τιμή 0x04.

Όταν ληφθούν τα "χονδροποιημένα" δεδομένα που πρέπει να συγκεντρωθούν, πρέπει να επανασυναρμολογηθούν σε μια ενιαία τιμή. Ακολουθεί ο τρόπος ανασυγκρότησης των δεδομένων τόσο στο "C" όσο και στην Python

// Υλοποίηση "C" για επανασυναρμολόγηση του 2 byte, // Τιμές 7 bit σε μία μόνο τιμή int max_distance = argv [0] + (argv [1] << 7); Υλοποίηση # Python για επανασυναρμολόγηση των τιμών των 2 byte, # 7 bit σε μία τιμή max_distance = δεδομένα [0] + (δεδομένα [1] << 7)

Μετά την επανασυναρμολόγηση, η τιμή ισούται και πάλι με 525 δεκαδικά ή 0x20D δεκαεξαδικά.

Αυτή η διαδικασία αποσυναρμολόγησης/επανασυναρμολόγησης μπορεί να πραγματοποιηθεί είτε από τον πελάτη είτε από τον διακομιστή.

Βήμα 2: Ας ξεκινήσουμε

Η υποστήριξη μιας νέας συσκευής απαιτεί αλλαγές τόσο στον διακομιστή Arduino, όσο και στον υπολογιστή -πελάτη Python. Το έργο του Δρ Wheeler θα χρησιμοποιηθεί για να απεικονίσει τις απαραίτητες τροποποιήσεις.

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

Για την υποστήριξη συσκευών DHT, ο Δρ Wheeler βασίζει τον κωδικό επέκτασής του στη βιβλιοθήκη DHTNew. Πολύ έξυπνα, ο Δρ Wheeler χώρισε τη λειτουργικότητα της βιβλιοθήκης DHTNew στις πλευρές Arduino και pymata4 της εξίσωσης για να παρέχει ελάχιστο μπλοκάρισμα στην πλευρά του Arduino.

Αν κοιτάξουμε το DHTNew, εκτελεί όλα τα ακόλουθα:

  • Ρυθμίζει την επιλεγμένη λειτουργία ψηφιακής εξόδου pin.
  • Ρυθμίζει ένα κωδικοποιημένο σήμα για να ανακτήσει τις πιο πρόσφατες τιμές υγρασίας και θερμοκρασίας.
  • Ελέγχει και αναφέρει τυχόν σφάλματα.
  • Υπολογίζει τις τιμές της θερμοκρασίας και της υγρασίας που είναι αναγνώσιμες από τον άνθρωπο από τα ανεπεξέργαστα δεδομένα που ανακτήθηκαν.

Για να διατηρηθούν τα πράγματα όσο το δυνατόν πιο αποτελεσματικά από την πλευρά του FirmataExpress, ο Δρ Wheeler κατέβασε τις ρουτίνες μετατροπής δεδομένων από το Arduino σε pymata4.

Βήμα 3: Τροποποίηση FirmataExpress για υποστήριξη DHT

Το δέντρο καταλόγου FirmataExpress

Παρακάτω είναι όλα τα αρχεία που περιλαμβάνουν το αποθετήριο FirmataExpress. Αυτό το δέντρο είναι πανομοιότυπο με αυτό του StandardFiramata, μόνο που μερικά από τα ονόματα αρχείων αντανακλούν το όνομα του αποθετηρίου.

Τα αρχεία που χρειάζονται τροποποίηση είναι αυτά που έχουν έναν αστερίσκο (*) δίπλα τους.

FirmataExpress

Bo * Πίνακες.η

├── παραδείγματα

Irm └── FirmataExpress

├── ├── boardx

├── * FirmataExpress.ino

├── ├── ΑΔΕΙΑ.txt

Makefile

* FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Ας δούμε καθένα από τα αρχεία και τις αλλαγές που έγιναν.

Πίνακες.η

Αυτό το αρχείο περιέχει ορισμούς μακροεντολών τύπου pin για κάθε έναν από τους υποστηριζόμενους τύπους πλακέτας. Ορίζει τον μέγιστο αριθμό συσκευών που υποστηρίζονται όταν πρέπει να υποστηρίζονται περισσότερες από μία συσκευές.

Για τη συσκευή DHT, μπορεί να συνδεθούν έως 6 συσκευές τη φορά και αυτή η τιμή ορίζεται ως:

#ifndef MAX_DHTS

#define MAX_DHTS 6 #endif

Επίσης, οι μακροεντολές τύπου pin μπορεί να ορίζονται προαιρετικά για τη νέα συσκευή, είτε για όλους τους τύπους πλακέτας είτε μόνο για αυτούς που σας ενδιαφέρουν. Αυτές οι μακροεντολές χρησιμοποιούνται κυρίως για σκοπούς αναφοράς και δεν χρησιμοποιούνται για τον έλεγχο των συσκευών. Αυτές οι μακροεντολές ορίζουν και τις δύο ακίδες που υποστηρίζουν τη συσκευή:

#define IS_PIN_DHT (p) (IS_PIN_DIGITAL (p) && (p) - 2 <MAX_DHTS)

Καθώς και μια μακροεντολή για να ορίσετε μια μετατροπή αριθμού PIN.

#define PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataConstants.h

Αυτό το αρχείο περιέχει τον αριθμό έκδοσης υλικολογισμικού, τον οποίο μπορείτε να τροποποιήσετε για να παρακολουθείτε ποια έκδοση έχετε φορτώσει στο Arduino σας. Περιέχει επίσης τις τιμές μηνυμάτων Firmata, συμπεριλαμβανομένων των μηνυμάτων Firmata SysEx.

Θα χρειαστεί να εκχωρήσετε ένα νέο μήνυμα ή ένα σύνολο μηνυμάτων για τη συσκευή σας σε αυτό το αρχείο. Για το DHT, προστέθηκαν δύο μηνύματα. Το ένα διαμορφώνει ένα pin ως "DHT" pin και το άλλο, ως μήνυμα δημοσιογράφου, όταν στέλνει τα τελευταία δεδομένα DHT πίσω στον πελάτη.

στατικό const int DHT_CONFIG = 0x64;

στατικό const int DHT_DATA = 0x65;

Οι λειτουργίες καρφιτσών καθορίζονται επίσης σε αυτό το αρχείο. Για το DHT, δημιουργήθηκε μια νέα λειτουργία pin:

στατικό const int PIN_MODE_DHT = 0x0F; // pin έχει ρυθμιστεί για DHT

Κατά την προσθήκη μιας νέας λειτουργίας καρφίτσας, το TOTAL_PIN_MODES πρέπει να προσαρμοστεί:

στατικό const int TOTAL_PIN_MODES = 17;

FirmataDefines.h

Αυτό το αρχείο πρέπει να ενημερωθεί ώστε να αντικατοπτρίζει τα νέα μηνύματα που προστίθενται στο FirmataConstants.h:

#ifdef DHT_CONFIG # αδιευκρ DHT_CONFIG #endif #define DHT_CONFIG firmata:: DHT_CONFIG // αίτημα DHT #ifdef DHT_DATA #undef DHT_DATA #endif #define DHT_DATA firmata:: DHT_DATA // DHT απαντήσει #ifdef PIN_MODE_DHT #undef PIN_MODE_DHT #endif #define PIN_MODE_DHT firmata:: PIN_MODE_DHT

FirmataExpress.ino

Σε αυτήν τη συζήτηση, θα καλύψουμε τα «υψηλά σημεία» των αλλαγών που έγιναν σε αυτό το σκίτσο του Arduino.

Προκειμένου το FirmataExpress να υποστηρίζει έως και έξι συσκευές DHT ταυτόχρονα, δημιουργήθηκαν 3 συστοιχίες για να παρακολουθούν κάθε έναν από τους συσχετισμένους αριθμούς PIN της συσκευής, την τιμή WakeUpDelay και τον τύπο συσκευής, δηλαδή DHT22 ή DHT11:

// Αισθητήρες DHT

int numActiveDHTs = 0; // αριθμός DHT συνημμένων uint8_t DHT_PinNumbers [MAX_DHTS]. uint8_t DHT_WakeUpDelay [MAX_DHTS]; uint8_t DHT_TYPE [MAX_DHTS];

Επειδή και οι δύο τύποι συσκευών απαιτούν περίπου 2 δευτερόλεπτα μεταξύ της ανάγνωσης, πρέπει να βεβαιωθούμε ότι διαβάζουμε κάθε DHT μόνο μία φορά στο χρονικό πλαίσιο των 2 δευτερολέπτων. Ορισμένες συσκευές, όπως οι συσκευές DHT και οι αισθητήρες απόστασης HC-SR04, έχουν πρόσβαση μόνο περιοδικά. Αυτό τους δίνει το χρόνο να αλληλεπιδρούν με το περιβάλλον τους.

uint8_t επόμενοDHT = 0; // ευρετηρίαση σε dht για την επόμενη συσκευή που θα διαβαστεί

uint8_t currentDHT = 0; // Παρακολουθεί ποιος αισθητήρας είναι ενεργός. int dhtNumLoops = 0; // Στόχος πολλές φορές μέσω του βρόχου b4 πρόσβαση σε DHT int dhtLoopCounter = 0; // Μετρητής βρόχου

Διαμόρφωση και ανάγνωση της συσκευής DHT

Όταν το FirmataExpress λαμβάνει μια εντολή SysEx για να διαμορφώσει μια καρφίτσα για λειτουργία DHT, επαληθεύει ότι δεν έχει γίνει υπέρβαση του μέγιστου αριθμού συσκευών DHT. Εάν το νέο DHT μπορεί να υποστηριχθεί, οι συστοιχίες DHT ενημερώνονται. Εάν ο τύπος DHT είναι άγνωστος, δημιουργείται ένα μήνυμα συμβολοσειράς SysEx και μεταδίδεται πίσω στο pymata4

θήκη DHT_CONFIG: int DHT_Pin = argv [0]; int DHT_type = argv [1]; if (numActiveDHTs <MAX_DHTS) {if (DHT_type == 22) {DHT_WakeUpDelay [numActiveDHTs] = 1; } else if (DHT_type == 11) {DHT_WakeUpDelay [numActiveDHTs] = 18; } else {Firmata.sendString ("ΣΦΑΛΜΑ: ΑΓΝΩΣΤΟΣ ΤΥΠΟΣ ΑΙΣΘΗΤΗΡΑ, ΕΓΚΥΡΙΟΙ ΑΙΣΘΗΤΗΡΙΕΣ ΕΙΝΑΙ 11, 22"); Διακοπή; } // δοκιμάστε τον αισθητήρα DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = DHT_type; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

Στη συνέχεια, το FirmataExpress επιχειρεί να επικοινωνήσει με τη συσκευή DHT. Εάν υπάρχουν σφάλματα, σχηματίζει ένα μήνυμα SysEx με τα δεδομένα σφάλματος και στέλνει το μήνυμα SysEx πίσω στο pymat4. Η μεταβλητή _bits κρατά τα δεδομένα που επιστρέφονται από τη συσκευή DHT για πρόσθετη επεξεργασία από το pymata4, εάν είναι επιθυμητό.

Firmata.write (START_SYSEX);

Firmata.write (DHT_DATA); Firmata.write (DHT_Pin); Firmata.write (DHT_type); για (uint8_t i = 0; i> 7 & 0x7f); } Firmata.write (abs (rv)); Firmata.write (1); Firmata.write (END_SYSEX);

Εάν επιστρέψουν έγκυρα δεδομένα, ο αριθμός των ενεργών DHT αυξάνεται. Προσαρμόζεται επίσης μια μεταβλητή που παρακολουθεί πόσες επαναλήψεις βρόχου πρέπει να ολοκληρωθούν πριν από τον έλεγχο της επόμενης DHT για δεδομένα. Αυτή η μεταβλητή διασφαλίζει ότι ανεξάρτητα από το πόσα DHT προστίθενται στο σύστημα, όλα θα διαβαστούν μέσα σε περίοδο 2 δευτερολέπτων.

int rv = readDhtSensor (numActiveDHTs);

if (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHTs; // όλα καλά}

Εάν μία ή περισσότερες συσκευές DHT έχουν ρυθμιστεί στη λειτουργία βρόχου του σκίτσου, τότε διαβάζεται η επόμενη συσκευή DHT. Είτε τα έγκυρα δεδομένα είτε η κατάσταση σφάλματος επιστρέφονται στο pymata4 με τη μορφή μηνύματος SysEx:

if (dhtLoopCounter ++> dhtNumLoops) {if (numActiveDHTs) {int rv = readDhtSensor (nextDHT); uint8_t current_pin = DHT_PinNumbers [nextDHT]; uint8_t current_type = DHT_TYPE [nextDHT]; dhtLoopCounter = 0; currentDHT = nextDHT; if (nextDHT ++> = numActiveDHTs - 1) {nextDHT = 0; } if (rv == DHTLIB_OK) {// TEST CHECKSUM uint8_t sum = _bits [0] + _bits [1] + _bits [2] + _bits [3]; εάν (_bits [4]! = άθροισμα) {rv = -1; }} // στείλτε το μήνυμα πίσω με κατάσταση σφάλματος Firmata.write (START_SYSEX); Firmata.write (DHT_DATA); Firmata.write (current_pin); Firmata.write (current_type); για (uint8_t i = 0; i <sizeof (_bits) - 1; ++ i) {Firmata.write (_bits ); // Firmata.write (_bits ;} Firmata.write (abs (rv)); Firmata.write (0); Firmata.write (END_SYSEX);}}

Ο κωδικός που χρησιμοποιείται για την επικοινωνία με τη συσκευή DHT προέρχεται απευθείας από τη βιβλιοθήκη DHTNew:

int readDhtSensor (int index) {

// INIT BUFFERVAR ΓΙΑ ΛΗΗ ΔΕΔΟΜΕΝΩΝ uint8_t mask = 128; uint8_t idx = 0; // ΚΕΝΟ ΜΠΑΦΕΡ // memset (_bits, 0, sizeof (_bits)); για (uint8_t i = 0; i 5 BYTES για (uint8_t i = 40; i! = 0; i--) {loopCnt = DHTLIB_TIMEOUT; while (digitalRead (pin) == LOW) {if (--loopCnt == 0) επιστροφή DHTLIB_ERROR_TIMEOUT;} uint32_t t = micros (); loopCnt = DHTLIB_TIMEOUT; while (digitalRead (pin) == HIGH) {if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;} if ((micros ()-t) 40) {_bits [idx] | = mask;} mask >> = 1; if (mask == 0) // next byte? {Mask = 128; idx ++;}} return DHTLIB_OK;}

Βήμα 4: Τροποποίηση του Pymata4 για υποστήριξη DHT

private_constants.h

Για να υποστηρίξουμε το DHT, πρέπει να προσθέσουμε και τα νέα μηνύματα τύπου pin και SysEx σε αυτό το αρχείο:

# pin τρόποι ΕΙΣΟΔΟΣ = 0x00 # καρφίτσα ορίζεται ως είσοδος 0x06 # pin περιλαμβάνεται στη ρύθμιση I2C STEPPER = 0x08 # οποιαδήποτε καρφίτσα στη λειτουργία stepper SERIAL = 0x0a PULLUP = 0x0b # Οποιαδήποτε καρφίτσα σε λειτουργία pullup SONAR = 0x0c # Οποιαδήποτε καρφίτσα στη λειτουργία SONAR TONE = 0x0d # Οποιαδήποτε καρφίτσα σε λειτουργία τόνου PIXY = 0x0e # προορίζεται για λειτουργία pixy camera DHT = 0x0f # DHT sensor IGNORE = 0x7f # DHT SysEx μηνύματα εντολών DHT_CONFIG = 0x64 # dht εντολή διαμόρφωσης DHT_DATA = 0x65 # dht απάντηση αισθητήρα

Ο προστιθέμενος τύπος pin και οι εντολές SysEx πρέπει να ταιριάζουν με τις τιμές στο FirmataConstants.h που προστέθηκε στο FirmataExpress.

pymata4.py

Το Pymata4 χρησιμοποιεί ένα λεξικό Python για να συσχετίσει γρήγορα ένα εισερχόμενο μήνυμα Firmata με έναν χειριστή μηνυμάτων. Το όνομα αυτού του λεξικού είναι report_dispatch.

Η μορφή για μια καταχώριση λεξικού είναι:

{MessageID: [message_handler, αριθμός δεδομένων byte προς επεξεργασία]}

Προστέθηκε μια καταχώριση στο λεξικό για τον χειρισμό εισερχόμενων μηνυμάτων DHT:

{PrivateConstants. DHT_DATA: [self._dht_read_response, 7]}

Τα 7 byte δεδομένων στο μήνυμα είναι ο ψηφιακός αριθμός Arduino, ο τύπος της συσκευής DHT (22 ή 11) και τα 5 byte ακατέργαστων δεδομένων.

Η μέθοδος _dht_read_response ελέγχει για τυχόν αναφερόμενα σφάλματα. Εάν δεν υπάρχουν αναφερόμενα σφάλματα, η υγρασία και η θερμοκρασία υπολογίζονται χρησιμοποιώντας τον αλγόριθμο που μεταφέρεται από τη βιβλιοθήκη Arduino DHTNew.

Οι υπολογισμένες τιμές αναφέρονται μέσω μιας μεθόδου επανάκλησης που παρέχεται από τον χρήστη. Είναι επίσης αποθηκευμένα στην εσωτερική δομή δεδομένων pin_data. Η τελευταία αναφερόμενη τιμή μπορεί να ανακληθεί με τη δημοσκόπηση pin_data χρησιμοποιώντας τη μέθοδο dht_read.

Διαμόρφωση νέας συσκευής DHT

Όταν προσθέτετε μια νέα συσκευή DHT, καλείται η μέθοδος set_pin_mode_dht. Αυτή η μέθοδος ενημερώνει τα pin_data για ψηφιακές ακίδες. Δημιουργεί και στέλνει επίσης ένα μήνυμα DHT_CONFIG SysEx στο FirmataExpress.

Βήμα 5: Αναδίπλωση

Όπως είδαμε, η προσθήκη υποστήριξης Firmata για μια νέα συσκευή απαιτεί να τροποποιήσετε τον κώδικα διακομιστή Arduino FirmataExpress και τον κωδικό πελάτη pymata4 που βασίζεται σε Python. Ο κώδικας FirmataExpress μπορεί να είναι δύσκολο να διορθωθεί. Μια μέθοδος που ονομάζεται printData προστέθηκε στο FirmataExpress για να βοηθήσει στον εντοπισμό σφαλμάτων. Αυτή η μέθοδος σάς επιτρέπει να στείλετε τιμές δεδομένων από το FirmataExpress και θα τις εκτυπώσετε στην κονσόλα pymata4.

Αυτή η συνάρτηση απαιτεί τόσο έναν δείκτη σε μια συμβολοσειρά χαρακτήρων όσο και την τιμή που θέλετε να προβάλετε. Εάν η τιμή δεδομένων περιέχεται σε μια μεταβλητή που ονομάζεται argc, μπορείτε να καλέσετε το printData με τις ακόλουθες παραμέτρους.

printData ((char*) "argc =", argc);

Εάν έχετε οποιεσδήποτε ερωτήσεις, αφήστε ένα σχόλιο και θα χαρώ να απαντήσω.

Καλή κωδικοποίηση!

Συνιστάται: