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

Arduino και PCF8591 ADC DAC IC: 7 Βήματα
Arduino και PCF8591 ADC DAC IC: 7 Βήματα

Βίντεο: Arduino και PCF8591 ADC DAC IC: 7 Βήματα

Βίντεο: Arduino και PCF8591 ADC DAC IC: 7 Βήματα
Βίντεο: How to Interface PCF8591 ADC/DAC Module with Arduino 2024, Ιούλιος
Anonim
Arduino και PCF8591 ADC DAC IC
Arduino και PCF8591 ADC DAC IC

Θέλατε ποτέ περισσότερες αναλογικές ακίδες εισόδου στο έργο σας Arduino, αλλά δεν θέλατε να βγείτε για ένα Mega; Or θα θέλατε να δημιουργήσετε αναλογικά σήματα; Στη συνέχεια, ελέγξτε το θέμα του σεμιναρίου μας - το IC NXP PCF8591.

Επιλύει και τα δύο αυτά προβλήματα καθώς διαθέτει έναν μόνο μετατροπέα DAC (ψηφιακό σε αναλογικό) καθώς και τέσσερις ADC (μετατροπείς αναλογικών σε ψηφιακούς) - όλα προσβάσιμα μέσω του διαύλου I2C. Το PCF8591 διατίθεται σε μορφή DIP, επιτοίχιας τοποθέτησης και μονάδας, γεγονός που καθιστά εύκολο τον πειραματισμό.

Πριν προχωρήσετε, κάντε λήψη του φύλλου δεδομένων. Το PCF8591 μπορεί να λειτουργήσει τόσο στα 5V όσο και στα 3.3V, οπότε αν χρησιμοποιείτε Arduino Due, Raspberry Pi ή άλλη πλακέτα ανάπτυξης 3.3 V είστε καλά. Τώρα θα εξηγήσουμε πρώτα το DAC και μετά το ADC.

Βήμα 1: Χρήση του DAC (μετατροπέας ψηφιακού σε αναλογικό)

Χρήση του DAC (ψηφιακός σε αναλογικός μετατροπέας)
Χρήση του DAC (ψηφιακός σε αναλογικός μετατροπέας)

Το DAC στο PCF8591 έχει ανάλυση 8-bit-έτσι μπορεί να δημιουργήσει ένα θεωρητικό σήμα μεταξύ μηδενικών βολτ και της τάσης αναφοράς (Vref) σε 255 βήματα. Για σκοπούς επίδειξης θα χρησιμοποιήσουμε Vref 5V και μπορείτε να χρησιμοποιήσετε χαμηλότερο Vref όπως 3.3V ή όποια θέλετε να είναι η μέγιστη τιμή … ωστόσο πρέπει να είναι μικρότερη από την τάση τροφοδοσίας.

Σημειώστε ότι όταν υπάρχει ένα φορτίο στην αναλογική έξοδο (πραγματική κατάσταση), η μέγιστη τάση εξόδου θα πέσει-το φύλλο δεδομένων (το οποίο κατεβάσατε) εμφανίζει πτώση 10% για φορτίο 10kΩ. Τώρα για το κύκλωμα επίδειξης.

Σημειώστε τη χρήση αντιστάσεων έλξης 10kΩ στο δίαυλο I2C και τον πυκνωτή 10μF μεταξύ 5V και GND. Η διεύθυνση του διαύλου I2C ορίζεται από ένα συνδυασμό ακίδων A0 ~ A2 και μαζί με αυτές στο GND η διεύθυνση είναι 0x90. Η αναλογική έξοδος μπορεί να ληφθεί από τον πείρο 15 (και υπάρχει ένα ξεχωριστό αναλογικό GND στον πείρο 13. Επίσης, συνδέστε τον πείρο 13 στο GND και το κύκλωμα GND στο Arduino GND.

Για να ελέγξουμε το DAC πρέπει να στείλουμε δύο byte δεδομένων. Το πρώτο είναι το byte ελέγχου, το οποίο απλώς ενεργοποιεί το DAC και είναι 1000000 (ή 0x40) και το επόμενο byte είναι η τιμή μεταξύ 0 και 255 (επίπεδο εξόδου). Αυτό αποδεικνύεται στο ακόλουθο σκίτσο:

// Παράδειγμα 52.1 επίδειξη DAC PCF8591

#include "Wire.h" #define PCF8591 (0x90 >> 1) // I2C bus bus address void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (0x40); // byte ελέγχου - ενεργοποιήστε το DAC (δυαδικό 1000000) Wire.write (i); // τιμή για αποστολή στο DAC Wire.endTransmission (); // τερματισμός μετάδοσης}

για (int i = 255; i> = 0; --i)

{Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (0x40); // byte ελέγχου - ενεργοποιήστε το DAC (δυαδικό 1000000) Wire.write (i); // τιμή για αποστολή στο DAC Wire.endTransmission (); // τερματισμός μετάδοσης}}

Παρατηρήσατε τη μετατόπιση bit της διεύθυνσης διαύλου στη δήλωση #define; Το Arduino στέλνει διευθύνσεις 7-bit αλλά ο PCF8591 θέλει 8-bit, οπότε μετατοπίζουμε το byte κατά ένα bit.

Βήμα 2:

Εικόνα
Εικόνα

Τα αποτελέσματα του σκίτσου εμφανίζονται στην εικόνα, συνδέσαμε το Vref με 5V και τον αισθητήρα παλμογράφου και το GND στην αναλογική έξοδο και GND αντίστοιχα.

Βήμα 3:

Εικόνα
Εικόνα

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

// Παράδειγμα 52.2 Επίδειξη ημιτονοειδούς κύματος PCF8591 DAC

#include "Wire.h" #define PCF8591 (0x90 >> 1) // I2C λεωφορείο διεύθυνση uint8_t sine_wave [256] = {0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96, 0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE, 0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4, 0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0 ως, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0 ως, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A, 0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52, 0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x 3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0X18, 0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0x, 0x0x, 0x0x, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0x 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0X18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64, 0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D}; void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (0x40); // byte ελέγχου - ενεργοποιήστε το DAC (δυαδικό 1000000) Wire.write (sine_wave ); // τιμή για αποστολή στο DAC Wire.endTransmission (); // τερματισμός μετάδοσης}}

Βήμα 4:

Εικόνα
Εικόνα

Για την ακόλουθη χωματερή εικόνας DSO, αλλάξαμε το Vref σε 3.3V - σημειώστε την αλλαγή στο μέγιστο στο ημιτονοειδές κύμα.

Τώρα μπορείτε να πειραματιστείτε με το DAC για να δημιουργήσετε ηχητικά εφέ, σήματα ή να ελέγξετε άλλα αναλογικά κυκλώματα.

Βήμα 5: Χρήση των ADC (μετατροπείς αναλογικού σε ψηφιακό)

Εάν έχετε χρησιμοποιήσει τη λειτουργία analogRead () στο Arduino (πολύ πίσω στο Κεφάλαιο 1), τότε είστε ήδη εξοικειωμένοι με ένα ADC. Χωρίς PCF8591 μπορούμε να διαβάσουμε μια τάση μεταξύ μηδέν και του Vref και θα επιστρέψει μια τιμή μεταξύ μηδέν και 255 που είναι ευθέως ανάλογη με το μηδέν και το Vref.

Για παράδειγμα, η μέτρηση των 3.3V θα πρέπει να επιστρέψει 168. Η ανάλυση (8-bit) του ADC είναι χαμηλότερη από το ενσωματωμένο Arduino (10-bit), ωστόσο το PCF8591 μπορεί να κάνει κάτι που το ADC του Arduino δεν μπορεί. Αλλά θα φτάσουμε σε αυτό σε μια στιγμή. Πρώτον, για απλή ανάγνωση των τιμών κάθε καρφίτσας ADC στέλνουμε ένα byte ελέγχου για να πούμε στον PCF8591 ποιο ADC θέλουμε να διαβάσουμε. Για ADC μηδέν έως τρία το byte ελέγχου είναι 0x00, 0x01, ox02 και 0x03 αντίστοιχα.

Στη συνέχεια, ζητάμε δύο byte δεδομένων πίσω από το ADC και αποθηκεύουμε το δεύτερο byte για χρήση. Γιατί δύο byte; Το PCF8591 επιστρέφει πρώτα την τιμή που μετρήθηκε προηγουμένως - μετά το τρέχον byte. (Δείτε το σχήμα 8 στο φύλλο δεδομένων). Τέλος, εάν δεν χρησιμοποιείτε όλες τις καρφίτσες ADC, συνδέστε τις αχρησιμοποίητες στο GND. Το ακόλουθο σκίτσο παρακολούθησης απλώς ανακτά τιμές από κάθε καρφίτσα ADC μία κάθε φορά και στη συνέχεια τις εμφανίζει στη σειριακή οθόνη:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // Διεύθυνση I2C bus #define ADC0 0x00 // byte ελέγχου για ανάγνωση μεμονωμένων ADCs #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 byte value0, value1, value2, value3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (ADC0); // byte ελέγχου - διαβάστε ADC0 Wire.endTransmission (); // τερματισμός μετάδοσης Wire.requestFrom (PCF8591, 2); value0 = Wire.read (); value0 = Wire.read (); Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (ADC1); // byte ελέγχου - διαβάστε ADC1 Wire.endTransmission (); // τερματισμός μετάδοσης Wire.requestFrom (PCF8591, 2); value1 = Wire.read (); value1 = Wire.read (); Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (ADC2); // byte ελέγχου - διαβάστε ADC2 Wire.endTransmission (); // τερματισμός μετάδοσης Wire.requestFrom (PCF8591, 2); value2 = Wire.read (); value2 = Wire.read (); Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (ADC3); // byte ελέγχου - διαβάστε ADC3 Wire.endTransmission (); // τερματισμός μετάδοσης Wire.requestFrom (PCF8591, 2); value3 = Wire.read (); value3 = Wire.read (); Serial.print (value0); Serial.print (""); Serial.print (value1); Serial.print (""); Serial.print (value2); Serial.print (""); Serial.print (value3); Serial.print (""); Serial.println (); }

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

Βήμα 6:

Για να το κάνετε αυτό, αλλάξτε το byte ελέγχου για να ζητήσετε αυτόματη αύξηση, η οποία γίνεται ρυθμίζοντας το bit 2 του byte ελέγχου στο 1. Έτσι, για να ξεκινήσουμε από το ADC0 χρησιμοποιούμε ένα νέο byte ελέγχου δυαδικού 00000100 ή δεκαεξαδικού 0x04. Στη συνέχεια, ζητήστε πέντε byte δεδομένων (για άλλη μια φορά αγνοούμε το πρώτο byte) που θα προκαλέσει την επιστροφή του PCF8591 σε μια αλυσίδα byte. Αυτή η διαδικασία αποδεικνύεται στο ακόλουθο σκίτσο:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // Διεύθυνση διαύλου I2C byte τιμή0, τιμή1, τιμή2, τιμή3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // ξυπνήστε PCF8591 Wire.write (0x04); // byte ελέγχου - διαβάστε το ADC0 και, στη συνέχεια, αυξήστε αυτόματα το Wire.endTransmission (); // τερματισμός μετάδοσης Wire.requestFrom (PCF8591, 5); value0 = Wire.read (); value0 = Wire.read (); value1 = Wire.read (); value2 = Wire.read (); value3 = Wire.read (); Serial.print (value0); Serial.print (""); Serial.print (value1); Serial.print (""); Serial.print (value2); Serial.print (""); Serial.print (value3); Serial.print (""); Serial.println (); }

Προηγουμένως αναφέραμε ότι το PCF8591 μπορεί να κάνει κάτι που το ADC του Arduino δεν μπορεί, και αυτό προσφέρει διαφορετικό ADC. Σε αντίθεση με το μονόκλινο του Arduino (δηλαδή επιστρέφει τη διαφορά μεταξύ της θετικής τάσης σήματος και του GND, το διαφορικό ADC δέχεται δύο σήματα (που δεν χρειάζεται απαραίτητα να αναφέρονται στη γείωση) και επιστρέφει τη διαφορά μεταξύ των δύο σημάτων Αυτό μπορεί να είναι βολικό για τη μέτρηση μικρών μεταβολών τάσεων για κυψέλες φορτίου και ούτω καθεξής.

Βήμα 7:

Εικόνα
Εικόνα

Η ρύθμιση του PCF8591 για διαφορικό ADC είναι απλή υπόθεση αλλαγής του byte ελέγχου. Εάν μεταβείτε στη σελίδα επτά του φύλλου δεδομένων, λάβετε υπόψη τους διαφορετικούς τύπους προγραμματισμού αναλογικών εισόδων. Προηγουμένως χρησιμοποιούσαμε τη λειτουργία '00' για τέσσερις εισόδους, ωστόσο μπορείτε να επιλέξετε τις άλλες που είναι σαφώς εικονογραφημένες, για παράδειγμα την εικόνα.

Για να ορίσετε το byte ελέγχου για δύο διαφορικές εισόδους, χρησιμοποιήστε δυαδικό 00110000 ή 0x30. Στη συνέχεια, είναι ένα απλό ζήτημα να ζητήσετε τα byte δεδομένων και να εργαστείτε μαζί τους. Όπως μπορείτε να δείτε, υπάρχει επίσης συνδυασμός μονής/διαφορικής και σύνθετης τριών διαφορικής εισόδου. Ωστόσο, θα τους αφήσουμε προς το παρόν.

Ας ελπίσουμε ότι βρήκατε αυτό το ενδιαφέρον, είτε προσθέτετε ένα DAC στα πειράματά σας είτε μάθετε λίγο περισσότερα για τους ADC. Παρακαλώ σκεφτείτε να παραγγείλετε το PCF8591 σας από το PMD Way.

Αυτή η ανάρτηση σας έφερε το pmdway.com - τα πάντα για κατασκευαστές και λάτρεις των ηλεκτρονικών ειδών, με δωρεάν παράδοση σε όλο τον κόσμο.

Συνιστάται: