Arduino-gegevensuitwisseling via I2C-protocol. Laten we eens kijken naar de handigste communicatie die fysiek is ingebed in Arduino-controllers

Arduino ondersteunt veel interfaces voor gegevensoverdracht, waaronder I2C, die tegenwoordig behoorlijk populair is. Ooit is dit communicatieprotocol uitgevonden door Philips en geregistreerd onder de gepatenteerde naam “I2C”, je vindt het ook onder de namen TWI, 2 line interface, maar ze werken allemaal volgens hetzelfde principe.

Het hele punt van de I2C bus is dat je aan 2 draden een groot (128) aantal verschillende apparaten kunt hangen, van temperatuursensoren tot microcontrollers.

Maar tegelijkertijd is I2C qua snelheid inferieur aan UART en SPI, vanwege de basisprincipes van de werking, omdat twee lijnen zijn altijd verbonden met weerstanden (Vcc), wat betekent dat we in de grafiek geen rechthoekige pulsen krijgen, maar trapeziumvormige pulsen, in tegenstelling tot de bovenstaande.

SDA - verantwoordelijk voor het verzenden van informatie (begin van verzending, adres, gegevens)
SCL - busklokken

In I2C kunnen apparaten van twee typen zijn: Master en Slave

Laten we nu eens kijken naar de basisprincipes van programmeren met behulp van de standaard Wire.h-bibliotheek:

Wire.begin(uint8_t adres) - gebruikt om het apparaat te initialiseren, in de slave-modus moet u het adres invoeren, in de master-modus Wire.begin() . In plaats van Draad kunt u elk ander woord gebruiken.

Wire.requestFrom(uint8_t adres, uint8_t hoeveelheid) – een verzoek om een ​​bepaald aantal bytes te ontvangen van een specifiek apparaat (7-bits adres). Retourneert het aantal gelezen bytes.

Wire.beginTransmission(uint8_t adres) - begin van verzending

Wire.endTransmission() - einde van verzending, retourneert foutnummer of succes (0)

Wire.write(uint8_t data) – kan de waarde aannemen van een enkele byte (waarde), meerdere bytes (string), een array van een bepaalde lengte (data, lengte). Gelegen tussen: beginTransmission en endTransmission. Retourneert het aantal geschreven bytes.

Wire.available() – retourneert het aantal bytes dat beschikbaar is voor verwerking. Opgeroepen door de meester na requestFrom.

Wire.read() – leest een byte van het slave-apparaat. Het is geschreven na requestFrom.

Het verbinden van bibliotheken met de Arduino IDE is niet moeilijk, omdat deze wordt geleverd met een standaardeditor.

Er zijn nog een paar functies, maar ik denk dat deze basis voldoende is om te beginnen, en bovendien kun je voor bijna elk randapparaat een bibliotheek vinden.

Denk bijvoorbeeld aan de aansluiting en werking van de Gy-521 accelerometer en gyroscoop.

We verbinden volgens het diagram (pull-up-weerstanden zijn ingebouwd in de module):

De module kan zowel op 3,3 volt als op 5 volt werken.

#erbij betrekken // verbind de bibliotheek voor het werken met de i2c-interface const int MPU_addr = 0x68; // I2C-adres GY-521 int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ; // variabelen voor het schrijven van waarden void setup() ( Wire.begin(); // initialiseer de i2c-bus Wire.beginTransmission(MPU_addr); // start transmissie Wire.write(0x6B); // schrijf bepaalde registers om te initialiseren de Wire-module write(0); // stuur nul om de module uit de slaapstand te halen Wire.endTransmission(true); Serial.begin(9600); void loop() ( Wire.beginTransmission(MPU_addr); Wire.write(0x3B ); // begin met dit register Wire.endTransmission(false);<< 8 | Wire.read(); // 0x3B AcY = Wire.read() << 8 | Wire.read(); // 0x3D AcZ = Wire.read() << 8 | Wire.read(); // 0x3F Tmp = Wire.read() << 8 | Wire.read(); // 0x41 GyX = Wire.read() << 8 | Wire.read(); // 0x43 GyY = Wire.read() << 8 | Wire.read(); // 0x45 GyZ = Wire.read() << 8 | Wire.read(); // 0x47 Serial.print("AcX = "); Serial.print(AcX); // выводим данные в Serial Serial.print(" | AcY = "); Serial.print(AcY); Serial.print(" | AcZ = "); Serial.print(AcZ); Serial.print(" | Tmp = "); Serial.print(Tmp / 340.00 + 36.53); // выводим температуры по формуле Serial.print(" | GyX = "); Serial.print(GyX); Serial.print(" | GyY = "); Serial.print(GyY); Serial.print(" | GyZ = "); Serial.println(GyZ); delay(333); }

Het I2C-protocol voor gegevensuitwisseling is ooit ontwikkeld door Philips. De naam I2C komt van het Engelse Iner-IC control of anderszins inter-chip control, Inter-IC, IIC (I2C) is de naam van hetzelfde protocol.

Dit protocol of interface zorgt voor hoogwaardige ontvangst en overdracht van informatie (data) van verschillende apparaten. Zo kunt u bijvoorbeeld de temperatuur meten en tegelijkertijd een digitale potentiometer aansturen. Communicatie vindt plaats in software; het algoritme voor communicatie met de sensor via het I2C-protocol wordt in het Arduino-programma geschreven (schets).

Er zijn speciale adapters waarmee u andere apparaten kunt aansluiten. Met een adapter kunt u bijvoorbeeld een Arduino-display 1602 (16x2) LCD aansluiten met behulp van het i2c-protocol met behulp van twee draden. Op aanvraag LCD i2c is er veel informatie op internet te vinden, hier is een voorbeeld van hoe een adapter voor een beeldscherm er uit moet zien http://www.ebay.com/itm/310565362720

Bij het werken aan deze interface is het ene apparaat de master en het andere de slave. De master initieert de verzending en genereert de signalen die nodig zijn voor synchronisatie.

De slaaf is op zijn beurt afhankelijk van de meester en begint pas gegevens te verzenden nadat hij een opdracht van het meesterapparaat heeft ontvangen.

Een apparaat dat op de I2C-bus is aangesloten, heeft zijn eigen unieke adres. Op dit adres wordt het masterapparaat geadresseerd.

Een voorbeeld van het aansluiten van sensoren met behulp van het I2C-protocol

De verbinding gebeurt via twee draden: SCL – het kloksignaal of kloksignaal en SDA – het datasignaal. Tegelijkertijd kan een willekeurig aantal verschillende sensoren (slave-apparaten) met hun eigen unieke ID's op de I2C-bus worden aangesloten.

De kennismaking begint met een speciaal voor deze doeleinden geschreven bibliotheek, genaamd Wire. Voordat u met het werk begint, moet het in het project worden geïmporteerd; het heeft speciale commando's of methoden om met apparaten te "communiceren".

Om gegevens met apparaten uit te wisselen, moet u hun ID kennen. Verschillende apparaten kunnen verschillende adreslengtes (id) hebben van 8 of 7 bits. De Wire-bibliotheek gebruikt 7-bits adressering.

De slave-apparaten worden aangesloten op de pinnen op het Arduino-bord. Elke versie van Arduino heeft zijn eigen I2C-pinnen

  • UNO-A4(SDA), A5(SCL);
  • Mega-20(SDA), 21(SCL);
  • Leonardo-2(SDA), 3(SCL);
  • Verschuldigd - 20(SDA), 21(SCL),SDA1,SCL1;

Voorbeeldprogrammacode voor het besturen van een digitale potentiometer met behulp van de Wire-bibliotheek

Dit voorbeeld laat zien hoe u een specifieke weerstandswaarde in een digitale potentiometer kunt instellen met behulp van de Wire-bibliotheek. Het instellen van een specifieke waarde gebeurt met behulp van de val-variabele.

#erbij betrekken void setup() ( Wire.begin(); // join i2c bus (adres optioneel voor master) ) byte val = 0; void loop() ( Wire.beginTransmission(44); // verzenden naar apparaat #44 (0x2c) // apparaatadres is gespecificeerd in datasheet Wire.write(byte(0x00)); // verzendt instructiebyte Wire.write(val ); // verzendt potentiometerwaardebyte Wire.endTransmission(); laagste waarde) vertraging(500);

Video van I2C en Arduino werkend. Deel 1

LCD-scherm– een frequente gast in Arduino-projecten. Maar in complexe circuits kunnen we het probleem hebben van een gebrek aan Arduino-poorten vanwege de noodzaak om een ​​schild aan te sluiten dat heel veel pinnen heeft. De oplossing in deze situatie zou kunnen zijn I2C/IIC Een adapter die een bijna standaard Arduino 1602-schild met slechts 4 pinnen verbindt met Uno-, Nano- of Mega-borden. In dit artikel bekijken we hoe je een LCD-scherm met een I2C-interface kunt aansluiten, welke bibliotheken je kunt gebruiken, een korte voorbeeldschets schrijven en veelvoorkomende fouten bekijken.

Vloeibare kristallen weergave LCD-scherm 1602 is een goede keuze voor het uitvoeren van tekenreeksen in een verscheidenheid aan projecten. Het is goedkoop, er zijn verschillende aanpassingen met verschillende achtergrondverlichtingskleuren, je kunt eenvoudig kant-en-klare bibliotheken voor Arduino-schetsen downloaden. Maar het grootste nadeel van dit scherm is het feit dat het display 16 digitale pinnen heeft, waarvan er minstens 6 nodig zijn. Daarom brengt het gebruik van dit LCD-scherm zonder i2c serieuze beperkingen met zich mee voor Arduino Uno- of Nano-borden. Als er niet genoeg contacten zijn, dan zul je een Arduino Mega-bord moeten kopen of contacten moeten opslaan, onder meer door het display via i2c aan te sluiten.

Korte beschrijving van LCD 1602-pinnen

Laten we de LCD1602-pinnen eens nader bekijken:

Elk van de pinnen heeft zijn eigen doel:

  1. Aarde GND;
  2. Voeding 5 V;
  3. Monitorcontrast instellen;
  4. Commando, gegevens;
  5. Gegevens schrijven en lezen;
  6. Inschakelen;

7-14. Datalijnen;

  1. Plus achtergrondverlichting;
  2. Minus de achtergrondverlichting.

Schermspecificaties:

  • Karakterweergavetype, het is mogelijk om symbolen te laden;
  • LED-achtergrondverlichting;
  • Controller HD44780;
  • Voedingsspanning 5V;
  • Formaat 16x2 tekens;
  • Bedrijfstemperatuurbereik van -20C tot +70C, opslagtemperatuurbereik van -30C tot +80C;
  • Kijkhoek 180 graden.

Aansluitschema van LCD naar Arduino-bord zonder i2C

Het standaardschema voor het rechtstreeks aansluiten van een monitor op een Arduino-microcontroller zonder I2C is als volgt.

Vanwege het grote aantal aangesloten contacten is er mogelijk niet voldoende ruimte om de benodigde elementen aan te sluiten. Het gebruik van I2C vermindert het aantal draden tot 4 en bezette pinnen tot 2.

Waar i2c 1602-schermen voor Arduino te kopen

LCD-scherm 1602 is behoorlijk populair, dus je kunt het gemakkelijk vinden, zowel in binnenlandse online winkels als op buitenlandse sites. Hier zijn enkele links naar de meest beschikbare opties:

  • Een variant van een gewoon display van een redelijk bekende verkoper Wavgat voor een prijs onder de 100 roebel.
  • Set van scherm en i2c-adapter (deze moet je zelf solderen). Prijs – minder dan 200 roebel
  • i2c schermafscherming – LCD 1602-module met bedieningsknoppen en uitbreidingskaart.

Beschrijving van het I2C-protocol

Voordat we het hebben over het verbinden van het beeldscherm met Arduino via een i2c-adapter, willen we het eerst even hebben over het i2C-protocol zelf.

I2C/IIC(Inter-Integrated Circuit) is een protocol dat oorspronkelijk is gemaakt om geïntegreerde schakelingen binnen een elektronisch apparaat te communiceren. De ontwikkeling is van Philips. Het i2c-protocol is gebaseerd op het gebruik van een 8-bits bus, die nodig is om blokken in de besturingselektronica te communiceren, en een adresseringssysteem, waardoor je met meerdere apparaten over dezelfde draden kunt communiceren. We dragen eenvoudigweg gegevens over naar een of ander apparaat, waarbij we de identificatie van het gewenste element aan de datapakketten toevoegen.

Het eenvoudigste I2C-circuit kan één masterapparaat (meestal een Arduino-microcontroller) en meerdere slaves (bijvoorbeeld een LCD-scherm) bevatten. Elk apparaat heeft een adres in het bereik van 7 tot 127. Er mogen geen twee apparaten met hetzelfde adres in hetzelfde circuit zijn.

Het Arduino-bord ondersteunt i2c in hardware. U kunt pinnen A4 en A5 gebruiken om apparaten aan te sluiten die dit protocol gebruiken.

Er zijn verschillende voordelen aan I2C-werking:

  • Voor de bediening zijn slechts 2 lijnen nodig: SDA (datalijn) en SCL (synchronisatielijn).
  • Een groot aantal toonaangevende apparaten aansluiten.
  • Kortere ontwikkeltijd.
  • Er is slechts één microcontroller nodig om de hele set apparaten te besturen.
  • Het mogelijke aantal microcircuits dat op één bus is aangesloten, wordt alleen beperkt door de maximale capaciteit.
  • Hoge mate van gegevensbeveiliging dankzij een speciaal in de circuits ingebouwdr.
  • Een eenvoudige procedure voor het diagnosticeren van opkomende fouten en het snel opsporen van fouten.
  • De bus is al in de Arduino zelf geïntegreerd, waardoor er geen noodzaak is om een ​​extra businterface te ontwikkelen.

Gebreken:

  • Er is een capacitieve limiet op de lijn: 400 pF.
  • Moeilijk om een ​​I2C-controller te programmeren als er meerdere verschillende apparaten op de bus staan.
  • Met een groot aantal apparaten wordt het moeilijk om een ​​fout te isoleren als een van de apparaten per ongeluk laag wordt.

i2c-module voor LCD 1602 Arduino

De snelste en handigste manier om een ​​i2c-display in Arduino te gebruiken, is door een kant-en-klaar scherm met ingebouwde protocolondersteuning aan te schaffen. Maar er zijn niet heel veel van deze schermen en ze zijn niet goedkoop. Maar er zijn al een groot aantal verschillende standaardschermen geproduceerd. Daarom is de meest betaalbare en populaire optie van vandaag de aanschaf en het gebruik van een afzonderlijke I2C-module - een adapter, die er als volgt uitziet:

Aan de ene kant van de module zien we i2c-pinnen - aarde, voeding en 2 voor gegevensoverdracht. Op de andere adapter zien we externe stroomaansluitingen. En uiteraard beschikt het bord over veel pinnen waarmee de module aan de standaard schermpinnen wordt gesoldeerd.


i2c-uitgangen worden gebruikt om verbinding te maken met het Arduino-bord. Indien nodig sluiten we externe voeding aan voor achtergrondverlichting. Met de ingebouwde trimmer kunnen we contrastwaarden J op maat instellen

Op de markt zijn LCD 1602-modules te vinden met reeds gesoldeerde adapters; het gebruik ervan is zoveel mogelijk vereenvoudigd. Als u een aparte adapter heeft aangeschaft, moet u deze eerst aan de module solderen.

Het LCD-scherm verbinden met Arduino via I2C

Om verbinding te maken heb je het Arduino-bord zelf nodig, een display, een breadboard, aansluitdraden en een potentiometer.

Als u een speciale losse i2c-adapter gebruikt, moet u deze eerst aan de schermmodule solderen. Het is moeilijk om daar een fout te maken, je kunt dit schema volgen.


Een LCD-monitor met i2c-ondersteuning wordt met vier draden op het bord aangesloten: twee draden voor data en twee draden voor stroom.

  • De GND-pin wordt aangesloten op GND op het bord.
  • De VCC-pin staat op 5V.
  • SCL wordt aangesloten op pin A5.
  • SDA is verbonden met pin A.

En dat is alles! Geen web van draden, waar je gemakkelijk in verstrikt kunt raken. Tegelijkertijd kunnen we alle complexiteit van de implementatie van het i2C-protocol eenvoudigweg aan bibliotheken toevertrouwen.

Bibliotheken voor het werken met i2c LCD-scherm

Om via de I2C-bus met Arduino en LCD 1602 te communiceren, hebt u minimaal twee bibliotheken nodig:

  • De Wire.h-bibliotheek voor het werken met I2C is al opgenomen in het standaard Arduino IDE-programma.
  • De LiquidCrystal_I2C.h-bibliotheek, die een grote verscheidenheid aan opdrachten bevat voor het besturen van de monitor via de I2C-bus, waarmee u de schets eenvoudiger en korter kunt maken. U moet bovendien de bibliotheek installeren. Nadat u het beeldscherm hebt aangesloten, moet u bovendien de LiquidCrystal_I2C.h-bibliotheek installeren

Nadat we alle benodigde bibliotheken aan de schets hebben gekoppeld, creëren we een object en kunnen we al zijn functies gebruiken. Laten we voor het testen de volgende standaardvoorbeeldschets laden.

#erbij betrekken #erbij betrekken // Inclusief de bibliotheek //#include // Een alternatieve bibliotheek aansluiten LiquidCrystal_I2C lcd(0x27,16,2); // Specificeer het I2C-adres (de meest voorkomende waarde), evenals schermparameters (in het geval van LCD 1602 - 2 regels van elk 16 tekens //LiquidCrystal_PCF8574 lcd(0x27); // Optie voor de PCF8574-bibliotheek void setup( ) ( lcd.init (); // Initialiseer het scherm lcd.backlight(); // Verbind de achtergrondverlichting lcd.setCursor(0,0); // Zet de cursor op het begin van de eerste regel lcd.print(" Hallo"); lcd.setCursor(0,1); // Zet de cursor op het begin van de tweede regel lcd.print("ArduinoMaster"); // Typ tekst op de tweede regel ) void loop() ( )

Beschrijving van functies en methoden van de LiquidCrystal_I2C-bibliotheek:

  • home() en clear() - met de eerste functie kunt u de cursor terugbrengen naar het begin van het scherm, de tweede doet hetzelfde, maar verwijdert tegelijkertijd alles wat eerder op de monitor stond.
  • write(ch) – hiermee kunt u een enkel teken ch op het scherm afdrukken.
  • cursor() en noCursor() – toont/verbergt de cursor op het scherm.
  • blink() en noBlink() – de cursor knippert/knippert niet (als de weergave ervan eerder was ingeschakeld).
  • display() en noDisplay() – hiermee kunt u het beeldscherm aansluiten/uitschakelen.
  • scrollDisplayLeft() en scrollDisplayRight() – schuift het scherm één teken naar links/rechts.
  • autoscroll() en noAutoscroll() – hiermee kunt u de autoscroll-modus in-/uitschakelen. In deze modus wordt elk nieuw personage op dezelfde plaats geschreven, waardoor wat eerder op het scherm werd geschreven, wordt vervangen.
  • leftToRight() en rightToLeft() – De richting van de weergegeven tekst instellen – van links naar rechts of van rechts naar links.
  • createChar(ch, bitmap) – creëert een teken met code ch (0 – 7), met behulp van een reeks bitmap-bitmaps om zwart-witte punten te creëren.

Alternatieve bibliotheek voor het werken met i2c-display

In sommige gevallen kunnen er fouten optreden bij het gebruik van de opgegeven bibliotheek met apparaten die zijn uitgerust met PCF8574-controllers. In dit geval kan de bibliotheek LiquidCrystal_PCF8574.h als alternatief worden voorgesteld. Het breidt LiquidCrystal_I2C uit, dus er zouden geen problemen moeten zijn bij het gebruik ervan.

Problemen met het verbinden van het i2c lcd-scherm

Als u na het uploaden van de schets geen bericht op het display ziet, probeert u de volgende stappen.

Ten eerste kunt u het contrast van de monitor verhogen of verlagen. Vaak zijn karakters simpelweg niet zichtbaar vanwege het contrast en de achtergrondverlichting.

Als dit niet helpt, controleer dan of de contacten correct zijn aangesloten en of de achtergrondverlichting is aangesloten. Als je een aparte i2c-adapter hebt gebruikt, controleer dan nogmaals de kwaliteit van het solderen van de contacten.

Een andere veel voorkomende reden voor ontbrekende tekst op het scherm kan een onjuist i2c-adres zijn. Probeer eerst het apparaatadres in de schets te wijzigen van 0x27 0x20 of naar 0x3F. Verschillende fabrikanten kunnen verschillende standaardadressen hebben geprogrammeerd. Als dit niet helpt, kunt u de i2c-scannerschets uitvoeren, die alle aangesloten apparaten scant en met brute kracht hun adres bepaalt. Een voorbeeld van een i2c-scannerschets.

Als het scherm nog steeds niet werkt, probeer dan de adapter los te maken en het LCD-scherm zoals gewoonlijk aan te sluiten.

Conclusie

In dit artikel hebben we gekeken naar de belangrijkste problemen bij het gebruik van een LCD-scherm in complexe Arduino-projecten, waarbij we vrije pinnen op het bord moeten opslaan. Met een eenvoudige en goedkope i2c-adapter kunt u een 1602 LCD-scherm aansluiten, dat slechts 2 analoge pinnen in beslag neemt. In veel situaties kan dit erg belangrijk zijn. De prijs voor het gemak is de noodzaak om een ​​extra module te gebruiken: een converter en een bibliotheek. Naar onze mening is dit geen hoge prijs voor het gemak en we raden u ten zeerste aan deze functie in projecten te gebruiken.

I2C is een seriële asymmetrische bus voor communicatie tussen geïntegreerde schakelingen in elektronische apparaten. Dat wil zeggen dat dit communicatieprotocol is ontwikkeld voor interne communicatie in de apparaatkast of in het schakelbord. Het was niet belast met het verzenden van gegevens over lange afstanden, dus er zijn veel mythen over het maximale communicatiebereik - voor sommigen werkt het zelfs op 50 cm slecht, voor anderen op 2 meter.

De I2C-bus biedt plaats aan maximaal 128 apparaten. Adressen van 0 tot 127.

Arduino-controllers beschikken over fysieke I2C-communicatie, waarmee u via twee informatiedraden verschillende sensoren, discrete input-output-expanders, digitaal-naar-analoog en analoog-naar-digitaal converters en andere controllers kunt aansluiten.

Er is geen informatie over de transmissiesnelheid op de website van de fabrikant. Maar volgens de algemene documentatie voor het protocol zou deze minimaal 100 kbit/s moeten zijn


Nu zou ik graag willen testen hoe goed de I2C-bus werkelijk is, en hoe moeilijk het is om gegevens uit te wisselen tussen verschillende Arduino-controllers die er gebruik van maken

Ik neem drie controllers, verbind ze met een I2C-bus en zoek uit hoe ik daar gegevens over kan uitwisselen. De eerste controller fungeert als master en de overige twee als slave.

Om de gegevens weer te geven, gebruik ik een 1602 LCD-indicator met een I2C-module, die op dezelfde communicatiebus wordt aangesloten.

De mastercontroller zal achtereenvolgens de tweede en derde controllers pollen. De eerste controller moet de ontvangen gegevens op de indicator weergeven. De Arduino Nano-slaves worden gepolled met een frequentie van 1 keer/sec.

Aansluitschema

Vier draden van elk van de 4 apparaten moeten parallel worden aangesloten. Pin A4 van het Arduino Nano-bord is de SDA-bus van het I2C-protocol en A5 is SCL.

Ik zal montageschilden voor Nano-controllers gebruiken voor eenvoudige verbindingen.

Via een mini-USB-ingang wordt eenvoudig stroom aan een van de controllers geleverd.

Het LCD-scherm heeft een standaardadres in het I2C-netwerk van 27. Voor de tweede controller stellen we het adres in op 2 en voor de derde op 3. Het adres van de leidende eerste controller is niet nodig.

Het controllerprogramma is een master.

#erbij betrekken #erbij betrekken // Stel het LCD-adres in op 0x27 voor een weergave van 16 tekens en 2 regels LiquidCrystal_I2C lcd (0x27, 16, 2); int nano1=0; int nano2; int nano3; void setup() ( Serial.begin(9600); // initialiseer het LCD-scherm lcd.begin(); // Schakel het blacklight in en druk een bericht af. lcd.backlight(); ) void loop() ( lcd.setCursor( 0, 0); lcd.print(nano1); Wire.requestFrom(2, 2); // verzoek 6 bytes van slave-apparaat #8 int i=0;nano2=0; / slave verzendt mogelijk minder dan gevraagde byte c = Wire.read(); ontvang een byte als teken Serial.print(c);<< 8); else nano2 = nano2 | c; i++; } Serial.println(""); Serial.println(nano2); lcd.setCursor(9, 0); lcd.print(nano2); delay(100); Wire.requestFrom(3, 2); // request 6 bytes from slave device #8 i=0;nano3=0; while (Wire.available()) { // slave may send less than requested byte c = Wire.read(); // receive a byte as character Serial.print(c); if (i==0) nano3 = ((c & 0xff) << 8); else nano3 = nano3 | c; i++; } lcd.setCursor(0, 1); lcd.print(nano3); delay(100); nano1++; delay(800); }

De eerste controller verandert zijn geheeltallige variabele en geeft de waarde ervan weer op de indicator. Het ondervraagt ​​ook beurtelings de slaaf met het tweede en derde adres. Vraagt ​​twee bytes aan informatie van hen op en converteert deze naar een geheel getalvariabele. Hierdoor roteert de eerste controller drie variabelen uit drie Nano’s en kan deze op de indicator weergeven.

Tweede controllerprogramma

#erbij betrekken int nano2=0; byte hoog; void setup() ( Wire.begin(2); // sluit je aan bij i2c-bus met adres #8 Wire.onRequest(requestEvent); // registreer gebeurtenis) void loop() ( delay(1000); nano2--; ) // functie die wordt uitgevoerd wanneer gegevens worden opgevraagd door master // deze functie wordt geregistreerd als een gebeurtenis, zie setup() void requestEvent() ( high = (nano2 >>

Derde Arduino Nano-programma

#erbij betrekken int nano2=0; byte hoog; void setup() ( Wire.begin(3); // sluit je aan bij i2c-bus met adres #8 Wire.onRequest(requestEvent); // registreer gebeurtenis) void loop() ( delay(1500); nano2--; ) // functie die wordt uitgevoerd wanneer gegevens worden opgevraagd door master // deze functie wordt geregistreerd als een gebeurtenis, zie setup() void requestEvent() ( high = (nano2 >> 8); high = (nano2 & 0xff); Wire.write(high ); // reageer met een bericht van 2 bytes Wire.write(high);

De laatste twee programma's verschillen eenvoudigweg in het adres in de functie Wire.begin(3); en de frequentie van verandering van de variabele.

Deze programma's veranderen voortdurend de integer-variabele en wachten op een verzoek van de master. Op verzoek wordt deze variabele ontleed in twee bytes en als antwoord op het verzoek naar de mastercontroller gestuurd.

Zo kan de werking van I2C-communicatie worden gecontroleerd door de veranderende waarden van drie variabelen op het LCD-scherm.

Conclusies

Alles werkt prima - de cijfers op het display veranderen. Ik heb geprobeerd de kabelkabel tussen de tweede en derde Arduino-controller te verlengen. Ik controleerde de werking van de communicatiebus met een lengte van 3 m - geen klachten. Ik heb geen langere geprobeerd, maar velen vertelden me dat I2C niet verder werkt dan 0,5 ... 2 m en ik werd geïnspireerd door de lengte van 3 m.

Voor mezelf kan ik al kijken waar ik zo’n verbinding tussen de drie Nano’s ga gebruiken.

Ik heb nog niet geprobeerd gegevens van de master naar de slave over te dragen. Als je het probeert, meld je dan aan.

De nadelen hier op korte afstanden zijn aanzienlijk minder dan de voordelen.

Met vermogens van 10 Ohm tot 1 MOhm);

  • 2 weerstanden van 4,7 kOhm (uit dezelfde set);
  • aansluitdraden (hier is bijvoorbeeld een goede set);
  • computer met Arduino-IDE.
  • 1 Beschrijving I2C-interface

    Seriële IIC (ook wel I2C genoemd - Inter-Integrated Circuits) maakt gebruik van twee bidirectionele communicatielijnen, de seriële databus genaamd, om gegevens te verzenden. SDA (seriële gegevens) en klokbus SCL (seriële klok). Er zijn ook twee elektriciteitsleidingen. De SDA- en SCL-bussen worden via weerstanden naar de voedingsbus getrokken.

    Er staat er minstens één online meester-apparaat, dat de gegevensoverdracht initieert en synchronisatiesignalen genereert. Het netwerk heeft dat ook slaaf apparaten, die gegevens verzenden op verzoek van de leider. Elk slave-apparaat heeft een uniek adres, dat door de master wordt gebruikt om er toegang toe te krijgen. Het apparaatadres staat vermeld in het gegevensblad. Er kunnen maximaal 127 apparaten, waaronder meerdere masters, op één I2C-bus worden aangesloten. Apparaten kunnen tijdens bedrijf op de bus worden aangesloten, d.w.z. het ondersteunt hot-plugging.

    Laten we eens kijken naar het timingdiagram van de uitwisseling via het I2C-protocol. Er zijn verschillende opties, laten we eens kijken naar een van de meest voorkomende. Laten we een logische analysator gebruiken die is aangesloten op de SCL- en SDA-bussen.

    De master initieert de uitwisseling. Om dit te doen, begint het klokpulsen te genereren en stuurt deze langs de SCL-lijn in een pakket van 9 stuks. Tegelijkertijd wordt het op de SDA-datalijn ingesteld apparaat adres, waarmee het nodig is om communicatie tot stand te brengen, die wordt geklokt door de eerste 7 klokpulsen (vandaar de beperking van het adresbereik: 2 7 = 128 minus nul adres). Het volgende deel van de boodschap is operatiecode(lezen of schrijven) en nog een beetje - erkenning stukje(ACK) dat het slave-apparaat het verzoek heeft geaccepteerd. Als het bevestigingsbit niet arriveert, eindigt de uitwisseling. Of de meester blijft herhaalde verzoeken sturen.

    Dit wordt geïllustreerd in de onderstaande afbeelding. In het eerste geval ontkoppelen we bijvoorbeeld het slave-apparaat van de bus. Te zien is dat de master probeert communicatie tot stand te brengen met het apparaat met adres 0x27, maar geen bevestiging ontvangt (NAK). De uitwisseling eindigt.


    Sluit nu het slave-apparaat aan op de I2C-bus en herhaal de handeling. De situatie is veranderd. Het eerste pakket met het adres ontving een bevestiging (ACK) van de slaaf. De uitwisseling ging door. Informatie wordt ook verzonden in pakketten van 9 bits, maar nu zijn 8 bits bezet gegevens en 1 beetje - erkenning stukje de slaaf ontvangt elke byte aan gegevens. Als op enig moment de verbinding wordt verbroken en het bevestigingsbit niet aankomt, stopt de master met zenden.

    2 I2C-implementatie in Arduino

    Arduino gebruikt twee poorten om via de I2C-interface te werken. In Arduino UNO en Arduino Nano komt de analoge poort A4 bijvoorbeeld overeen met SDA en komt de analoge poort A5 overeen met SCL.


    Voor andere bordmodellen is de pincorrespondentie als volgt:

    3 Bibliotheek "Draad" voor het werken met IIC

    Om de gegevensuitwisseling met apparaten via de I2C-bus te vergemakkelijken, is voor Arduino een standaardbibliotheek geschreven Draad. Het heeft de volgende functies:

    FunctieDoel
    begin(adres) het initialiseren van de bibliotheek en het verbinden met de I2C-bus; als het adres niet is opgegeven, wordt het aangesloten apparaat als de master beschouwd; Er wordt gebruik gemaakt van 7-bits adressering;
    verzoekVan() gebruikt door de master om een ​​bepaald aantal bytes op te vragen bij de slave;
    beginVerzending(adres) start van gegevensoverdracht naar het slaafapparaat op een specifiek adres;
    eindTransmissie() het stoppen van de gegevensoverdracht naar de slaaf;
    schrijven() het vastleggen van gegevens van de slaaf als reactie op een verzoek;
    beschikbaar() retourneert het aantal bytes aan informatie dat beschikbaar is om van de slaaf te ontvangen;
    lezen() het lezen van een byte die is verzonden van een slaaf naar een meester of van een meester naar een slaaf;
    opOntvangen() geeft een functie aan die moet worden aangeroepen wanneer de slaaf een transmissie van de meester ontvangt;
    op aanvraag() geeft een functie aan die moet worden aangeroepen als de master een transmissie van de slave ontvangt.

    4 Een I2C-apparaat aansluiten naar Arduino

    Laten we eens kijken hoe we met de I2C-bus kunnen werken met behulp van Arduino.

    Laten we eerst een circuit samenstellen, zoals in de figuur. De helderheid van de LED regelen we met behulp van een digitale 64-standen potentiometer AD5171 (zie technische beschrijving), die is aangesloten op de I2C-bus. Het adres waarop we toegang krijgen tot de potentiometer is 0x2c (44 in decimalen).


    5 Apparaatbeheer via IIC-bus

    Laten we eens kijken naar de diagrammen van informatie-uitwisseling met de AD5171 digitale potentiometer, gepresenteerd in de technische beschrijving:


    We zijn geïnteresseerd in het diagram van het schrijven van gegevens naar het register RDAC. Dit register wordt gebruikt om de weerstand van de potentiometer te regelen.

    Laten we een schets openen uit de voorbeelden van de "Wire" -bibliotheek: Bestandsvoorbeelden Bedrading digitale_potentiometer. Laten we het in het Arduino-geheugen laden.

    #erbij betrekken // verbind de "Wire" bibliotheek byte val = 0; // waarde om over te dragen naar potentiometer ongeldige setup() ( Draad.begin(); // maak verbinding met de I2C-bus als master } lege lus() ( Wire.beginTransmission(44); // start de uitwisseling met een apparaat met I2C-adres "44" (0x2C) Wire.write(byte(0x00)); // stuur een schrijfinstructie naar het RDAC-register Wire.write(val); // stel de positie in van de potentiometer met 64 posities Wire.endTransmission(); // volledige I2C-overdrachtval++; // verhoog de waarde met 1 if (val == 63) ( // wanneer de potentiometer zijn maximale waarde = 0 bereikt; // reset val ) delay(500); }

    Na het inschakelen zie je hoe de helderheid van de LED cyclisch toeneemt en vervolgens uitgaat. In dit geval sturen we de potentiometer aan met behulp van Arduino via de I2C-bus.