- Hvad er I2C kommunikationsprotokol?
- Hvordan fungerer I2C-kommunikation?
- Hvor skal jeg bruge I2C-kommunikation?
- I2C i Arduino
- Komponenter, der kræves
- Kredsløbsdiagram
- Arbejdsforklaring
- I2C programmering i Arduino
- Master Arduino Programmering Forklaring
- Slave Arduino Programmering Forklaring
I vores tidligere tutorial lærte vi om SPI-kommunikation i Arduino. I dag lærer vi om en anden seriel kommunikationsprotokol: I2C (Inter Integrated Circuits). Sammenligning af I2C med SPI har I2C kun to ledninger, mens SPI bruger fire, og I2C kan have Multiple Master og Slave, mens SPI kun kan have en master og flere slaver. Så der er mere end en mikrocontroller i et projekt, der skal være mestre, så I2C bruges. I2C-kommunikation bruges generelt til at kommunikere med gyroskop, accelerometer, barometertrykfølere, LED-skærme osv.
I denne Arduino I2C-tutorial bruger vi I2C-kommunikation mellem to arduino-kort og sender (0 til 127) værdier til hinanden ved hjælp af potentiometer. Værdier vises på 16x2 LCD tilsluttet til hver af Arduino. Her vil en Arduino fungere som mester og en anden fungere som slave. Så lad os starte med introduktionen om I2C-kommunikation.
Hvad er I2C kommunikationsprotokol?
Udtrykket IIC står for " Inter Integrated Circuits ". Det betegnes normalt som I2C eller I kvadrat C eller endda som 2-leder interface-protokol (TWI) nogle steder, men det hele betyder det samme. I2C er en synkron kommunikationsprotokol, der betyder, at begge enheder, der deler informationen, skal dele et fælles ursignal. Den har kun to ledninger til at dele information, hvoraf den ene bruges til cocksignalet, og den anden bruges til at sende og modtage data.
Hvordan fungerer I2C-kommunikation?
I2C-kommunikation blev først introduceret af Phillips. Som sagt tidligere har den to ledninger, disse to ledninger forbindes på tværs af to enheder. Her kaldes en enhed en master, og den anden enhed kaldes slave. Kommunikation skal og vil altid forekomme mellem to en mester og en slave. Fordelen ved I2C-kommunikation er, at mere end en slave kan forbindes til en Master.
Den komplette kommunikation finder sted gennem disse to ledninger, nemlig Serial Clock (SCL) og Serial Data (SDA).
Serielt ur (SCL): Deler det ursignal, der genereres af masteren, med slaven
Serial Data (SDA): Sender dataene til og fra mellem Master og slave.
På ethvert givet tidspunkt er det kun mesteren, der er i stand til at starte kommunikationen. Da der er mere end en slave i bussen, skal mesteren henvise til hver slave ved hjælp af en anden adresse. Når kun slave med den pågældende adresse adresseres, svarer de tilbage med informationen, mens de andre holder op. På denne måde kan vi bruge den samme bus til at kommunikere med flere enheder.
De spændingsniveauer I2C er ikke prædefineret. I2C-kommunikation er fleksibel, betyder enheden, der får strøm fra 5V volt, kan bruge 5V til I2C, og 3.3V-enhederne kan bruge 3V til I2C-kommunikation. Men hvad hvis to enheder, der kører på forskellige spændinger, har brug for at kommunikere ved hjælp af I2C? En 5V I2C-bus kan ikke tilsluttes en 3.3V-enhed. I dette tilfælde bruges spændingsskiftere til at matche spændingsniveauerne mellem to I2C-busser.
Der er nogle sæt betingelser, der rammer en transaktion. Initialisering af transmission begynder med en faldende kant af SDA, der er defineret som 'START' -tilstand i nedenstående diagram, hvor master efterlader SCL høj, mens SDA laves.
Som vist i ovenstående diagram nedenfor, Den faldende kant af SDA er hardwaretriggeren til START-tilstanden. Herefter går alle enheder på den samme bus i lyttetilstand.
På samme måde stopper den stigende kant af SDA transmissionen, der er vist som 'STOP'-tilstand i ovenstående diagram, hvor masteren efterlader SCL høj og også frigiver SDA for at gå HØJ. Så stigende kant af SDA stopper transmissionen.
R / W-bit angiver transmissionsretningen for de følgende bytes, hvis den er HIGH betyder slaven at sende, og hvis den er lav, vil masteren sende.
Hver bit transmitteres på hver urcyklus, så det tager 8 urcykler at sende en byte. Efter hver byte, der er sendt eller modtaget, holdes den niende urcyklus for ACK / NACK (kvitteret / ikke kvitteret). Denne ACK-bit genereres af enten slave eller master afhængigt af situationen. For ACK-bit er SDA indstillet til lav af master eller slave ved 9. urcyklus. Så det er lavt, det betragtes som ACK ellers NACK.
Hvor skal jeg bruge I2C-kommunikation?
I2C-kommunikation bruges kun til kortdistancekommunikation. Det er bestemt pålideligt i et omfang, da det har en synkroniseret urpuls for at gøre det smart. Denne protokol bruges hovedsageligt til at kommunikere med sensorer eller andre enheder, der skal sende information til en master. Det er meget praktisk, når en mikrocontroller skal kommunikere med mange andre slave-moduler ved hjælp af et minimum af kun ledninger. Hvis du leder efter langkommunikation, skal du prøve RS232, og hvis du leder efter mere pålidelig kommunikation, skal du prøve SPI-protokollen.
I2C i Arduino
Billedet nedenfor viser I2C-stifterne til stede i Arduino UNO.
I2C Line | Pin i Arduino |
SDA | A4 |
SCL | A5 |
Før vi begynder at programmere I2C ved hjælp af to Arduino. Vi er nødt til at lære om Wire-biblioteket, der bruges i Arduino IDE.
den biblioteket
1. Wire.begin (adresse):
Anvendelse: Dette bibliotek bruges til kommunikation med I2C-enheder. Dette initier Wire-biblioteket, og slut dig til I2C-bussen som en master eller slave.
Adresse: 7-bit slave-adressen er valgfri, og hvis adressen ikke er angivet, slutter den sig til bussen som en master som denne.
2. Wire.read ():
Brug: Denne funktion bruges til at læse en byte, der blev modtaget fra master- eller slaveenhed, enten som blev transmitteret fra en slaveenhed til en masterenhed efter et opkald til anmodning fra () eller blev sendt fra en master til en slave.
3. Wire.write ():
Anvendelse: Denne funktion bruges til at skrive data til en slave eller masterenhed.
Slave to Master: Slave skriver data til en master, når Wire.RequestFrom () bruges i master.
Master til slave: Til transmission fra en master til slave-enhed bruges Wire.write () mellem opkald til Wire.beginTransmission () og Wire.endTransmission ().
Wire.write () kan skrives som:
- Wire.write (værdi)
værdi: en værdi, der skal sendes som en enkelt byte.
- Wire.write (streng):
streng: en streng, der skal sendes som en række bytes.
- Wire.write (data, længde):
data: en række data, der skal sendes som bytes
længde: antallet af bytes, der skal transmitteres.
4. Wire.beginTransmission (adresse):
Anvendelse: Denne funktion bruges til at starte en transmission til I2C-enheden med den givne slave-adresse. Derefter skal du oprette kø af bytes til transmission med funktionen skrive () og derefter sende dem ved at kalde endTransmission () -funktionen. Enhedens 7-bit-adresse transmitteres.
5. Wire.endTransmission ();
Anvendelse: Denne funktion bruges til at afslutte en transmission til en slaveenhed, der blev startet med beginTransmission () og transmitterer de byte, der blev sat i kø af Wire.write ().
6. Wire.onRequest ();
Brug: Denne funktion kaldes, når en master beder om data ved hjælp af Wire.requestFrom () fra slaveenheden. Her kan vi inkludere Wire.write () -funktionen til at sende data til masteren.
7. Wire.onReceive ();Brug: Denne funktion kaldes, når en slaveenhed modtager data fra en master. Her kan vi inkludere Wire.read (); funktion til at læse data sendt fra master.
8. Wire.requestFrom (adresse, mængde);
Anvendelse: Denne funktion bruges i masteren til at anmode om bytes fra en slaveenhed. Funktionen Wire.read () bruges til at læse de data, der sendes fra slaveenheden.
adresse: 7-bit-adressen på den enhed, som bytes fra
antal: antallet af bytes, der skal bestilles
Komponenter, der kræves
- Arduino Uno (2-Nos)
- 16X2 LCD display modul
- 10K potentiometer (4-Nos)
- Brødbræt
- Tilslutning af ledninger
Kredsløbsdiagram
Arbejdsforklaring
Her til demonstration af I2C-kommunikation i Arduino bruger vi To Arduino UNO med to 16X2 LCD-skærme fastgjort til hinanden og bruger to potentiometre på begge arduino til at bestemme sendeværdierne (0 til 127) fra master til slave og slave til master ved at variere potentiometer.
Vi tager input analog værdi ved arduino pin A0 fra (0 til 5V) ved hjælp af potentiometer og konverterer dem til Analog til Digital værdi (0 til 1023). Derefter konverteres disse ADC-værdier yderligere til (0 til 127), da vi kun kan sende 7-bit data gennem I2C-kommunikation. I2C-kommunikationen finder sted gennem to ledninger ved pin A4 og A5 på begge arduino.
Værdierne på Slave Arduinos LCD vil blive ændret ved at variere POT på mastersiden og omvendt.
I2C programmering i Arduino
Denne vejledning har to programmer, et til master Arduino og et andet til slave Arduino. Komplette programmer for begge sider gives i slutningen af dette projekt med en demonstrationsvideo.
Master Arduino Programmering Forklaring
1. Først og fremmest skal vi inkludere Wire-biblioteket til brug af I2C-kommunikationsfunktioner og LCD-bibliotek til brug af LCD-funktioner. Definer også LCD-ben til 16x2 LCD. Lær mere om grænseflade mellem LCD og Arduino her.
#omfatte
2. I ugyldig opsætning ()
- Vi starter seriel kommunikation med baudrate 9600.
Serial.begin (9600);
- Dernæst starter vi I2C-kommunikationen ved pin (A4, A5)
Wire.begin (); // Begynder I2C-kommunikation ved pin (A4, A5)
- Dernæst initialiserer vi LCD-displaymodul i 16X2-tilstand og viser velkomstmeddelelsen og rydder efter fem sekunder.
lcd.begin (16,2); // Initialize LCD display lcd.setCursor (0,0); // Indstiller markør på første linje i Display lcd.print ("Circuit Digest"); // Udskriver CIRCUIT DIGEST i LCD lcd.setCursor (0,1); // Indstiller markør på anden linje i Display lcd.print ("I2C 2 ARDUINO"); // udskriver I2C ARDUINO i LCD forsinkelse (5000); // Forsink i 5 sekunder lcd.clear (); // Rydder LCD-display
3. I ugyldig løkke ()
- Først skal vi hente data fra Slave, så vi bruger requestFrom () med slaveadressen 8, og vi anmoder om en byte
Wire.requestFrom (8,1);
Den modtagne værdi læses ved hjælp af Wire.read ()
byte MasterReceive = Wire.read ();
- Dernæst skal vi læse den analoge værdi fra master arduino POT, der er knyttet til pin A0
int potvalue = analogRead (A0);
Vi konverterer denne værdi i form af en byte som 0 til 127.
byte MasterSend = kort (potværdi, 0,1023,0,127);
- Dernæst skal vi sende de konverterede værdier, så vi begynder transmissionen med slave arduino med 8 adresse
Wire.beginTransmission (8); Wire.write (MasterSend); Wire.endTransmission ();
- Dernæst viser vi de modtagne værdier fra slave arduino med en forsinkelse på 500 mikrosekunder, og vi modtager og viser kontinuerligt disse værdier.
lcd.setCursor (0,0); // Indstiller markør på linje en i LCD lcd.print (">> Master <<"); // Udskriver >> Master << ved LCD lcd.setCursor (0,1); // Indstiller markør på linje to i LCD lcd.print ("SlaveVal:"); // Udskriver SlaveVal: i LCD lcd.print (MasterReceive); // Udskriver MasterReceive i LCD modtaget fra Slave Serial.println ("Master modtaget fra Slave"); // Udskriver i Serial Monitor Serial.println (MasterReceive); forsinkelse (500); lcd.clear ();
Slave Arduino Programmering Forklaring
1. Samme som master, først og fremmest skal vi inkludere Wire-biblioteket til brug af I2C-kommunikationsfunktioner og LCD-bibliotek til brug af LCD-funktioner. Definer også LCD-ben til 16x2 LCD.
#omfatte
2. I ugyldig opsætning ()
- Vi starter seriel kommunikation med baudrate 9600.
Serial.begin (9600);
- Dernæst starter vi I2C-kommunikationen ved pin (A4, A5) med slave-adresse som 8. Her er det vigtigt at specificere slave-adressen.
Wire.begin (8);
Dernæst skal vi kalde funktionen, når Slave modtager værdi fra master, og når Master anmoder værdi fra Slave
Wire.onReceive (receiveEvent); Wire.onRequest (requestEvent);
- Dernæst initialiserer vi LCD-displaymodul i 16X2-tilstand og viser velkomstmeddelelsen og rydder efter fem sekunder.
lcd.begin (16,2); // Initialize LCD display lcd.setCursor (0,0); // Indstiller markør på første linje i Display lcd.print ("Circuit Digest"); // Udskriver CIRCUIT DIGEST i LCD lcd.setCursor (0,1); // Indstiller markør på anden linje i Display lcd.print ("I2C 2 ARDUINO"); // udskriver I2C ARDUINO i LCD forsinkelse (5000); // Forsink i 5 sekunder lcd.clear (); // Rydder LCD-display
3. Dernæst har vi to funktioner, en til anmodningshændelse og en til at modtage begivenhed
For anmodning Begivenhed
Når Master anmodningsværdi fra slave udføres denne funktion. Denne funktion tager inputværdien fra Slave POT og konverterer den i form af 7-bit og sender denne værdi til master.
ugyldig requestEvent () { int potvalue = analogRead (A0); byte SlaveSend = kort (potværdi, 0,1023,0,127); Wire.write (SlaveSend); }
Til modtagelse af begivenhed
Når Master sender data til slave med slave-adresse (8), udføres denne funktion. Denne funktion læser den modtagne værdi fra master og gem i en variabel af typen byte .
ugyldigt modtageEvent (int howMany { SlaveReceived = Wire.read (); }
4. I ugyldig sløjfe ():
Vi viser kontinuerligt den modtagne værdi fra master i LCD-displaymodulet.
void loop (void) { lcd.setCursor (0,0); // Indstiller markør på linje en i LCD lcd.print (">> Slave <<"); // Udskriver >> Slave << ved LCD lcd.setCursor (0,1); // Indstiller markør på linje to i LCD lcd.print ("MasterVal:"); // Udskriver MasterVal: i LCD lcd.print (SlaveReceived); // Udskriver SlaveReceived værdi i LCD modtaget fra Master Serial.println ("Slave modtaget fra Master:"); // Udskriver i Serial Monitor Serial.println (SlaveReceived); forsinkelse (500); lcd.clear (); }
Ved at dreje potentiometeret på den ene side kan du se de forskellige værdier på LCD på en anden side:
Så det er sådan, I2C-kommunikation finder sted i Arduino, her har vi brugt to Arduinos til at demonstrere ikke kun afsendelse af data, men også modtagelse af data ved hjælp af I2C-kommunikation. Så nu kan du interface enhver I2C-sensor til Arduino.
Den komplette kodning for Master og Slave Arduino er angivet nedenfor med en demonstrationsvideo