- Hva er I2C kommunikasjonsprotokoll?
- Hvordan fungerer I2C-kommunikasjon?
- Hvor skal jeg bruke I2C-kommunikasjon?
- I2C i Arduino
- Komponenter kreves
- Kretsdiagram
- Arbeidsforklaring
- I2C programmering i Arduino
- Master Arduino Programmering Forklaring
- Slave Arduino Programmering Forklaring
I vår forrige veiledning lært om SPI-kommunikasjon i Arduino. I dag vil vi lære om en annen seriell kommunikasjonsprotokoll: I2C (Inter Integrated Circuits). Sammenligner I2C med SPI, har I2C bare to ledninger mens SPI bruker fire og I2C kan ha Multiple Master og Slave, mens SPI bare kan ha en master og flere slaver. Så det er mer enn en mikrokontroller i et prosjekt som trenger å være mestere, så brukes I2C. I2C-kommunikasjon brukes vanligvis til å kommunisere med gyroskop, akselerometer, barometertrykksensorer, LED-skjermer etc.
I denne Arduino I2C-opplæringen vil vi bruke I2C-kommunikasjon mellom to arduino-kort og sende (0 til 127) verdier til hverandre ved å bruke potensiometer. Verdiene vises på 16x2 LCD-en som er koblet til hver av Arduino-enhetene. Her vil en Arduino fungere som mester og en annen vil fungere som slave. Så la oss starte med introduksjonen om I2C-kommunikasjon.
Hva er I2C kommunikasjonsprotokoll?
Begrepet IIC står for " Inter Integrated Circuits ". Det er vanligvis betegnet som I2C eller jeg kvadratisk C eller til og med som 2-leder grensesnittprotokoll (TWI) noen steder, men alt betyr det samme. I2C er en synkron kommunikasjonsprotokoll som betyr at begge enhetene som deler informasjonen må dele et vanlig klokkesignal. Den har bare to ledninger for å dele informasjon hvorav den ene brukes til cocksignalet og den andre brukes til å sende og motta data.
Hvordan fungerer I2C-kommunikasjon?
I2C-kommunikasjon ble først introdusert av Phillips. Som sagt tidligere har den to ledninger, disse to ledningene vil være koblet på tvers av to enheter. Her kalles den ene enheten en mester og den andre enheten kalles slave. Kommunikasjon skal og vil alltid skje mellom to en mester og en slave. Fordelen med I2C-kommunikasjon er at mer enn en slave kan kobles til en Master.
Den komplette kommunikasjonen skjer gjennom disse to ledningene, nemlig Serial Clock (SCL) og Serial Data (SDA).
Serial Clock (SCL): Deler kloksignalet som genereres av mesteren med slaven
Serial Data (SDA): Sender dataene til og fra mellom Master og slave.
Til enhver tid er det bare mesteren som kan starte kommunikasjonen. Siden det er mer enn en slave i bussen, må mesteren henvise til hver slave ved hjelp av en annen adresse. Når bare slaven med den aktuelle adressen er adressert, vil svare tilbake med informasjonen mens de andre slutter. På denne måten kan vi bruke den samme bussen til å kommunisere med flere enheter.
De spenningsnivåer på I2C ikke er forhåndsdefinert. I2C-kommunikasjon er fleksibel, betyr at enheten som drives av 5v volt, kan bruke 5v for I2C og 3.3v-enhetene kan bruke 3v for I2C-kommunikasjon. Men hva om to enheter som kjører på forskjellige spenninger, trenger å kommunisere ved hjelp av I2C? En 5V I2C-buss kan ikke kobles til 3.3V-enheten. I dette tilfellet brukes spenningsskiftere til å matche spenningsnivåene mellom to I2C-busser.
Det er noen sett med betingelser som rammer en transaksjon. Initialisering av overføring begynner med en fallende kant av SDA, som er definert som 'START' -tilstand i diagrammet nedenfor der master forlater SCL høyt mens SDA er lavt.
Som vist i diagrammet ovenfor, Den fallende kanten av SDA er maskinvareutløseren for START-tilstanden. Etter dette går alle enheter på samme buss i lyttemodus.
På samme måte stopper stigende kant av SDA transmisjonen som er vist som 'STOPP' -tilstand i diagrammet ovenfor, der masteren forlater SCL høyt og også frigjør SDA for å gå HØY. Så stigende kant av SDA stopper overføringen.
R / W-bit indikerer overføringsretningen for følgende byte, hvis den er HØY betyr slaven at den vil sende, og hvis den er lav, vil mesteren sende.
Hver bit overføres på hver klokkesyklus, så det tar åtte klokkesykluser å overføre en byte. Etter hver byte som er sendt eller mottatt, holdes den niende klokkesyklusen for ACK / NACK (kvittert / ikke kvittert). Denne ACK-biten genereres av enten slave eller master, avhengig av situasjonen. For ACK kronen, SDA satt til lavt ved master- eller slave ved ni th klokkesyklus. Så det er lavt, det regnes som ACK ellers NACK.
Hvor skal jeg bruke I2C-kommunikasjon?
I2C-kommunikasjon brukes bare for kortdistansekommunikasjon. Det er absolutt pålitelig til en viss grad siden det har en synkronisert klokkepuls for å gjøre det smart. Denne protokollen brukes hovedsakelig til å kommunisere med sensor eller andre enheter som må sende informasjon til en master. Det er veldig praktisk når en mikrokontroller må kommunisere med mange andre slave-moduler ved å bruke minimum bare ledninger. Hvis du er ute etter kommunikasjon over lang rekkevidde, bør du prøve RS232, og hvis du leter etter mer pålitelig kommunikasjon, bør du prøve SPI-protokollen.
I2C i Arduino
Bildet nedenfor viser I2C-pinnene som er til stede i Arduino UNO.
I2C Line | Fest i Arduino |
SDA | A4 |
SCL | A5 |
Før vi begynner å programmere I2C ved hjelp av to Arduino. Vi må lære om Wire-biblioteket som brukes i Arduino IDE.
den bibliotek
1. Wire.begin (adresse):
Bruk: Dette biblioteket brukes til å lage kommunikasjon med I2C-enheter. Dette initier Wire-biblioteket og bli med på I2C-bussen som en mester eller slave.
Adresse: 7-bit slave-adressen er valgfri, og hvis adressen ikke er spesifisert, blir den med i bussen som en master som denne.
2. Wire.read ():
Bruk: Denne funksjonen brukes til å lese en byte som ble mottatt fra master- eller slaveenhet, enten som ble overført fra en slaveenhet til en masterenhet etter en samtale om å be om fra () eller ble overført fra en master til en slave.
3. Wire.write ():
Bruk: Denne funksjonen brukes til å skrive data til en slave eller masterenhet.
Slave to Master: Slave skriver data til en master når Wire.RequestFrom () brukes i master.
Master to Slave: For overføring fra en master til slave-enhet Wire.write () brukes mellom anrop til Wire.beginTransmission () og Wire.endTransmission ().
Wire.write () kan skrives som:
- Wire.write (verdi)
verdi: en verdi som skal sendes som en enkelt byte.
- Wire.write (streng):
streng: en streng som skal sendes som en byteserie.
- Wire.write (data, lengde):
data: en rekke data som skal sendes som byte
lengde: antall byte som skal overføres.
4. Wire.beginTransmission (adresse):
Bruk: Denne funksjonen brukes til å starte en overføring til I2C-enheten med den gitte slaveadressen. Bygg deretter kø med byte for overføring med skriv () -funksjonen, og send dem deretter ved å ringe endTransmission () -funksjonen. 7-biters adresse til enheten overføres.
5. Wire.endTransmission ();
Bruk: Denne funksjonen brukes til å avslutte en overføring til en slaveenhet som ble startet med beginTransmission () og overfører byte som ble satt i kø av Wire.write ().
6. Wire.onRequest ();
Bruk: Denne funksjonen blir ringt når en master ber om data ved hjelp av Wire.requestFrom () fra slaveenheten. Her kan vi inkludere Wire.write () -funksjonen for å sende data til mesteren.
7. Wire.onReceive ();Bruk: Denne funksjonen blir ringt når en slaveenhet mottar data fra en mester. Her kan vi inkludere Wire.read (); funksjon for å lese dataene som sendes fra master.
8. Wire.requestFrom (adresse, mengde);
Bruk: Denne funksjonen brukes i masteren for å be om byte fra en slaveenhet. Funksjonen Wire.read () brukes til å lese dataene som sendes fra slaveenheten.
adresse: 7-biters adressen til enheten du vil be om byte fra
antall: antall byte å be om
Komponenter kreves
- Arduino Uno (2-Nos)
- 16X2 LCD-skjermmodul
- 10K potensiometer (4-Nos)
- Brettbrett
- Koble ledninger
Kretsdiagram
Arbeidsforklaring
Her for å demonstrere I2C-kommunikasjon i Arduino bruker vi To Arduino UNO med to 16X2 LCD-skjerm festet til hverandre og bruker to potensiometre på begge arduino for å bestemme sendingsverdiene (0 til 127) fra master til slave og slave til master ved å variere potensiometer.
Vi tar inngangs analog verdi på arduino pin A0 fra (0 til 5V) ved å bruke potensiometer og konverterer dem til Analog til Digital verdi (0 til 1023). Deretter konverteres disse ADC-verdiene videre til (0 til 127), ettersom vi bare kan sende 7-biters data gjennom I2C-kommunikasjon. I2C-kommunikasjonen foregår gjennom to ledninger på pin A4 og A5 på begge arduino.
Verdiene på Slave Arduinos LCD vil endres ved å variere POTTEN på mastersiden og omvendt.
I2C programmering i Arduino
Denne opplæringen har to programmer, ett for master Arduino og et annet for slave Arduino. Komplette programmer for begge sider er gitt på slutten av dette prosjektet med en demonstrasjonsvideo.
Master Arduino Programmering Forklaring
1. Først og fremst må vi inkludere Wire-biblioteket for bruk av I2C-kommunikasjonsfunksjoner og LCD-bibliotek for bruk av LCD-funksjoner. Definer også LCD-pinner for 16x2 LCD. Lær mer om grensesnitt LCD med Arduino her.
#inkludere
2. I ugyldig oppsett ()
- Vi starter seriekommunikasjon med Baud Rate 9600.
Serial.begin (9600);
- Deretter starter vi I2C-kommunikasjonen på pin (A4, A5)
Wire.begin (); // Begynner I2C-kommunikasjon ved pin (A4, A5)
- Deretter initialiserer vi LCD-skjermmodulen i 16X2-modus og viser velkomstmeldingen og slettes etter fem sekunder.
lcd.begin (16,2); // Initialisere LCD-skjerm lcd.setCursor (0,0); // Setter markør på første linje i Display lcd.print ("Circuit Digest"); // skriver ut CIRCUIT DIGEST i LCD lcd.setCursor (0,1); // Setter markør på andre linje i Display lcd.print ("I2C 2 ARDUINO"); // Skriver ut I2C ARDUINO i LCD- forsinkelse (5000); // Forsink i 5 sekunder lcd.clear (); // Tømmer LCD-skjermen
3. I ugyldig sløyfe ()
- Først må vi få data fra Slave, så vi bruker requestFrom () med slaveadressen 8 og vi ber om en byte
Wire.requestFrom (8,1);
Den mottatte verdien leses ved hjelp av Wire.read ()
byte MasterReceive = Wire.read ();
- Deretter må vi lese den analoge verdien fra master arduino POT festet til pin A0
int potvalue = analogRead (A0);
Vi konverterer den verdien i form av en byte som 0 til 127.
byte MasterSend = kart (potensverdi, 0,1023,0,127);
- Deretter må vi sende de konverterte verdiene slik at vi begynner overføringen med slave arduino med 8 adresse
Wire.beginTransmission (8); Wire.write (MasterSend); Wire.endTransmission ();
- Deretter viser vi de mottatte verdiene fra slaven arduino med en forsinkelse på 500 mikrosekunder, og vi mottar og viser kontinuerlig disse verdiene.
lcd.setCursor (0,0); // Angir markør på linje en i LCD lcd.print (">> Master <<"); // Skriver ut >> Master << på LCD lcd.setCursor (0,1); // Setter markør på linje to i LCD lcd.print ("SlaveVal:"); // Skriver ut SlaveVal: i LCD lcd.print (MasterReceive); // Skriver ut MasterReceive i LCD mottatt fra Slave Serial.println ("Master mottatt fra slave"); // Skriver ut i Serial Monitor Serial.println (MasterReceive); forsinkelse (500); lcd.clear ();
Slave Arduino Programmering Forklaring
1. Samme som master, først og fremst trenger vi å inkludere Wire-biblioteket for bruk av I2C-kommunikasjonsfunksjoner og LCD-bibliotek for bruk av LCD-funksjoner. Definer også LCD-pinner for 16x2 LCD.
#inkludere
2. I ugyldig oppsett ()
- Vi starter seriekommunikasjon med Baud Rate 9600.
Serial.begin (9600);
- Deretter starter vi I2C-kommunikasjonen på pin (A4, A5) med slave-adresse som 8. Her er det viktig å spesifisere slave-adressen.
Wire.begin (8);
Deretter må vi ringe funksjonen når Slave mottar verdi fra master og når Master forespørsler om verdi fra Slave
Wire.onReceive (receiveEvent); Wire.onRequest (requestEvent);
- Deretter initialiserer vi LCD-skjermmodulen i 16X2-modus og viser velkomstmeldingen og slettes etter fem sekunder.
lcd.begin (16,2); // Initialisere LCD-skjerm lcd.setCursor (0,0); // Setter markør på første linje i Display lcd.print ("Circuit Digest"); // skriver ut CIRCUIT DIGEST i LCD lcd.setCursor (0,1); // Setter markør på andre linje i Display lcd.print ("I2C 2 ARDUINO"); // Skriver ut I2C ARDUINO i LCD- forsinkelse (5000); // Forsink i 5 sekunder lcd.clear (); // Tømmer LCD-skjermen
3. Neste har vi to funksjoner en for forespørselshendelse og en for motta hendelse
For anmodning Event
Når hovedforespørsel fra slave blir denne funksjonen utført. Denne funksjonen tar inngangsverdien fra Slave POT og konverterer den i form av 7-bit og sender den verdien til master.
ugyldig requestEvent () { int potvalue = analogRead (A0); byte SlaveSend = kart (potensverdi, 0,1023,0,127); Wire.write (SlaveSend); }
For motta hendelse
Når Master sender data til slave med slave-adresse (8) vil denne funksjonen bli utført. Denne funksjonen leser den mottatte verdien fra master og lagring i en variabel av typen byte .
ugyldig motta hendelse (int howMany { SlaveReceived = Wire.read (); }
4. I Void loop ():
Vi viser den mottatte verdien fra master kontinuerlig i LCD-skjermmodulen.
void loop (void) { lcd.setCursor (0,0); // Setter markør på linje en i LCD lcd.print (">> Slave <<"); // Skriver ut >> Slave << på LCD lcd.setCursor (0,1); // Setter markør på linje to i LCD lcd.print ("MasterVal:"); // Skriver ut MasterVal: i LCD lcd.print (SlaveReceived); // Skriver ut SlaveMottatt verdi i LCD mottatt fra Master Serial.println ("Slave mottatt fra Master:"); // Skriver ut i seriell skjerm Serial.println (SlaveReceived); forsinkelse (500); lcd.clear (); }
Ved å rotere potensiometeret på den ene siden, kan du se de forskjellige verdiene på LCD-skjermen på en annen side:
Så dette er hvordan I2C-kommunikasjon foregår i Arduino, her har vi brukt to Arduinos for å demonstrere ikke bare sending av data, men også mottak av data ved hjelp av I2C-kommunikasjon. Så nå kan du grense hvilken som helst I2C-sensor til Arduino.
Den komplette kodingen for Master og Slave Arduino er gitt nedenfor med en demonstrasjonsvideo