Jak połączyć dwie płyty Arduino za pomocą I2C

Jak połączyć dwie płyty Arduino za pomocą I2C
Czytelnicy tacy jak ty pomagają wspierać MUO. Kiedy dokonujesz zakupu za pomocą linków na naszej stronie, możemy otrzymać prowizję partnerską. Czytaj więcej.

Podczas gdy pojedynczy Arduino może wykonać wiele zadań, niektóre projekty mogą wymagać użycia więcej niż jednej płytki do obsługi różnych funkcji. Tak więc, aby umożliwić przesyłanie danych między dwoma mikrokontrolerami, należy skonfigurować protokół komunikacyjny, taki jak CAN, SPI, I2C lub UART.





W tym przewodniku omówimy podstawy działania I2C, połączenia sprzętowe i implementację oprogramowania potrzebną do skonfigurowania dwóch płyt Arduino jako urządzeń nadrzędnych i podrzędnych I2C.





WYKORZYSTAJ WIDEO DNIA PRZEWIŃ, ABY KONTYNUOWAĆ TREŚĆ

Co to jest I2C?

Inter-Integrated Circuit (I2C) to szeroko stosowany protokół komunikacyjny w systemach wbudowanych i mikrokontrolerach umożliwiający przesyłanie danych między urządzeniami elektronicznymi. W przeciwieństwie do SPI (Serial Peripheral Interface), I2C umożliwia podłączenie więcej niż jednego urządzenia nadrzędnego do magistrali z jednym lub wieloma urządzeniami podrzędnymi. Został po raz pierwszy użyty przez firmę Philips i jest również znany jako protokół komunikacyjny Two Wire Interface (TWI).





Jak działa komunikacja I2C?

I2C wykorzystuje dwie linie dwukierunkowe: dane szeregowe (SDA) i zegar szeregowy (SCL) do przesyłania danych i synchronizacji komunikacji między urządzeniami. Każde urządzenie podłączone do magistrali I2C posiada unikalny adres, który identyfikuje je podczas komunikacji. Protokół I2C umożliwia wielu urządzeniom współdzielenie tej samej magistrali, a każde urządzenie może działać jako master lub slave.

  Demonstracja komunikacji I2C

Komunikacja jest inicjowana przez urządzenie nadrzędne, a nieprawidłowe adresowanie urządzeń podrzędnych może powodować błędy w transmisji. Zapoznaj się z naszym szczegółowym przewodnikiem na temat jak działa komunikacja szeregowa UART, SPI i I2C aby dać ci kontekst.



Główną zaletą komunikacji I2C, na którą warto zwrócić uwagę, jest elastyczność, jaką oferuje, jeśli chodzi o zarządzanie energią. Urządzenia działające na różnych poziomach napięcia mogą nadal skutecznie komunikować się za pomocą przesuwników napięcia. Oznacza to, że urządzenia pracujące z napięciem 3,3 V wymagają przesuwników napięcia, aby połączyć się z magistralą 5 V I2C.

Biblioteka drutu

Biblioteka Wire to wbudowana biblioteka Arduino, która zapewnia funkcje do komunikacji przez I2C. Wykorzystuje dwa piny — SDA i SCL — na płycie Arduino do komunikacji I2C.





Piny I2C na Arduino Uno:

  Piny Arduino I2C Uno

Piny Arduino Nano I2C:





  Pinout Arduino nano I2C

Aby korzystać z biblioteki, należy dołączyć Drut h plik nagłówkowy na początku szkicu Arduino.

 #include <Wire.h>

Biblioteka Wire udostępnia funkcje do inicjowania komunikacji z urządzeniem I2C, wysyłania i odbierania danych. Niektóre ważne funkcje, które powinieneś znać, obejmują:

  • Drut.rozpocznij() : używany do dołączania do magistrali I2C i inicjowania komunikacji.
  • Wire.beginTransmission() : służy do określenia adresu urządzenia podrzędnego i rozpoczęcia transmisji.
  • Wire.write() : używany do wysyłania danych do urządzenia I2C.
  • Wire.endTransmission() : służy do kończenia transmisji i sprawdzania błędów.
  • Wire.requestFrom() : używany do żądania danych z urządzenia I2C.
  • Przewód.dostępny() : służy do sprawdzania, czy dane są dostępne do odczytu z urządzenia I2C.
  • drut.odczyt() : służy do odczytu danych z urządzenia I2C.

Użyj Wire.beginTransmission() funkcja ustawiania adresu czujnika, który jest wstawiany jako argument. Na przykład, jeśli adres czujnika to 0x68 , użyłbyś:

 Wire.beginTransmission(0x68);

Konfiguracja sprzętu Arduino I2C

Aby połączyć dwie płyty Arduino za pomocą I2C, potrzebne będą następujące komponenty sprzętowe:

  • Dwie płytki Arduino (master i slave)
  • deska do krojenia chleba
  • Przewody rozruchowe
  • Dwa rezystory podciągające 4,7 kΩ

Podłącz SDA I SCL piny obu płyt Arduino do płytki prototypowej. Podłącz rezystory podciągające między SDA I SCL szpilki i 5V szyna zasilająca na płytce stykowej. Na koniec połącz ze sobą dwie płytki stykowe za pomocą przewodów połączeniowych.

Obwód Arduino Uno

  Połączenie Arduino_I2C na płytce prototypowej

Obwód Arduino Nano

  nano33BS_06_ilustracja dla protokołu komunikacyjnego I2C
Źródło obrazu: Dokumentacja Arduino I2C

Konfigurowanie płyt Arduino jako urządzeń nadrzędnych i podrzędnych I2C

Użyj Wire.requestFrom() do określenia adresu urządzenia podrzędnego, z którym chcemy się komunikować. Następnie skorzystaj z drut.odczyt() funkcja pobierania danych z urządzenia podrzędnego.

Kod urządzenia głównego:

 #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();
}

The Wire.onReceive() służy do określenia, co należy zrobić, gdy urządzenie podrzędne odbierze dane z urządzenia nadrzędnego. W powyższym kodzie plik Przewód.dostępny() funkcja sprawdza, czy dane są dostępne, a drut.odczyt() funkcja odczytuje dane przesłane przez urządzenie nadrzędne.

Kod urządzenia podrzędnego:

 #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
}

Wysyłanie i odbieranie danych za pomocą I2C

W tym przykładzie odczytajmy temperaturę z czujnika temperatury DHT11 połączonego z podrzędnym Arduino i wydrukujmy ją na monitorze szeregowym nadrzędnego Arduino.

  Przykład DHT11 I2C z 2 płytami Arduino

Zmodyfikujmy kod, który napisaliśmy wcześniej, aby zawierał pomiar temperatury, który następnie wyślemy do płyty głównej przez magistralę I2C. Płyta główna może następnie odczytać przesłaną przez nas wartość, a następnie wyświetlić ją na monitorze szeregowym.

Kod urządzenia głównego:

 #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
}

Kod urządzenia podrzędnego:

 #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
}

Możesz dostosować ten kod, aby pasował do dowolnych czujników, które możesz mieć w swoim projekcie, a nawet wyświetlić wartości czujników na module wyświetlacza, aby stwórz własny termometr pokojowy i miernik wilgotności .

Adresowanie Slave z I2C na Arduino

Aby odczytać wartości z komponentów dodanych do magistrali I2C w takim projekcie, ważne jest, aby podczas kodowania podać prawidłowy adres urządzenia podrzędnego. Na szczęście Arduino oferuje bibliotekę skanerów, która upraszcza proces identyfikacji adresów urządzeń podrzędnych, eliminując konieczność przeglądania długich arkuszy danych czujników i mylącej dokumentacji online.

Użyj poniższego kodu, aby zidentyfikować adres dowolnego urządzenia podrzędnego obecnego na szynie I2C.

jak zrobić listę numerowaną w programie Excel
 #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
}

Rozwiń swój projekt już dziś

Połączenie dwóch płyt Arduino za pomocą protokołu komunikacyjnego I2C oferuje elastyczny i wydajny sposób realizacji złożonych zadań, których nie może obsłużyć pojedyncza płyta. Z pomocą biblioteki Wire komunikacja między dwiema płytami za pomocą I2C jest łatwa, co pozwala na dodanie większej liczby komponentów do twojego projektu.