Giao tiếp I2C giữa nhiều arduino với nhau

Bởi nguyenthanhphi (15/08/2017) 0 Bình luận

Giao tiếp I2C trong arduino:

Nhiều bạn thường dùng 2 chân RXD và TXD để giao tiếp, nhưng trong trường hợp chúng ta cần kết nối nhiều arduino với nhau thì việc giao tiếp qua 2 cổng RXD và TXD là không khả thi. Việc sử dụng giao thức I2C cho arduino kết nối với nhau là cực kì đơn giản và chính xác, số lượng arduino có thể kết nối trong cùng 1 mạng, dưới sự điều hành của 1 boad arduino chủ lên tới hơn 100 boad arduino con.

Thỉnh thoảng mình vẫn hay gặp phải những dự án cần nhiều số lượng chân digital và analog, việc đầu tiên mình nghĩ đến là vác ngay con arudino mega 2560 về. Nhưng thực tế có những dự án 1 con arduino mega 2560 sẽ không đảm nhận được trách nhiệm, 1 phần vì nếu để nó chia áp ra quá nhiều chân sẽ dẫn tới bị loạn chip khi sử dụng hoặc thậm chí có thể sẽ không hoạt động được. và khi đó mình nghĩ tới việc kết nối nhiều con arduino nano vơi nhau.

Tất nhiên chúng ta có thể sử dụng IC khác để giải quyết các vấn đề về số lượng chân như 74hc595. Nhưng mình thích sự nhanh chóng, cắm dây là xong. Nếu các bạn quan tâm thì hãy cùng mình nghiên cứu nội dung này nhé!

Để hiểu rõ hơn về nguyên lý hoạt động của giao tiếp I2C, các bạn xem lại bài viết của mình về nhé

1. CHUẨN BỊ:

2. SƠ ĐỒ KẾT NỐI:

Như bài viết trước mình đã nêu rõ về nguyên lý hoạt động của I2C, việc kết nối giữa arduino với arduino hoàn toàn giống như giữa arduino và các module khác. Ta chỉ cần kết nối chân SDA - SDA; SCL - SCL và đặc biệt quan trọng đó là phải có chung GND. Trong trường hợp cần thiết, cần phải có trở từ 1 - 2k kéo từ các chân SCL và SDA tới +5v để chắc chắn giao tiếp sẽ hoạt động.

giao tiếp i2c giữa hai board arduino uno

Có 1 lưu ý đó là các bạn không được kết nối giữa 2 boad sử dụng mức điện áp khác nhau, ví dụ nếu 1 boad sử dụng nguồn nuôi chip là 5v, kết nối với 1 boad là 3,3v. Boad 5v sẽ không hỏng, nhưng mình không dám chắc boad 3,3v của bạn sẽ còn hoạt động được

Việc kết nối với nhiều boad cũng tương tự như trên, chỉ cần nối GND chung, SDA và SCL của các boad theo chung đường với nhau là được

2.Master TRUYỀN LỆNH, Slave NHẬN LỆNH (master write - Slave read)

Ở phần này mình xin đưa ra ví dụ về việc boad chủ (master) truyền tín hiệu về boad trạm (slave)

Code Chủ

  1. //i2c Master Code(UNO)
  2. #include <Wire.h>
  3. void setup()
  4. {
  5.   Serial.begin(9600);
  6.   Wire.begin(); // Khởi tạo thư viện i2c
  7. }
  8.  
  9. void loop()
  10. {
  11.   while(Serial.available()) // đợi cho đến khi serial có tín hiệu
  12.   {
  13.     char c = Serial.read(); // gán biến c đọc dữ liệu trong serial
  14.     
  15.     if(c == 'H') / nếu c= "H"
  16.     {
  17.       Wire.beginTransmission(6); // Bắt đầu truyền dữ liệu về địa chỉ số 6
  18.       Wire.write('H'); // Truyền ký tự H
  19.       Wire.endTransmission(); // kết thúc truyền dữ liệu
  20.     }
  21.     else if(c == 'L') // Nếu c = "L"
  22.     {
  23.       Wire.beginTransmission(6); // Bắt đầu truyền dữ liệu về địa chỉ sô 6
  24.       Wire.write('L'); // Truyền ký tự L
  25.       Wire.endTransmission();// Kết thúc truyền dữ liệu
  26.     }
  27.   }
  28. }

ở đây tại sao lại là "6"

  1.  Wire.beginTransmission(6)

I²C sử dụng 7 bit để định địa chỉ, do đó trên một bus có thể có tới 2^7 địa chỉ tương ứng với 128 thiết bị có thể kết nối, các bạn có thể tùy ý chọn các địa chỉ từ 1-127, ở đây mình chọn là 6, và 6 chính là địa chỉ của Boad arduino trạm (slave).

Board chủ không cần địa chỉ nhé

Tiếp đến là code cho boad slave

 

  1. //i2c Slave Code(UNO)
  2. #include <Wire.h>
  3. void setup()
  4. {
  5.   Wire.begin(6); // Khởi tạo thư viện i2c địa chỉ 6
  6.   Wire.onReceive(receiveEvent); // khởi tạo chế độ nhận tín hiệu từ boad chủ
  7.   pinMode(13,OUTPUT);
  8.   digitalWrite(13,LOW);
  9. }
  10.  
  11. void loop()
  12. {
  13. }
  14.  
  15. void receiveEvent() // hàm sự kiện nhận tín hiệu từ boad chủ
  16. {
  17.   while(Wire.available()) // chờ cho đến khi có tín hiệu
  18.   {
  19.     char c = Wire.read(); // biến c để lưu dữ liệu nhận được
  20.     
  21.     if(c == 'H') // nếu boad chủ gửi về tín hiệu là H
  22.     {
  23.       digitalWrite(13,HIGH); // chân 13 ở mức High
  24.     }
  25.     else if(c == 'L') // nếu tín hiệu boad chủ gửi về là L
  26.     {
  27.       digitalWrite(13,LOW);// chân 13 ở mức Low
  28.     }
  29.   }
  30. }

Như các bạn thấy việc khởi tạo địa chỉ cho boad slave rất đơn giản, và trong trường hợp các bạn cần nhiều boad slave hơn các bạn chỉ cần khởi tạo các đia chỉ khác nhau

 

Đóng góp ý kiến