- Τι είναι το πρωτόκολλο επικοινωνίας I2C;
- Πώς λειτουργεί η επικοινωνία I2C;
- Πού να χρησιμοποιήσετε την επικοινωνία I2C;
- I2C στο Arduino
- Απαιτούμενα στοιχεία
- Διάγραμμα κυκλώματος
- Επεξήγηση εργασίας
- Προγραμματισμός I2C στο Arduino
- Εξήγηση προγραμματισμού Master Arduino
- Επεξήγηση προγραμματισμού Slave Arduino
Στο προηγούμενο σεμινάριό μας έμαθα για την επικοινωνία SPI στο Arduino. Σήμερα θα μάθουμε για ένα άλλο πρωτόκολλο σειριακής επικοινωνίας: I2C (Inter Integrated Circuits). Συγκρίνοντας το I2C με το SPI, το I2C έχει μόνο δύο καλώδια ενώ το SPI χρησιμοποιεί τέσσερα και το I2C μπορεί να έχει Multiple Master και Slave, ενώ το SPI μπορεί να έχει μόνο ένα master και πολλαπλά slave. Υπάρχουν λοιπόν περισσότεροι από ένας μικροελεγκτές σε ένα έργο που πρέπει να είναι κύριοι και στη συνέχεια χρησιμοποιείται το I2C. Η επικοινωνία I2C χρησιμοποιείται γενικά για επικοινωνία με γυροσκόπιο, επιταχυνσιόμετρο, αισθητήρες βαρομετρικής πίεσης, οθόνες LED κ.λπ.
Σε αυτό το σεμινάριο Arduino I2C θα χρησιμοποιήσουμε την επικοινωνία I2C μεταξύ δύο πινάκων arduino και θα στείλουμε (0 έως 127) τιμές ο ένας στον άλλο χρησιμοποιώντας ποτενσιόμετρο. Οι τιμές θα εμφανίζονται στην οθόνη LCD 16x2 που είναι συνδεδεμένη σε κάθε ένα από το Arduino. Εδώ ένα Arduino θα ενεργήσει ως Master και ένα άλλο θα ενεργήσει ως Slave. Ας ξεκινήσουμε λοιπόν με την εισαγωγή για την επικοινωνία I2C.
Τι είναι το πρωτόκολλο επικοινωνίας I2C;
Ο όρος IIC σημαίνει " Inter Integrated Circuits ". Κανονικά δηλώνεται ως I2C ή I τετράγωνο C ή ακόμα και ως πρωτόκολλο διασύνδεσης 2 καλωδίων (TWI) σε ορισμένα σημεία, αλλά όλα σημαίνει το ίδιο. Το I2C είναι ένα σύγχρονο πρωτόκολλο επικοινωνίας που σημαίνει, και οι δύο συσκευές που μοιράζονται τις πληροφορίες πρέπει να μοιράζονται ένα κοινό σήμα ρολογιού. Έχει μόνο δύο καλώδια για την κοινή χρήση πληροφοριών από τις οποίες το ένα χρησιμοποιείται για το σήμα κόκορας και το άλλο χρησιμοποιείται για την αποστολή και λήψη δεδομένων.
Πώς λειτουργεί η επικοινωνία I2C;
Η επικοινωνία I2C παρουσιάστηκε για πρώτη φορά από τον Phillips. Όπως ειπώθηκε νωρίτερα, έχει δύο καλώδια, αυτά τα δύο καλώδια θα συνδεθούν σε δύο συσκευές. Εδώ μια συσκευή ονομάζεται κύριος και η άλλη συσκευή ονομάζεται σκλάβος. Η επικοινωνία πρέπει και θα συμβαίνει πάντα μεταξύ δύο Δασκάλων και Σκλάβων. Το πλεονέκτημα της επικοινωνίας I2C είναι ότι περισσότεροι από ένας σκλάβοι μπορούν να συνδεθούν με έναν Master.
Η πλήρης επικοινωνία πραγματοποιείται μέσω αυτών των δύο καλωδίων, δηλαδή Serial Clock (SCL) και Serial Data (SDA).
Serial Clock (SCL): Μοιράζεται το σήμα ρολογιού που δημιουργείται από τον κύριο με το slave
Σειριακά δεδομένα (SDA): Στέλνει τα δεδομένα από και προς το Master και το slave.
Ανά πάσα στιγμή μόνο ο πλοίαρχος θα μπορεί να ξεκινήσει την επικοινωνία. Δεδομένου ότι υπάρχουν περισσότεροι από ένας σκλάβοι στο λεωφορείο, ο πλοίαρχος πρέπει να αναφέρεται σε κάθε σκλάβος χρησιμοποιώντας διαφορετική διεύθυνση. Όταν απευθύνεται μόνο ο σκλάβος με τη συγκεκριμένη διεύθυνση θα απαντήσει πίσω με τις πληροφορίες, ενώ οι άλλοι θα σταματήσουν. Με αυτόν τον τρόπο μπορούμε να χρησιμοποιήσουμε το ίδιο λεωφορείο για επικοινωνία με πολλές συσκευές.
Τα επίπεδα τάσης του I2C δεν είναι προκαθορισμένα. Η επικοινωνία I2C είναι ευέλικτη, σημαίνει ότι η συσκευή που τροφοδοτείται από 5v volt, μπορεί να χρησιμοποιήσει 5v για I2C και οι συσκευές 3.3v μπορούν να χρησιμοποιήσουν 3v για επικοινωνία I2C. Τι γίνεται όμως αν δύο συσκευές που λειτουργούν σε διαφορετικές τάσεις, πρέπει να επικοινωνήσουν χρησιμοποιώντας το I2C; Μια 5V I2C λεωφορείο δεν μπορεί να συνδεθεί με 3.3V συσκευή. Σε αυτήν την περίπτωση χρησιμοποιούνται μετατοπιστές τάσης για να ταιριάζουν με τα επίπεδα τάσης μεταξύ δύο διαύλων I2C.
Υπάρχουν ορισμένα σύνολα όρων που πλαισιώνουν μια συναλλαγή. Η αρχικοποίηση της μετάδοσης ξεκινά με ένα μειωμένο άκρο του SDA, το οποίο ορίζεται ως συνθήκη «ΕΚΚΙΝΗΣΗ» στο παρακάτω διάγραμμα όπου ο κύριος αφήνει το SCL υψηλό ενώ ρυθμίζει το SDA χαμηλό.
Όπως φαίνεται στο παραπάνω διάγραμμα παρακάτω, Το μειονέκτημα του SDA είναι η σκανδάλη υλικού για την κατάσταση START. Μετά από αυτό όλες οι συσκευές του ίδιου διαύλου μπαίνουν σε λειτουργία ακρόασης.
Με τον ίδιο τρόπο, το ανερχόμενο άκρο του SDA σταματά τη μετάδοση που εμφανίζεται ως κατάσταση «STOP» στο παραπάνω διάγραμμα, όπου ο κύριος αφήνει το SCL ψηλά και επίσης απελευθερώνει το SDA για να πάει ΥΨΗΛΑ. Έτσι, η άνοδος του SDA σταματά τη μετάδοση.
Το bit R / W δείχνει την κατεύθυνση μετάδοσης των ακόλουθων byte, εάν είναι ΥΨΗΛΟ σημαίνει ότι ο σκλάβος θα μεταδώσει και εάν είναι χαμηλός σημαίνει ότι ο κύριος θα μεταδώσει.
Κάθε bit μεταδίδεται σε κάθε κύκλο ρολογιού, οπότε χρειάζονται 8 κύκλους ρολογιού για τη μετάδοση ενός byte. Μετά από κάθε byte που αποστέλλεται ή λαμβάνεται, ο ένατος κύκλος ρολογιού διατηρείται για το ACK / NACK (αναγνωρίζεται / δεν αναγνωρίζεται). Αυτό το bit ACK δημιουργείται είτε από σκλάβους είτε από τον κύριο ανάλογα με την κατάσταση. Για bit ACK, το SDA έχει οριστεί σε χαμηλά από τον κύριο ή τον σκλάβο στον 9ο κύκλο ρολογιού. Επομένως, είναι χαμηλό, θεωρείται ως ACK διαφορετικά NACK.
Πού να χρησιμοποιήσετε την επικοινωνία I2C;
Η επικοινωνία I2C χρησιμοποιείται μόνο για επικοινωνία μικρής απόστασης. Είναι σίγουρα αξιόπιστο σε ένα βαθμό, δεδομένου ότι διαθέτει συγχρονισμένο παλμό ρολογιού για να το κάνει έξυπνο. Αυτό το πρωτόκολλο χρησιμοποιείται κυρίως για επικοινωνία με αισθητήρα ή άλλες συσκευές που πρέπει να στέλνουν πληροφορίες σε έναν κύριο. Είναι πολύ βολικό όταν ένας μικροελεγκτής πρέπει να επικοινωνεί με πολλές άλλες υπομονάδες χρησιμοποιώντας τουλάχιστον μόνο καλώδια. Αν ψάχνετε για επικοινωνία μεγάλης εμβέλειας, πρέπει να δοκιμάσετε το RS232 και αν ψάχνετε για πιο αξιόπιστη επικοινωνία, θα πρέπει να δοκιμάσετε το πρωτόκολλο SPI.
I2C στο Arduino
Η παρακάτω εικόνα δείχνει τις καρφίτσες I2C που υπάρχουν στο Arduino UNO.
Γραμμή I2C | Καρφιτσώστε στο Arduino |
SDA | Α4 |
SCL | Α5 |
Πριν ξεκινήσουμε τον προγραμματισμό I2C χρησιμοποιώντας δύο Arduino. Πρέπει να μάθουμε για τη βιβλιοθήκη Wire που χρησιμοποιείται στο Arduino IDE.
Η βιβλιοθήκη
1. Wire.begin (διεύθυνση):
Χρήση: Αυτή η βιβλιοθήκη χρησιμοποιείται για επικοινωνία με συσκευές I2C. Αυτό ξεκινά τη βιβλιοθήκη του Wire και εγγραφείτε στο λεωφορείο I2C ως master ή slave.
Διεύθυνση: Η διεύθυνση σκλάβων 7-bit είναι προαιρετική και εάν η διεύθυνση δεν έχει καθοριστεί, συνδέεται στο λεωφορείο ως master σαν αυτό.
2. Wire.read ():
Χρήση: Αυτή η συνάρτηση χρησιμοποιείται για να διαβάσει ένα byte που ελήφθη από την κύρια ή τη δευτερεύουσα συσκευή, είτε μεταδόθηκε από μια υποτελή συσκευή σε μια κύρια συσκευή μετά από μια κλήση προς requestFrom () ή μεταδόθηκε από έναν κύριο σε έναν υποτελή.
3. Wire.write ():
Χρήση: Αυτή η λειτουργία χρησιμοποιείται για την εγγραφή δεδομένων σε μια υποτελή συσκευή ή μια κύρια συσκευή.
Slave to Master: Ο Slave γράφει δεδομένα σε ένα master όταν το Wire.RequestFrom () χρησιμοποιείται στο master.
Master to Slave: Για μετάδοση από μια κύρια σε εξαρτημένη συσκευή, το Wire.write () χρησιμοποιείται ενδιάμεσες κλήσεις προς Wire.beginTransmission () και Wire.endTransmission ().
Το Wire.write () μπορεί να γραφτεί ως:
- Wire.write (τιμή)
τιμή: μια τιμή για αποστολή ως ένα byte.
- Wire.write (συμβολοσειρά):
string: μια συμβολοσειρά για αποστολή ως σειρά byte.
- Wire.write (δεδομένα, μήκος):
data: μια σειρά δεδομένων για αποστολή ως byte
μήκος: ο αριθμός των bytes για μετάδοση.
4. Wire.begin Μετάδοση (διεύθυνση):
Χρήση: Αυτή η λειτουργία χρησιμοποιείται για να ξεκινήσει μια μετάδοση στη συσκευή I2C με τη δεδομένη διεύθυνση σκλάβου. Στη συνέχεια, build ουρά των bytes για μετάδοση με το write () λειτουργία και στη συνέχεια να τα μεταδίδει με την κλήση endTransmission () λειτουργία. Μεταδίδεται η διεύθυνση 7-bit της συσκευής.
5. Wire.endTransmission ();
Χρήση: Αυτή η συνάρτηση χρησιμοποιείται για τον τερματισμό μιας μετάδοσης σε μια εξαρτημένη συσκευή που ξεκίνησε από το startTransmission () και μεταδίδει τα bytes που ήταν στην ουρά από το Wire.write ().
6. Wire.onRequest ();
Χρήση: Αυτή η λειτουργία καλείται όταν ένας κύριος ζητά δεδομένα χρησιμοποιώντας το Wire.requestFrom () από τη δευτερεύουσα συσκευή. Εδώ μπορούμε να συμπεριλάβουμε τη συνάρτηση Wire.write () για την αποστολή δεδομένων στον κύριο.
7. Wire.onReceive ();Χρήση: Αυτή η λειτουργία καλείται όταν μια εξαρτημένη συσκευή λαμβάνει δεδομένα από έναν κύριο. Εδώ μπορούμε να συμπεριλάβουμε το Wire.read (); συνάρτηση για την ανάγνωση των δεδομένων που αποστέλλονται από τον κύριο.
8. Wire.requestFrom (διεύθυνση, ποσότητα)
Χρήση: Αυτή η λειτουργία χρησιμοποιείται στο κύριο για να ζητήσει byte από μια εξαρτημένη συσκευή. Η συνάρτηση Wire.read () χρησιμοποιείται για την ανάγνωση των δεδομένων που αποστέλλονται από τη δευτερεύουσα συσκευή.
διεύθυνση: η διεύθυνση 7-bit της συσκευής για να ζητήσετε byte
ποσότητα: ο αριθμός των byte που θα ζητήσετε
Απαιτούμενα στοιχεία
- Arduino Uno (2-Nos)
- Μονάδα οθόνης 16X2 LCD
- Ποτενσιόμετρο 10K (4-Nos)
- Ψωμί
- Σύνδεση καλωδίων
Διάγραμμα κυκλώματος
Επεξήγηση εργασίας
Εδώ για να δείξουμε την επικοινωνία I2C στο Arduino, χρησιμοποιούμε το Two Arduino UNO με οθόνη LCD 16X2 συνδεδεμένη μεταξύ τους και χρησιμοποιούμε δύο ποτενσιόμετρα και στα δύο arduino για να καθορίσουμε τις τιμές αποστολής (0 έως 127) από master σε slave και slave σε master μεταβάλλοντας το ποτενσιόμετρο.
Παίρνουμε αναλογική τιμή εισόδου στο arduino pin A0 από (0 έως 5V) χρησιμοποιώντας ποτενσιόμετρο και τα μετατρέπουμε σε αναλογική σε ψηφιακή τιμή (0 έως 1023). Στη συνέχεια, αυτές οι τιμές ADC μετατρέπονται περαιτέρω σε (0 έως 127) καθώς μπορούμε να στείλουμε μόνο δεδομένα 7-bit μέσω επικοινωνίας I2C. Η επικοινωνία I2C πραγματοποιείται μέσω δύο καλωδίων στον ακροδέκτη A4 & A5 και των δύο arduino.
Οι τιμές στην οθόνη LCD του Slave Arduino θα αλλάξουν μεταβάλλοντας το POT στην κύρια πλευρά και αντίστροφα.
Προγραμματισμός I2C στο Arduino
Αυτό το σεμινάριο έχει δύο προγράμματα ένα για τον κύριο Arduino και ένα άλλο για το slave Arduino. Πλήρη προγράμματα και για τις δύο πλευρές δίνονται στο τέλος αυτού του έργου με ένα βίντεο επίδειξης.
Εξήγηση προγραμματισμού Master Arduino
1. Πρώτα απ 'όλα πρέπει να συμπεριλάβουμε τη βιβλιοθήκη Wire για τη χρήση λειτουργιών επικοινωνίας I2C και τη βιβλιοθήκη LCD για τη χρήση λειτουργιών LCD. Ορίστε επίσης καρφίτσες LCD για LCD 16x2. Μάθετε περισσότερα σχετικά με τη διασύνδεση της οθόνης LCD με το Arduino εδώ.
#περιλαμβάνω
2. Σε άκυρη ρύθμιση ()
- Ξεκινάμε τη σειριακή επικοινωνία στο Baud Rate 9600.
Serial.begin (9600);
- Στη συνέχεια ξεκινάμε την επικοινωνία I2C στο pin (A4, A5)
Wire.begin (); // Ξεκινά την επικοινωνία I2C στο pin (A4, A5)
- Στη συνέχεια αρχικοποιούμε τη μονάδα οθόνης LCD σε λειτουργία 16Χ2 και προβάλλουμε το μήνυμα καλωσορίσματος και καθαρίζουμε μετά από πέντε δευτερόλεπτα.
lcd.begin (16,2); // Ενεργοποιήστε την οθόνη LCD lcd.setCursor (0,0); // Ορίζει τον κέρσορα στην πρώτη γραμμή του Display lcd.print ("Circuit Digest"); // Εκτυπώνει το CIRCUIT DIGEST σε LCD lcd.setCursor (0,1); // Ορίζει τον κέρσορα στη δεύτερη γραμμή του Display lcd.print ("I2C 2 ARDUINO"); // Εκτυπώνει το I2C ARDUINO σε καθυστέρηση LCD (5000). // Καθυστέρηση για 5 δευτερόλεπτα lcd.clear (); // Διαγράφει την οθόνη LCD
3. Σε κενό βρόχο ()
- Πρώτα πρέπει να λάβουμε δεδομένα από το Slave, ώστε να χρησιμοποιήσουμε το requestFrom () με τη διεύθυνση slave 8 και ζητάμε ένα byte
Wire.requestFrom (8,1);
Η ληφθείσα τιμή διαβάζεται χρησιμοποιώντας το Wire.read ()
byte MasterReceive = Wire.read ();
- Στη συνέχεια πρέπει να διαβάσουμε την αναλογική τιμή από το κύριο arduino POT που είναι προσαρτημένο στον ακροδέκτη A0
int potvalue = analogRead (A0);
Μετατρέπουμε αυτήν την τιμή σε όρους ενός byte από 0 σε 127.
byte MasterSend = χάρτης (αξία ποτ, 0,1023,0,127);
- Στη συνέχεια πρέπει να στείλουμε αυτές τις τιμές μετατροπής, ώστε να ξεκινήσουμε τη μετάδοση με το slave arduino με 8 διεύθυνση
Wire.begin Μετάδοση (8); Wire.write (MasterSend); Wire.endTransmission ();
- Στη συνέχεια προβάλλουμε αυτές τις ληφθείσες τιμές από το slave arduino με καθυστέρηση 500 μικροδευτερολέπτων και λαμβάνουμε και εμφανίζουμε συνεχώς αυτές τις τιμές.
lcd.setCursor (0,0); // Ορίζει το Currsor στη γραμμή 1 του LCD lcd.print (">> Master <<"); // Εκτυπώσεις >> Κύρια << στο LCD lcd.setCursor (0,1); // Ορίζει τον κέρσορα στη γραμμή δύο του LCD lcd.print ("SlaveVal:"); // Εκτυπώσεις SlaveVal: σε LCD lcd.print (MasterReceive); // Εκτυπώσεις MasterReceive σε LCD που ελήφθησαν από το Slave Serial.println ("Master Received From Slave"); // Εκτυπώσεις σε Serial Monitor Serial.println (MasterReceive); καθυστέρηση (500) lcd.clear ();
Επεξήγηση προγραμματισμού Slave Arduino
1. Ίδιο με το κύριο, πρώτα απ 'όλα πρέπει να συμπεριλάβουμε τη βιβλιοθήκη Wire για τη χρήση λειτουργιών επικοινωνίας I2C και τη βιβλιοθήκη LCD για τη χρήση λειτουργιών LCD. Ορίστε επίσης καρφίτσες LCD για LCD 16x2.
#περιλαμβάνω
2. Σε άκυρη ρύθμιση ()
- Ξεκινάμε τη σειριακή επικοινωνία στο Baud Rate 9600.
Serial.begin (9600);
- Στη συνέχεια ξεκινάμε την επικοινωνία I2C στο pin (A4, A5) με διεύθυνση slave ως 8. Εδώ είναι σημαντικό να προσδιορίσετε τη διεύθυνση slave.
Wire.begin (8);
Στη συνέχεια πρέπει να καλέσουμε τη συνάρτηση όταν ο Slave λαμβάνει τιμή από τον κύριο και όταν ο κύριος τιμή αιτήματος από τον Slave
Wire.onReceive (ReceiveEvent); Wire.onRequest (requestEvent);
- Στη συνέχεια αρχικοποιούμε τη μονάδα οθόνης LCD σε λειτουργία 16Χ2 και προβάλλουμε το μήνυμα καλωσορίσματος και καθαρίζουμε μετά από πέντε δευτερόλεπτα.
lcd.begin (16,2); // Ενεργοποιήστε την οθόνη LCD lcd.setCursor (0,0); // Ορίζει τον κέρσορα στην πρώτη γραμμή του Display lcd.print ("Circuit Digest"); // Εκτυπώνει το CIRCUIT DIGEST σε LCD lcd.setCursor (0,1); // Ορίζει τον κέρσορα στη δεύτερη γραμμή του Display lcd.print ("I2C 2 ARDUINO"); // Εκτυπώνει το I2C ARDUINO σε καθυστέρηση LCD (5000). // Καθυστέρηση για 5 δευτερόλεπτα lcd.clear (); // Διαγράφει την οθόνη LCD
3. Στη συνέχεια έχουμε δύο λειτουργίες μία για συμβάν αίτησης και μία για συμβάν λήψης
Για αίτημα Εκδήλωση
Όταν η κύρια τιμή του αιτήματος από το slave, αυτή η συνάρτηση θα εκτελεστεί. Αυτή η συνάρτηση παίρνει την τιμή εισόδου από το Slave POT και τη μετατρέπει σε όρους 7-bit και στέλνει αυτήν την τιμή στο master.
void requestEvent () { int potvalue = analogRead (A0); byte SlaveSend = χάρτης (αξία ποτ, 0,1023,0,127); Wire.write (SlaveSend); }
Για λήψη συμβάντος
Όταν ο Master στέλνει δεδομένα σε slave με διεύθυνση slave (8) αυτή η λειτουργία θα εκτελεστεί. Αυτή η συνάρτηση διαβάζει την ληφθείσα τιμή από τον κύριο και αποθηκεύει σε μια μεταβλητή τύπου byte .
void ReceEvent (int howMany { SlaveReceived = Wire.read (); })
4. Στο βρόχο Void ():
Εμφανίζουμε την ληφθείσα τιμή από τον κύριο συνεχώς στη μονάδα οθόνης LCD.
void loop (void) { lcd.setCursor (0,0); // Ορίζει το Currsor στη γραμμή 1 του LCD lcd.print (">> Slave <<"); // Εκτυπώσεις >> Slave << στο LCD lcd.setCursor (0,1); // Ορίζει τον κέρσορα στη γραμμή δύο του LCD lcd.print ("MasterVal:"); // Εκτυπώσεις MasterVal: σε LCD lcd.print (SlaveReceived); // Εκτυπώνει την τιμή SlaveReceived σε LCD που ελήφθη από το Master Serial.println ("Slave Received From Master:"); // Εκτυπώσεις στο Serial Monitor Serial.println (SlaveReceived); καθυστέρηση (500) lcd.clear (); }
Με την περιστροφή του ποτενσιόμετρου σε μία πλευρά, μπορείτε να δείτε τις διαφορετικές τιμές στην οθόνη LCD στην άλλη πλευρά:
Έτσι λοιπόν λαμβάνει χώρα η επικοινωνία I2C στο Arduino, εδώ έχουμε χρησιμοποιήσει δύο Arduinos για να δείξουμε όχι μόνο την αποστολή δεδομένων αλλά και τη λήψη των δεδομένων χρησιμοποιώντας την επικοινωνία I2C. Τώρα μπορείτε να συνδέσετε οποιονδήποτε αισθητήρα I2C με το Arduino.
Η πλήρης κωδικοποίηση για Master και Slave Arduino δίνεται παρακάτω με ένα βίντεο επίδειξης