2015년 5월 29일 금요일

아두이노의 TWI (I2C) 개요

 아두이노로 TWI (또는 I2C) 통신을 하기 위해서는 Wire 라는 라이브러리를 이용해야 한다. 시리얼 통신이 1:1 통신 규약인 반면, TWI는 1:n 통신 규약으로서 하나의 마스터(master) 기기가 여러 개의 슬레이브(slave) 디바이스들과 통신을 할 수 있다는 장점이 있다. Wire라이브러리는 아두이노의 표준 라이브러리이므로 아두이노 IDE에 기본으로 내장되어 있다.

#include <Wire.h>

그리고 통신을 하는 기기들 간에 SDA, SCL, 그리고 GND 끼리 연결하고 전압 레벨이 맞는지 반드시 확인해야 한다. 즉, 5V 기기는 5V 끼리, 3.3V기기는 3,3V 기기 상호간에 연결해야 하면 3.3V와 5V를 연결하려면 레벨 컨버터를 통해야 한다.

 연결된 기기는 하나의 마스터와 다수의 슬레이브로 구분하고 슬레이브들은 7bit 혹은 8bit 아이디(숫자)로 서로를 구분한다. TWI는 모든 통신 주도권을 master가 가진다. 슬레이브에서 데이터를 읽어올 때도 마스터에서 요구하고 슬레이브로 데이터를 보낼 때도 마찬가지로 마스터에서 통신을 요구한 후 보낸다. 마스터에서는 다음과 같이 초기화 함수를 호출한다.

Wire.begin(); // 마스터의 TWI 초기화

슬레이브에서는 다음과 같이 초기화 함수를 아이디를 가지고 호출한다.

Wire.begin(n); //슬레이브의 TWI 초기화

예를 들어서 2번 슬레이브는 Wire.begin(2); 라고 하면 된다. 이 아이디를 가지고 마스터에서 기기간 구별을 하게 된다.

마스터에서 슬레이브로 데이터 보내기

마스터에서 슬레이브로 데이터를 보낼 때는 다음과 같은 순서를 따른다.

//❶ 아이디가 id인 슬레이브와 TWI 통신을 시작한다.
Wire.beginTransmission(id);
Wire.write(by); //❷ byte형 데이터를 보낸다.
Wire.endTransmission(); //❸ 통신을 끝낸다.

Wire.write()함수는 입력 변수의 자료형에 따라 다음과 같이 세 가지가 오버로드 되어 있다.

Wire.write(byte by); // byte형 데이터를 하나를 전송
Wire.write(string str); // 문자열 str을 전송
Wire.write(const byte *ptrByte, int n); // byte형 포인터에 저장된 byte 배열에서 n개의 데이터를 전송

슬레이브 쪽에서는 마스터에서 데이터를 보냈을 때 호출되는 이벤트 함수를 등록해 두면 데이터가 보내졌을 때 이 함수가 호출되어 알맞게 처리를 해주면 된다.

// 데이터가 보내졌을 때 호출될 receiveEvent() 라는 함수를 등록한다.
void setup() {
   Wire.onReceive(receiveEvent);
}
....
....

// 이 이벤트 핸들러는 넘겨받은 바이트 수를 입력으로 건네준다.
void receiveEvent(int iNum)
{
   byte by[iNum];
   for(int n=0; n<iNum; n++)
       by[n] = Wire.read();
}

마스터에서 슬레이브로부터 데이터 읽기

  마스터가 슬레이브에서 데이터를 받을 때도 마스터에서 먼저 요구하며 그 요구에 슬레이브가 반응하도록 되어 있다. 마스터에서 슬레이브에 데이터를 요구하고 읽어오는 과정은 다음과 같다.

byte by[n], m=0;
Wire.requestFrom(id, n); // id를 가지는 슬레이브에 n 바이트를 보내기를 요구한다.
while( Wire.available() ) // 읽어올 데이터가 버퍼에 남아있다면
{
   by[m++]=Wire.read(); // 데이터를 읽는다.
}

슬레이브 측에서는 마스터에서 요구가 올 때 처리할 이벤터 핸들러를 등록해 두면 된다.

// 마스터의 전송 요구시 호출된 requestEvent()라는 함수를 등록
Wire.onRequest( requestEvent );
...
void requestEvent()
{
   Wire.write(100); // (예를 들어) 100이라는 숫자를 전송한다.
}

이와 같이 마스터와 슬레이브 사이에 통신을 할 경우 마스터에서 슬레이브 쪽으로 통신을 하겠다는 요구를 먼저 하게 되어 있다.


댓글 없음:

댓글 쓰기