程式人雜誌 -- 2013 年 11 月號 (開放公益出版品)

Arduino入門教學(11) – 多台 Arduino 間的通訊 - 透過 I2C (作者:Cooper Maa)

今天我們要介紹怎麼讓多台 Arduino 互相通訊。我們所用的通訊協定是 I2C Protocol,I2C 只需要兩支腳位就可以讓設備建立通訊,這兩支腳位一個叫作 SDA (Serial DAta line),另一個叫作 SCL (Serial CLock Line)。在大部份的 Arduino 板子上,SDA 是在 analog pin 4,而 SCL 是在 analog pin 5。

接線

參考底下的接線圖連接你的 Arduino:

接線方法很簡單,你只要把每一台 Arduino 的 SDA (analog pin 4), SCL (analog pin 5), GND 和 5V 分別連接在一起就可以了。另外,最好在 SDA 和 SCL 上加個接到 5V 的 4.7K 歐姆提升電阻以確保預設電壓為高電位。

I2C 是 Master-Slave 的架構,Master 可以向 Slave 發出需求要資料或傳送資料。I2C bus 上最多可以有 128 個設備。在 I2C bus 上可以有多個 Master 和多個 Slave,不過為了避免複雜,通常我們只會用一個 Master。每個 Slave 都會有一個識別的號碼,叫作 Slave address,Master 要跟 Slave 通訊的時候,就利用 Slave address 指定要跟哪個 Slave 建立對話。

底下將示範怎麼讓兩台 Arduino 透過 I2C 建立通訊。這兩台 Arduino 一台是 Master,一台是 Slave,其中 Slave 所用的 address 為 1。

程式

底下是 Master 的程式:

// master_sender.ino
// Refer to the "slave_receiver" example for use with this
#include <Wire.h>

const int SLAVE_ADDRESS = 1;
char incomingByte = 0;

void setup() {  
  Wire.begin();         // join I2C bus as a Master
  
  Serial.begin(9600);
  Serial.println("Type something to send:");
}

void loop() {
}

void serialEvent()
{
  // read one byte from serial port
  incomingByte = Serial.read();

  // send the received data to slave
  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write(incomingByte);
  Wire.endTransmission();
}

程式說明:

// send the received data to slave
Wire.beginTransmission(SLAVE_ADDRESS);
Wire.write(incomingByte);
Wire.endTransmission();

底下則是 Slave 的程式:

// slave_receiver.ino
// Refer to the "master_sender" example for use with this
#include <Wire.h>

const int SLAVE_ADDRESS = 1;
char incomingByte = 0;

void setup() {  
  Wire.begin(SLAVE_ADDRESS);    // join I2C bus as a slave with address 1
  Wire.onReceive(receiveEvent); // register event
  
  Serial.begin(9600);
  Serial.println("Received data:");
}

void loop() {
}

void receiveEvent(int howMany)
{
  while (Wire.available()) 
  {
    // receive one byte from Master
    incomingByte = Wire.read();
    Serial.print(incomingByte);
  }
}

程式說明:

執行結果

程式執行的時候,首先你會看到 Master 丟出一行 "Type something to send: " 的訊息。你可以在上面輸入任何資料,例如:

▲ 由於 Arduino IDE 不能同時開兩個 Serial Monitor,所以我用 Tera Term 開啟跟 Master 的連線

▲ 由於 Arduino IDE 不能同時開兩個 Serial Monitor,所以我用 Tera Term 開啟跟 Master 的連線

這時候 Slave 端就會顯示從 Master 端收到的資料,如下:

注意,在使用 Tera Term 的時候,記得要先設定 Terminal,這樣才可以看得到你輸入的資料而且 Tera Term 才會正確換行:

▲ 記得到 Setup > Terminal 畫面把 Transmit 改成 CR+LF 並把 Local echo 打開

參考資料

【本文作者為馬萬圳,原文網址為: http://coopermaa2nd.blogspot.tw/2011/12/arduino-i2c.html ,由陳鍾誠編輯後納入本雜誌】