2016년 9월 18일 일요일

아두이노 I2C통신

I2C(Inter Integrated Circuit)는 대표적인 칩간 통신 규격으로 필립스에서 개발하여 임베디드 시스템 개발 시 널리 사용되고 있습니다.
아두이노에서도 이 I2C를 사용하여 부품을 제어할 수 있습니다.
아두이노에서 기초적인 제어 방식은 다음과 같습니다.
  • Digital 핀을 이용해서 On/Off할 수 있다.
  • Digital 핀을 이용해서 스위치 등의 상태를 확인할 수 있다.
  • PWM 핀을 이용해서 전기 출력을 조절할 수 있다.
  • Analog 핀을 이용해서 센서의 상태를 확인할 수 있다.
이것만으로도 할 수 있는 것은 많지만, 더 복잡한 기능을 수행하려면 턱없이 부족합니다. 하드웨어에서 복잡한 기능을 효과적으로 구현하는 방법은 바로 IC로 만드는 것입니다.
하드웨어는 필요한 기능을 IC로 만들 수 있다.

이렇게 만들어진 IC로 아두이노에서 제어하려면 Digital/Analog 핀만으로는 다루기 어렵습니다. 그래서, 통신이라는 것이 필요하고 통신을 위해 프로토콜(통신 방식)을 사용합니다.
I2C는 바로 IC로 만들어진 기능을 쉽게 사용하기 위한 대표적인 방법입니다.
I2C는 버스(Bus)라 불리는 하나의 선으로 여러 장치를 효과적으로 제어할 수 있는 기능을 제공합니다.
I2C 버스의 개념

아두이노에서는 I2C통신을 지원하는 부품을 여러 개 연결해서 사용할 수 있다는 뜻입니다. 버스 통신은 하나의 선을 여러 장치가 사용하므로 충돌없이 통신할 수 있도록 다음의 개념이 필요합니다.
  • Master: 통신을 시작할 수 있는 권한이 있다. 반드시 한개만 존재해야 한다.
  • Slave: Master의 요구에 응답만 할 수 있다.
  • Address: 자신을 구별할 일종의 ID이다.
I2C Master/Slave 개념

아두이노에서 I2C를 사용하기 위해서는 2개의 핀이 필요합니다.
  • SDA: 아두이노 Uno에서는 A4 핀이 이 역할을 한다.
  • SCK: 아두이노 Uno에서는 A5 핀이 이 역할을 한다.
아두이노에서 I2C 핀

아두이노 보드의 종류마다 SDA/SCK 역할을 하는 핀이 다르므로 잘 확인해야 합니다.

하드웨어 연결을 잘 했다면, I2C 통신을 위해 스케치를 작성해야 합니다.
아두이노는 I2C 통신을 위해 Wire라 부르는 라이브러리를 제공합니다. (Wire 라이브러리 사용법)

<아두이노 보드가 Master역할을 하는 경우>
#include <Wire.h> // using Wire Library

void setup()
{
    Wire.begin(); // Start I2C Master
}

void loop()
{
    // Write data to Slave
    Wire.beginTransmission(3); // Slave address is 3
    Wire.write(data);
    Wire.endTransmission();


    // Read data from Slave
    Wire.requestFrom(3, 6);  // Slave address is 3, Data length is 6
    while(Wire.available())  // Wait data until completed
    {
         Wire.read();    // Get data from buffer
    }
}


<아두이노 보드가 Slave역할을 하는 경우>
#include <Wire.h> // using Wire Library

void setup()
{
    Wire.begin(5); // Set address of Slave
    Wire.onReceive(OnReceived);  // Set callback for writing of Master
    Wire.onRequest(OnRequested);  // Set callback for requesting of Master
}

void OnReceived(int numByte)
{
    // When received from Master
    while(Wire.available())  // Wait data until completed
    {
         Wire.read();    // Get data from buffer
    }  
}

void OnRequested()
{
    // When requested from Master
    Wire.write(data);
}


실제로 I2C를 통해 어떤 데이터를 주고 받을 지에 대해서는 해당 부품의 데이터시트(Data Sheet)를 확인해야 합니다.


댓글 없음:

댓글 쓰기