Twee Arduino-borden verbinden met I2C

Twee Arduino-borden verbinden met I2C
Lezers zoals jij steunen MUO. Wanneer u een aankoop doet via links op onze site, kunnen we een aangesloten commissie verdienen. Lees verder.

Hoewel een enkele Arduino veel taken kan uitvoeren, kunnen sommige projecten het gebruik van meer dan één bord vereisen om verschillende functionaliteiten aan te kunnen. Om gegevensoverdracht tussen de twee microcontrollers mogelijk te maken, moet dus een communicatieprotocol zoals CAN, SPI, I2C of UART worden ingesteld.





In deze gids behandelen we de basisprincipes van hoe I2C werkt, de hardwareverbindingen en de software-implementatie die nodig is om twee Arduino-kaarten in te stellen als I2C-master- en slave-apparaten.





MAAK GEBRUIK VAN DE VIDEO VAN DE DAG SCROLL OM DOOR TE GAAN MET INHOUD

Wat is I2C?

Inter-Integrated Circuit (I2C) is een veelgebruikt communicatieprotocol in ingebedde systemen en microcontrollers om gegevensoverdracht tussen elektronische apparaten mogelijk te maken. In tegenstelling tot SPI (Serial Peripheral Interface), kunt u met I2C meer dan één master-apparaat aansluiten op een bus met enkele of meerdere slave-apparaten. Het werd voor het eerst gebruikt door Philips en staat ook bekend als het Two Wire Interface (TWI) communicatieprotocol.





magische muis 2 versus magische trackpad 2

Hoe werkt I2C-communicatie?

I2C gebruikt twee bidirectionele lijnen: Serial Data (SDA) en Serial Clock (SCL) om gegevens over te dragen en de communicatie tussen apparaten te synchroniseren. Elk apparaat dat op de I2C-bus is aangesloten, heeft een uniek adres dat het tijdens de communicatie identificeert. Dankzij het I2C-protocol kunnen meerdere apparaten dezelfde bus delen en elk apparaat kan als master of als slave fungeren.

  Demonstratie van I2C-communicatie

De communicatie wordt geïnitieerd door het masterapparaat en onjuiste adressering van slaveapparaten kan overdrachtsfouten veroorzaken. Bekijk onze uitgebreide gids op hoe UART, SPI en I2C seriële communicatie werken om je wat context te geven.



Een belangrijk voordeel van I2C-communicatie dat het vermelden waard is, is de flexibiliteit die het biedt als het gaat om energiebeheer. Apparaten die op verschillende spanningsniveaus werken, kunnen nog steeds effectief communiceren met behulp van spanningsverschuivers. Dit betekent dat apparaten die werken op 3,3V spanningsverschuivers nodig hebben om verbinding te maken met een 5V I2C-bus.

De draadbibliotheek

De Wire-bibliotheek is een ingebouwde Arduino-bibliotheek die functies biedt om via I2C te communiceren. Het gebruikt twee pinnen - SDA en SCL - op het Arduino-bord voor I2C-communicatie.





I2C-pinnen op de Arduino Uno:

  Arduino I2C Uno-pinnen

Arduino Nano I2C-pinnen:





  Arduino nano I2C pinout

Om de bibliotheek te gebruiken, moet u de Draad.h header-bestand aan het begin van uw Arduino-schets.

 #include <Wire.h>

De Wire-bibliotheek biedt functies om communicatie met een I2C-apparaat te initiëren, gegevens te verzenden en gegevens te ontvangen. Enkele belangrijke functies die u moet kennen, zijn:

  • Draad.begin() : gebruikt om lid te worden van de I2C-bus en communicatie te initiëren.
  • Wire.beginTransmission() : wordt gebruikt om het slave-adres op te geven en een verzending te starten.
  • Draad.schrijven() : gebruikt om gegevens naar het I2C-apparaat te sturen.
  • Wire.endTransmission() : wordt gebruikt om de verzending te beëindigen en op fouten te controleren.
  • Wire.requestFrom() : gebruikt om gegevens van het I2C-apparaat op te vragen.
  • Draad.beschikbaar() : gebruikt om te controleren of er gegevens beschikbaar zijn om te lezen van het I2C-apparaat.
  • draad.lezen() : gebruikt om gegevens van het I2C-apparaat te lezen.

Gebruik de Wire.beginTransmission() functie om het adres van de sensor in te stellen, dat als argument wordt ingevoegd. Als het adres van de sensor bijvoorbeeld is 0x68 , zou je gebruiken:

 Wire.beginTransmission(0x68);

Arduino I2C hardware-installatie

Om twee Arduino-kaarten met I2C te verbinden, hebt u de volgende hardwarecomponenten nodig:

  • Twee Arduino-kaarten (master en slave)
  • Broodplank
  • Jumper draden
  • Twee pull-up weerstanden van 4,7 kΩ

Verbind de SDA En SCL pinnen van beide Arduino-boards op een breadboard. Sluit de pull-up weerstanden tussen de SDA En SCL pinnen en de 5V stroomrail op het breadboard. Verbind ten slotte de twee breadboards met behulp van hulpdraden.

Arduino Uno-circuit

hoe een externe harde schijf op pc te openen
  Arduino_I2C-verbinding op een breadboard

Arduino Nano-circuit

  nano33BS_06_illustration voor I2C-communicatieprotocol
Afbeelding tegoed: Arduino I2C-documentatie

De Arduino-kaarten instellen als I2C Master- en Slave-apparaten

Gebruik de Wire.requestFrom() functie om het adres op te geven van het slave-apparaat waarmee we willen communiceren. Gebruik dan de draad.lezen() functie om gegevens van het slaafapparaat te krijgen.

Master-apparaatcode:

 #include <Wire.h> 
void setup() {
Wire.begin(); // join i2c bus
Serial.begin(9600); // start serial for output
}
void receiveData() {
int address = 8;
int bytesToRead = 6;
Wire.requestFrom(address, bytesToRead);
while (Wire.available()) {
char data = Wire.read();
Serial.print(data);
}
delay(500);
}
void loop() {
receiveData();
}

De Wire.onReceive() functie wordt gebruikt om aan te geven wat er moet gebeuren als de slave gegevens ontvangt van het masterapparaat. In de bovenstaande code is de Draad.beschikbaar() functie controleert of gegevens beschikbaar zijn, en de draad.lezen() functie leest de gegevens die door het masterapparaat zijn verzonden.

Slave-apparaatcode:

 #include <Wire.h> 
void setup() {
Wire.begin(8); // join the I2C bus with address 8
Wire.onReceive(receiveEvent); // call receiveEvent when data is received
}
void loop() {
delay(100);
}
void receiveEvent(int bytes) {
Wire.write("hello "); // respond with message of 6 bytes as expected by master
}

Gegevens verzenden en ontvangen met I2C

Laten we in dit voorbeeld de temperatuur lezen van een DHT11-temperatuursensor die is gekoppeld aan de slave-Arduino en deze afdrukken op de seriële monitor van de master-Arduino.

  DHT11 I2C voorbeeld met 2 Arduino boards

Laten we de code die we eerder hebben geschreven aanpassen om de temperatuurmeting op te nemen die we vervolgens via de I2C-bus naar het masterboard sturen. Het hoofdbord kan dan de verzonden waarde lezen en deze vervolgens weergeven op de seriële monitor.

Master-apparaatcode:

 #include <Wire.h> 
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("Master Initialized!");
}
void loop() {
Wire.requestFrom(8, 1); // Request temperature data from slave
if (Wire.available()) {
byte temperature = Wire.read(); // Read temperature data from slave
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" &deg;C");
}
delay(2000); // Wait for 2 seconds before requesting temperature again
}

Slave-apparaatcode:

 #include <Wire.h> 
#include <DHT.h>

#define DHTPIN 4 // Pin connected to DHT sensor
#define DHTTYPE DHT11 // DHT sensor type
DHT dht(DHTPIN, DHTTYPE);
byte temperature;

void setup() {
Wire.begin(8); // Slave address is 8
Wire.onRequest(requestEvent);
dht.begin();
}

void loop() {
delay(2000); // Wait for 2 seconds for DHT to stabilize
temperature = dht.readTemperature(); // Read temperature from DHT sensor
}

void requestEvent() {
Wire.write(temperature); // Send temperature data to master
}

U kunt deze code aanpassen aan de sensoren die u in uw project heeft, of zelfs de sensorwaarden op een displaymodule weergeven om maak je eigen kamerthermometer en vochtigheidsmeter .

Slave-adressering met I2C op Arduino

Om waarden te lezen van componenten die in een dergelijk project aan een I2C-bus zijn toegevoegd, is het belangrijk dat u het juiste slave-adres opneemt bij het coderen. Gelukkig biedt Arduino een scannerbibliotheek die het proces van het identificeren van slave-adressen vereenvoudigt, waardoor het niet meer nodig is om lange sensorgegevensbladen en verwarrende online documentatie te doorzoeken.

Gebruik de volgende code om het adres van een slave-apparaat op de I2C-bus te identificeren.

 #include <Wire.h> // Include the Wire library for I2C communication 

void setup() {
Wire.begin(); // Initialize the I2C communication
Serial.begin(9600); // Initialize the serial communication with a baud rate of 9600
while (!Serial); // Wait for the serial connection to establish
Serial.println("\nI2C Scanner"); // Print a message indicating the start of I2C scanning
}

void loop() {
byte error, address; // Declare variables to store errors and device addresses
int nDevices; // Declare a variable to store the number of devices found

Serial.println("Scanning..."); // Print a message indicating the start of I2C scanning

nDevices = 0; // Set the number of devices found to 0
for (address = 1; address < 127; address++) { // Iterate over all possible I2C addresses
Wire.beginTransmission(address); // Start a transmission to the current address
error = Wire.endTransmission(); // End the transmission and store any errors

if (error == 0) { // If no errors were found
Serial.print("I2C device found at address 0x"); // Print a message indicating a device was found
if (address < 16) Serial.print("0"); // If the address is less than 16, add a leading 0 for formatting purposes
Serial.print(address, HEX); // Print the address in hexadecimal format
Serial.println(" !"); // Print a message indicating a device was found

nDevices++; // Increment the number of devices found
}
else if (error == 4) { // If an error was found
Serial.print("Unknown error at address 0x"); // Print a message indicating an error was found
if (address < 16) Serial.print("0"); // If the address is less than 16, add a leading 0 for formatting purposes
Serial.println(address, HEX); // Print the address in hexadecimal format
}
}
if (nDevices == 0) { // If no devices were found
Serial.println("No I2C devices found\n"); // Print a message indicating no devices were found
}
else { // If devices were found
Serial.println("done\n"); // Print a message indicating the end of I2C scanning
}
delay(5000); // Delay for 5 seconds before starting the next scan
}

Breid uw project vandaag nog uit

Het verbinden van twee Arduino-kaarten met behulp van het I2C-communicatieprotocol biedt een flexibele en efficiënte manier om complexe taken uit te voeren die niet door een enkele kaart kunnen worden afgehandeld. Met behulp van de Wire-bibliotheek wordt communicatie tussen de twee boards met behulp van I2C eenvoudig gemaakt, waardoor u meer componenten aan uw project kunt toevoegen.