Το δημοφιλές πρωτόκολλο I2C επιτρέπει σε δύο ή περισσότερες πλακέτες Arduino να επικοινωνούν. Ανακαλύψτε πώς να τα συνδέσετε και να τα κωδικοποιήσετε.
Ενώ ένα μόνο Arduino μπορεί να ολοκληρώσει πολλές εργασίες, ορισμένα έργα μπορεί να απαιτούν τη χρήση περισσότερων από μιας πλακέτας για τη διαχείριση διαφορετικών λειτουργιών. Επομένως, για να ενεργοποιηθεί η μεταφορά δεδομένων μεταξύ των δύο μικροελεγκτών, πρέπει να ρυθμιστεί ένα πρωτόκολλο επικοινωνίας όπως CAN, SPI, I2C ή UART.
Σε αυτόν τον οδηγό, θα καλύψουμε τα βασικά για το πώς λειτουργεί το I2C, τις συνδέσεις υλικού και την εφαρμογή λογισμικού που απαιτούνται για τη ρύθμιση δύο πλακών Arduino ως κύρια και εξαρτημένη συσκευή I2C.
Τι είναι το I2C;
Το Inter-Integrated Circuit (I2C) είναι ένα ευρέως χρησιμοποιούμενο πρωτόκολλο επικοινωνίας σε ενσωματωμένα συστήματα και μικροελεγκτές για να επιτρέψει τη μεταφορά δεδομένων μεταξύ ηλεκτρονικών συσκευών. Σε αντίθεση με το SPI (Serial Peripheral Interface), το I2C σάς επιτρέπει να συνδέσετε περισσότερες από μία κύριες συσκευές σε ένα δίαυλο με μονή ή πολλαπλές συσκευές slave. Χρησιμοποιήθηκε για πρώτη φορά από τη Philips και είναι επίσης γνωστό ως πρωτόκολλο επικοινωνίας Two Wire Interface (TWI).
Πώς λειτουργεί η επικοινωνία I2C;
Το I2C χρησιμοποιεί δύο αμφίδρομες γραμμές: Serial Data (SDA) και Serial Clock (SCL) για τη μεταφορά δεδομένων και το συγχρονισμό της επικοινωνίας μεταξύ συσκευών. Κάθε συσκευή που είναι συνδεδεμένη στο δίαυλο I2C έχει μια μοναδική διεύθυνση που την προσδιορίζει κατά την επικοινωνία. Το πρωτόκολλο I2C επιτρέπει σε πολλές συσκευές να μοιράζονται τον ίδιο δίαυλο και κάθε συσκευή μπορεί να λειτουργήσει ως κύριος ή σκλάβος.
Η επικοινωνία ξεκινά από την κύρια συσκευή και η εσφαλμένη διευθυνσιοδότηση των υποτελών συσκευών μπορεί να προκαλέσει σφάλματα στη μεταφορά. Δείτε τον αναλυτικό οδηγό μας για πώς λειτουργούν οι σειριακές επικοινωνίες UART, SPI και I2C για να σας δώσω κάποιο πλαίσιο.
Ένα σημαντικό πλεονέκτημα της επικοινωνίας I2C που αξίζει να σημειωθεί είναι η ευελιξία που προσφέρει όταν πρόκειται για διαχείριση ενέργειας. Οι συσκευές που λειτουργούν σε διαφορετικά επίπεδα τάσης μπορούν ακόμα να επικοινωνούν αποτελεσματικά με τη βοήθεια μετατροπέων τάσης. Αυτό σημαίνει ότι οι συσκευές που λειτουργούν στα 3,3 V χρειάζονται μετατοπιστές τάσης για να συνδεθούν σε δίαυλο I2C 5 V.
The Wire Library
Η βιβλιοθήκη Wire είναι μια ενσωματωμένη βιβλιοθήκη Arduino που παρέχει λειτουργίες για επικοινωνία μέσω I2C. Χρησιμοποιεί δύο ακίδες—SDA και SCL—στην πλακέτα Arduino για επικοινωνία I2C.
I2C pins στο Arduino Uno:
Καρφίτσες Arduino Nano I2C:
Για να χρησιμοποιήσετε τη βιβλιοθήκη, πρέπει να συμπεριλάβετε το Σύρμα.χ αρχείο κεφαλίδας στην αρχή του σκίτσου Arduino.
#περιλαμβάνω
Η βιβλιοθήκη Wire παρέχει λειτουργίες για την έναρξη επικοινωνίας με μια συσκευή I2C, την αποστολή δεδομένων και τη λήψη δεδομένων. Μερικές σημαντικές λειτουργίες που πρέπει να γνωρίζετε περιλαμβάνουν:
- Wire.begin(): χρησιμοποιείται για σύνδεση στο δίαυλο I2C και έναρξη επικοινωνίας.
- Wire.beginTransmission(): χρησιμοποιείται για τον καθορισμό της εξαρτημένης διεύθυνσης και την έναρξη μιας μετάδοσης.
- Wire.write(): χρησιμοποιείται για την αποστολή δεδομένων στη συσκευή I2C.
- Wire.endTransmission(): χρησιμοποιείται για τον τερματισμό της μετάδοσης και τον έλεγχο για σφάλματα.
- Wire.requestFrom(): χρησιμοποιείται για να ζητήσει δεδομένα από τη συσκευή I2C.
- Wire.available(): χρησιμοποιείται για να ελέγξει εάν τα δεδομένα είναι διαθέσιμα για ανάγνωση από τη συσκευή I2C.
- Wire.read(): χρησιμοποιείται για την ανάγνωση δεδομένων από τη συσκευή I2C.
Χρησιμοποιήστε το Wire.beginTransmission() λειτουργία για να ορίσετε τη διεύθυνση του αισθητήρα, η οποία εισάγεται ως όρισμα. Για παράδειγμα, εάν η διεύθυνση του αισθητήρα είναι 0x68, θα χρησιμοποιούσατε:
Σύρμα.έναρξηΜετάδοσης(0x68);
Ρύθμιση υλικού Arduino I2C
Για να συνδέσετε δύο πλακέτες Arduino χρησιμοποιώντας το I2C, θα χρειαστείτε τα ακόλουθα στοιχεία υλικού:
- Δύο πλακέτες Arduino (κύριος και σκλάβος)
- Breadboard
- Καλώδια βραχυκυκλωτήρα
- Δύο αντιστάσεις έλξης 4,7 kΩ
Συνδέστε το SDA και SCL καρφίτσες και των δύο πλακών Arduino σε ένα breadboard. Συνδέστε τις αντιστάσεις έλξης μεταξύ των SDA και SCL καρφίτσες και το 5V ράγα τροφοδοσίας στο breadboard. Τέλος, συνδέστε τις δύο σανίδες ψωμιού μεταξύ τους χρησιμοποιώντας καλώδια βραχυκυκλωτήρα.
Κύκλωμα Arduino Uno
Νανοκύκλωμα Arduino
Ρύθμιση των πλακών Arduino ως I2C Master και Slave Devices
Χρησιμοποιήστε το Wire.requestFrom() λειτουργία για να καθορίσουμε τη διεύθυνση της εξαρτημένης συσκευής με την οποία θέλουμε να επικοινωνήσουμε. Στη συνέχεια χρησιμοποιήστε το Wire.read() λειτουργία λήψης δεδομένων από τη εξαρτημένη συσκευή.
Κύριος κωδικός συσκευής:
#περιλαμβάνω
κενόςεγκατάσταση(){
Σύρμα.αρχίζουν(); // εγγραφείτε στο i2c bus
Κατα συρροη.αρχίζουν(9600); // έναρξη σειράς για έξοδο
}
κενόςλήψη Δεδομένων(){
ενθ διεύθυνση = 8;
ενθ bytesToRead = 6;
Σύρμα.αίτημαΑπό(διεύθυνση, bytesToRead);
ενώ (Σύρμα.διαθέσιμος()) {
απανθρακώνω δεδομένα = Σύρμα.ανάγνωση();
Κατα συρροη.Τυπώνω(δεδομένα);
}
καθυστέρηση(500);
}
κενόςβρόχος(){
receiveData();
}
ο Wire.onReceive() Η συνάρτηση χρησιμοποιείται για να καθορίσει τι πρέπει να κάνει όταν η υποτελής συσκευή λαμβάνει δεδομένα από την κύρια συσκευή. Στον παραπάνω κώδικα, το Wire.available() η λειτουργία ελέγχει εάν τα δεδομένα είναι διαθέσιμα και το Wire.read() η λειτουργία διαβάζει τα δεδομένα που αποστέλλονται από την κύρια συσκευή.
Κωδικός εξαρτημένης συσκευής:
#περιλαμβάνω
κενόςεγκατάσταση(){
Σύρμα.αρχίζουν(8); // συνδεθείτε στο δίαυλο I2C με διεύθυνση 8
Σύρμα.onΛήψη(receiveEvent); // κλήση receiveEvent όταν λαμβάνονται δεδομένα
}
κενόςβρόχος(){
καθυστέρηση(100);
}
κενόςλαμβάνωΕκδήλωση(ενθ byte){
Σύρμα.γράφω("Γειά σου "); // απαντήστε με μήνυμα 6 byte όπως αναμένεται από τον κύριο
}
Αποστολή και λήψη δεδομένων με χρήση I2C
Σε αυτό το παράδειγμα, ας διαβάσουμε τη θερμοκρασία από έναν αισθητήρα θερμοκρασίας DHT11 που συνδέεται με το βοηθητικό Arduino και ας την εκτυπώσουμε στη σειριακή οθόνη του κύριου Arduino.
Ας τροποποιήσουμε τον κώδικα που γράψαμε νωρίτερα για να συμπεριλάβουμε τη μέτρηση θερμοκρασίας που θα στείλουμε στη συνέχεια στην κύρια πλακέτα μέσω του διαύλου I2C. Στη συνέχεια, η κύρια πλακέτα μπορεί να διαβάσει την τιμή που στείλαμε και στη συνέχεια να την εμφανίσει στη σειριακή οθόνη.
Κύριος κωδικός συσκευής:
#περιλαμβάνω
κενόςεγκατάσταση(){
Σύρμα.αρχίζουν();
Κατα συρροη.αρχίζουν(9600);
Κατα συρροη.println("Master Initialized!");
}
κενόςβρόχος(){
Σύρμα.αίτημαΑπό(8, 1); // Ζητήστε δεδομένα θερμοκρασίας από την υποτελή
αν (Σύρμα.διαθέσιμος()) {
ψηφιόλεξη θερμοκρασία = Σύρμα.ανάγνωση(); // Ανάγνωση δεδομένων θερμοκρασίας από την υποτελή
Κατα συρροη.Τυπώνω("Θερμοκρασία:");
Κατα συρροη.Τυπώνω(θερμοκρασία);
Κατα συρροη.println("° C");
}
καθυστέρηση(2000); // Περιμένετε 2 δευτερόλεπτα πριν ζητήσετε ξανά θερμοκρασία
}
Κωδικός εξαρτημένης συσκευής:
#περιλαμβάνω
#περιλαμβάνω#καθορίζω DHTPIN 4 // Η καρφίτσα συνδέεται με τον αισθητήρα DHT
#καθορίζω DHTTYPE DHT11 // Τύπος αισθητήρα DHT
DHT dht(DHTPIN, DHTTYPE);
ψηφιόλεξη θερμοκρασία;κενόςεγκατάσταση(){
Σύρμα.αρχίζουν(8); // Η υποτελής διεύθυνση είναι 8
Σύρμα.κατόπιν αίτησης(requestEvent);
dht.αρχίζουν();
}κενόςβρόχος(){
καθυστέρηση(2000); // Περιμένετε 2 δευτερόλεπτα για να σταθεροποιηθεί το DHT
θερμοκρασία = dht.θερμοκρασία ανάγνωσης(); // Ανάγνωση θερμοκρασίας από τον αισθητήρα DHT
}
κενόςrequestEvent(){
Σύρμα.γράφω(θερμοκρασία); // Αποστολή δεδομένων θερμοκρασίας στο master
}
Μπορείτε να προσαρμόσετε αυτόν τον κωδικό ώστε να ταιριάζει σε όποιους αισθητήρες έχετε στο έργο σας ή ακόμη και να εμφανίσετε τις τιμές του αισθητήρα σε μια μονάδα οθόνης φτιάξτε το δικό σας θερμόμετρο και μετρητή υγρασίας δωματίου.
Slave Addressing με I2C στο Arduino
Για να διαβάσετε τιμές από στοιχεία που προστέθηκαν σε ένα δίαυλο I2C σε ένα τέτοιο έργο, είναι σημαντικό να συμπεριλάβετε τη σωστή υποτελή διεύθυνση κατά την κωδικοποίηση. Ευτυχώς, το Arduino προσφέρει μια βιβλιοθήκη σαρωτή που απλοποιεί τη διαδικασία αναγνώρισης σκλάβων διευθύνσεις, εξαλείφοντας την ανάγκη να κοιτάξουμε σε μεγάλα φύλλα δεδομένων αισθητήρων και προκαλούν σύγχυση στο διαδίκτυο τεκμηρίωση.
Χρησιμοποιήστε τον ακόλουθο κώδικα για να προσδιορίσετε τη διεύθυνση οποιασδήποτε εξαρτημένης συσκευής που υπάρχει στο δίαυλο I2C.
#περιλαμβάνω
// Συμπεριλάβετε τη βιβλιοθήκη Wire για επικοινωνία I2C κενόςεγκατάσταση(){
Σύρμα.αρχίζουν(); // Εκκίνηση της επικοινωνίας I2C
Κατα συρροη.αρχίζουν(9600); // Εκκινήστε τη σειριακή επικοινωνία με ρυθμό baud 9600
ενώ (!Κατα συρροη); // Περιμένετε να δημιουργηθεί η σειριακή σύνδεση
Κατα συρροη.println("\nΣαρωτής I2C"); // Εκτυπώστε ένα μήνυμα που υποδεικνύει την έναρξη της σάρωσης I2C
}κενόςβρόχος(){
ψηφιόλεξη σφάλμα, διεύθυνση? // Δήλωση μεταβλητών για αποθήκευση σφαλμάτων και διευθύνσεων συσκευών
ενθ nΣυσκευές; // Δηλώστε μια μεταβλητή για να αποθηκεύσετε τον αριθμό των συσκευών που βρέθηκανΚατα συρροη.println("Ερευνα..."); // Εκτυπώστε ένα μήνυμα που υποδεικνύει την έναρξη της σάρωσης I2C
nΣυσκευές = 0; // Ορίστε τον αριθμό των συσκευών που βρέθηκαν σε 0
Για (διεύθυνση = 1; διεύθυνση < 127; διεύθυνση++) { // Επανάληψη σε όλες τις πιθανές διευθύνσεις I2C
Σύρμα.έναρξηΜετάδοσης(διεύθυνση); // Ξεκινήστε μια μετάδοση στην τρέχουσα διεύθυνση
σφάλμα = Σύρμα.τέλοςΜετάδοση(); // Τερματίστε τη μετάδοση και αποθηκεύστε τυχόν σφάλματααν (σφάλμα == 0) { // Εάν δεν βρέθηκαν σφάλματα
Κατα συρροη.Τυπώνω("Βρέθηκε συσκευή I2C στη διεύθυνση 0x"); // Εκτυπώστε ένα μήνυμα που υποδεικνύει ότι βρέθηκε συσκευή
αν (διεύθυνση < 16) Κατα συρροη.Τυπώνω("0"); // Εάν η διεύθυνση είναι μικρότερη από 16, προσθέστε ένα αρχικό 0 για λόγους μορφοποίησης
Κατα συρροη.Τυπώνω(διεύθυνση, HEX); // Εκτυπώστε τη διεύθυνση σε δεκαεξαδική μορφή
Κατα συρροη.println(" !"); // Εκτυπώστε ένα μήνυμα που υποδεικνύει ότι βρέθηκε συσκευή
nDevices++; // Αύξηση του αριθμού των συσκευών που βρέθηκαν
}
αλλούαν (σφάλμα == 4) { // Εάν βρέθηκε σφάλμα
Κατα συρροη.Τυπώνω("Άγνωστο σφάλμα στη διεύθυνση 0x"); // Εκτυπώστε ένα μήνυμα που υποδεικνύει ότι βρέθηκε σφάλμα
αν (διεύθυνση < 16) Κατα συρροη.Τυπώνω("0"); // Εάν η διεύθυνση είναι μικρότερη από 16, προσθέστε ένα αρχικό 0 για λόγους μορφοποίησης
Κατα συρροη.println(διεύθυνση, HEX); // Εκτυπώστε τη διεύθυνση σε δεκαεξαδική μορφή
}
}
αν (nΣυσκευές == 0) { // Εάν δεν βρέθηκαν συσκευές
Κατα συρροη.println("Δεν βρέθηκαν συσκευές I2C\n"); // Εκτυπώστε ένα μήνυμα που υποδεικνύει ότι δεν βρέθηκαν συσκευές
}
αλλού { // Εάν βρέθηκαν συσκευές
Κατα συρροη.println("ολοκληρώθηκε\n"); // Εκτυπώστε ένα μήνυμα που υποδεικνύει το τέλος της σάρωσης I2C
}
καθυστέρηση(5000); // Καθυστέρηση για 5 δευτερόλεπτα πριν ξεκινήσει η επόμενη σάρωση
}
Επεκτείνετε το έργο σας σήμερα
Η διασύνδεση δύο πλακών Arduino με χρήση του πρωτοκόλλου επικοινωνίας I2C προσφέρει έναν ευέλικτο και αποτελεσματικό τρόπο για την επίτευξη πολύπλοκων εργασιών που δεν μπορούν να διεκπεραιωθούν από μία μόνο πλακέτα. Με τη βοήθεια της βιβλιοθήκης Wire, η επικοινωνία μεταξύ των δύο πλακών χρησιμοποιώντας το I2C γίνεται εύκολη, επιτρέποντάς σας να προσθέσετε περισσότερα στοιχεία στο έργο σας.