HƯỚNG DẪN LẬP TRÌNH I2C VỚI ARDUINO

Hôm nay, arduino shop xin hướng dẫn lập trình i2c với arduino, Cụ thể là hai con arduino mega 2560 với nhau. Giao tiếp I2C sẽ cho phép bạn kết nối lên đến 127 thiết bị với nhau mà chỉ cần 2 dây kết nối SDA và SCL rất tiện lợi cho các ứng dụng vì chúng khá tiết kiệm dây. Việc khởi tạo và lập trình cho giao tiếp này cũng đơn giản như chuẩn UART. Mời các bạn xem ví dụ bên dưới để hiểu rõ hơn như thế là giao thức truyền nhận I2C nhé. Nào Let's Go!

Ngày đăng: 21-09-2016

6,452 lượt xem

Định nghĩa chuẩn giao tiếp I2C

Chuẩn I2C là viết tắt của "Inter-Integrated Circuit", chuẩn này được tìm ra bởi Philips’ semiconductor division để đơn giản việc trao đổi dữ liệu. Chỉ sử dụng 2 dây để giao tiếp với các thiệt là SDA và SCL. Có rất nhiều thiết bị sử dụng chuẩn I2c này để giao tiếp như arduino, bộ đọc thời gian thực, màn hình LCD, một số cảm biến…
Các bạn có thể thấy bảng mô tả các chân I2C của các arduino bên dưới:

Board                           I2C / TWI pins
Uno, Ethernet             A4 (SDA), A5 (SCL)
Mega2560 20            (SDA), 21 (SCL)
Leonardo 2                 (SDA), 3 (SCL)
Due 20                        (SDA), 21 (SCL), SDA1, SCL1

Trong chuẩn giao tiếp i2c với arduino thì có một con chủ gọi là master và nhiều con tớ Slave. Mỗi con này đều có một địa chỉ khác nhau. Chuẩn giao tiếp I2C có đến 127 địa chỉ, đồng nghĩa với việc có thể giao tiếp lên đến 127 thiết bị với nhau chỉ thông qua 2 dây SDA và SCL. Các bạn có thể xem mô hình kết nối i2c bên dưới

giao-tiep-I2C

Mô hình giao tiếp I2C

Để I2C bus có thể hoạt động, chúng ta cần 2 điện trở pull-up như trong hình, 4.7k hoặc 10k là hợp lý. Tuy nhiên, nếu chỉ có một thiết bị I2C, chúng ta có thể bỏ qua điện trở pull-up vì trong MCU ATmega328 của Arduino UNO đã có sẵn 20k build-in resisters.
Lưu ý: vì Arduino UNO sử dụng điện áp 5V, do đó các thiết bị I2C cũng phải hoạt động ở 5V.

Vì sao phải chọn chuẩn i2c giao tiếp arduino?

Thứ 1: Thông thường để giao tiếp các arduino với nhau hoặc arduino với thiết bị khác thì chúng ta hay dùng 2 chân RX và TX của arduino để giao tiếp. Tuy nhiên nếu chúng ra muốn kết nối nhiều thiết bị với arduino hoặc nhiều arduino với nhau thì việc dùng UART là không khả thi chút nào. Việc các bạn sử dụng I2C giao tiếp với arduino và các thiết bị là cực ky đơn giản và chính xác. Số lượng thiết bị kết nối lên đến 127 thiết bị, dưới sự điều khiển của một board chủ.

Thứ 2. Nếu dự án của bạn có quá nhiều IO? Bạn phải thay đổi con arduino của bạn từ con ít chân sang con nhiều chan. Nhưng với arduino thì chỉ có con Atmega 2560 mới có 54 chân, còn lại các module arduino khác thì có số chân khá hạn chế. Tuy nhiên, nếu để nó xử lý nhiều vấn đề với IO quá thì sẽ làm nó bị chậm và không đảm bảo tính ổn định, vì nếu sử dụng nhiêu IO thì việc điện áp trên con này cũng ko ổn định các bạn ạ.

Thứ 3: Bạn dùng i2c để giao tiếp với các module arduino khác. Theo mình, đây là cách đơn giản, chỉ vài bước lập trình ngắn là đã có thể mở rộng IO. Tất nhiên chúng ta cũng có thể dùng chuẩn I2C để giao tiếp arduino với các thiết bị khác như 74HC595.
Để hiểu rõ hơn về nguyên lý hoạt động của I2C, Arduino Shop viết bài hướng dẫn lập trình i2c với arduino, mong muốn các bạn sẽ thực hành tốt với chuẩn giao tiếp này.

Hướng dẫn lập trình I2C giao tiếp arduino

Để sử dụng I2C trên arduino, chúng ta cần phải biết sử dụng tập lệnh trong thư viện WIre.h của arduino. Các bạn có thể tham khảo Arduino.cc

Arduino Shop xin giới thiệu một số hàm cơ bản sau:

  • Wire.begin(address (optional)): Khởi tạo thư viện. Address là địa chỉ để arduino biết nó cần làm việc với thiết bị nào. Nếu giá trị này là 0 thì nó là con master
  • Wire.beginTransmission(address); Bắt đầu truyền dữ liệu đến thiết bị "Slave" với address đã có.
  • Wire.endTransmission(); Kết thúc truyền dữ liệu đến thiết bị "Slave" đã được bắt đầu bởi Wire.beginTransmission(address).
  • Wire.write(value); Ghi dữ liệu lên thiết bị "Slave", được gọi giữa beginTransmission() và endTransmission().
  • Wire.read(); Đọc dữ liệu được truyền từ thiết bị "Slave" đến Arduino, được gọi sau requestFrom().
  • Wire.requestFrom(address, quantity); Được sử dụng bởi thiết bị "Master" để yêu cầu dữ liệu từ thiết bị "Slave". address: là địa chỉ của thiết bị  Slave". quantity: số lượng bytes yêu cầu.

Chuẩn bị:

Để lập trình I2C với arduino mà cụ thể trong bài viết này của Arduino shop, các bạn hãy chuẩn bị co mình 2 con Arduino. Bạn chọn con nào cũng được. Ở đây Arduino Shop chọn 2 con Arduino Mega 2560 để thực hiện đề tài

Kết nối:

Dùng 2 con arduino mega2560 và chỉ cần kết nối 2 chân SDA và SCL của chúng chung lại với nhau. Bạn nhớ cấp nguồn đúng 5V nhé, thêm nữa là có dây mass chung nha các bạn, để nó biết là chúng sài chung điện áp.

giao-tiep-arduino-mega-2560-i2c

Giao tiếp I2C với arduino

Code lập trình

Arduino Shop muốn tự viết cho các bạn một cái code, tuy nhiên, trong thư viện của wire.h đã có 2 cái ví dụ về cái này, nên Arduino Shop lấy cái ví dụ đó và giải thích cho các bạn hiểu trước. Arduino Shop cũng gởi cho các bạn VIDEO về nó để các bạn rõ hơn.

Code của con Master: Con master có vai trò là truyền dữ liệu các bạn nhé. Thực hiện truyền ký tự là char " x is" và số x

#include <Wire.h>

void setup() {
  Wire.begin(); // kHởi tạo I2C với tư cách là master. Như đã nói ở trên, không có tham số địa chỉ thì nó mặc định là master
}

byte x = 0;// Khai báo dữ liệu là kiểu byte

void loop() {
  Wire.beginTransmission(8); // Bắt đâu truyền dữ liệu cho con SLAVE có địa chỉ là 8. Các bạn lưu ý, bên con Slave bạn phải khai báo  Wire.begin(8) nhé, để nó nhận ra
  Wire.write("x is ");        // Gởi 5 byte dữ liệu kiểu char
  Wire.write(x);              // Gởi một byte dữ liệu dạng số
  Wire.endTransmission();    // Ngừng quá trình truyền dữ liệu

  x++;
  delay(500);
}

==> Đoạn code này mô tả, truyền vừa số vừa chữa, sau mỗi chu kỳ nó lại truyền 1 lần, mỗi lần truyền giá trị của biến x tăng lên 1 đơn vị.

Code của con Slave: Nhận dữ liệu từ con master và hiển thị lên màn hình

void setup() {
  Wire.begin(8);                // Khai báo i2c với slave có địa chỉ là 8
  Wire.onReceive(receiveEvent); // Khai báo ngắt sự kiện. Thông thường. mục đích của mình là khi có sự kiện thì nó mới làm việc này việc kia, vì con này là tớ, nên làm theo chủ sai. Nếu chủ không sai thì nó làm việc của nó trong vong lặp loop()
  Serial.begin(9600);           // Khai báo chuẩn uart
}

void loop() {
  delay(100);
}

Khi có một sự kiện ngắt xẩy ra do bus I2C, thì nó ngay lập tức tới hàm này để thực thi công việc
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // Mục đích là quét liên tục xem có sự kiện ngắt xảy ra do bus i2c hay không, nếu có thì thực hiện chức năng trong hàm
    char c = Wire.read(); // Nhận byte ký tự trước. Do con master tuyền ký tự trước mà
    Serial.print(c);         // in ra ký tự
  }
  int x = Wire.read();    // Nhận ký tự là số interger
  Serial.println(x);         // in ra giá trị số
}

Arduino Shop còn VIDEO hướng dẫn các bạn làm, hiện chưa up lên kịp, sẽ up trong thời gian tới các bạn nhé.

Trên đây là toàn bộ hướng dẫn cách lập trình I2C với arduino mà Arduino Shop đã soạn ra. Với mong muốn chia sẽ kinh nghiệm lập trình, arduino shop hi vọng các bạn sẽ thực hành tốt. Thì để làm được đề tài, thì mình cần trang bị thiết bị. Các bạn có thể tham khảo các sản phẩm tại arduino Sop để lựa chọn phù hợp nhé.

GỌI NGAY - 0902 37 12 52 (Mr Quốc): Tư vấn KT

ĐỂ ĐƯỢC TƯ VẤN VÀ CUNG CẤP GIẢI PHÁP KỊP THỜI CHO BẠN

ARDUINO SHOP

Địa chỉ: Số 41 Gò Dưa, Phường Tam Bình, Quận Thủ Đức, TP. Hồ Chí Minh
Email: arduinoshophcm@gmail.com

Bình luận (5)

Gửi bình luận của bạn

Captcha
  • thai (07-06-2018) Trả lời
    e muon dung nhieu con master gui du lieu cho 1 con slave thi phai theem hay thay doi ntn a!!!e cam on
    • HTQ (07-06-2018)
      Vì sao mình lại muốn làm ngược lại? Nhiều ông chủ giao việc cùng lúc cho 1 nhân viên, liệu nv đó làm hết và tốt ko? Rồi mình hãy nghỉ tới việc nhiều master giao tiếp với slave
  • quan (31-05-2017) Trả lời
    trên con arduino nano thì SDA và SCL là chân nào ạ
    • Huỳnh Tấn Quốc (02-06-2017)
      Hi bạn, Chân SDA/SCL của nano như con uno nha bạn, chân A4/A5 Thanks,
  • quan (29-05-2017) Trả lời
    hay quá!!!!!!1
<