Arduino Uno 에서 I2C 통신 구현 코드 소개
I2C 통신에 대해 간단히 알아보고, Arduino 에서 I2C 구현하는 방법
에 대해 소개합니다.I2C 통신
I2C는 UART와 유사한 직렬 통신 프로토콜 이지만, PC 장치 통신에는 사용되지 않고 모듈 및 센서와 함께 사용됩니다. 아두이노에서 사용되는 UART, I2C, SPI 는 차후 포스트에서 자세히 차이점에서 다룰 예정이고, 본 포스트에서는 I2C에 대해 간략한 소개만 작성하였습니다. 1
I2C의 특징
- 동기식 통신 방식
- 다중 연결이 가능 : 최대 128개의 장치
- 장치마다 고유한 주소를 사용하여 동일한 버스에 여러 장치 연결이 가능
- 사용처 : 마이크로컨트롤러, EEPROM, A/D 컨버터, D/A 컨버터, I/O 확장 인터페이스 등 저속 장치
I2C 작동 방식
I2C는 SCK(직렬클럭라인)과 SDA(직렬 데이터 라인)의 두개 라인이 있습니다. SCK는 전송 동기화를 위한 클럭라인, SDA는 데이터 비트가 전송되거나 수신되는 데이터 라인입니다. 슬레이브 장치는 각자 고유 주소가 지정되어 있습니다. Master가 Slave 에게 데이터를 전송 또는 요청 하기 위해 지정된 주소를 호출하고 데이터를 송신 또는 수신합니다.
I2C는 Master 와 Slave 가 고정되어 있지 않고, 누구나 Master 가 될 수 있고, Slave 가 될 수 있습니다. 통신에 사용할 클럭(SCK)은 Master가 생성합니다.
I2C 버스 라인은 풀업 저항으로 전원과 연결 되어야 합니다. 통신이 유후 상태일 때는 두 라인 모두 높은 전원 수준입니다.
I2C Interface
I2C 데이터 프레임
Master는 Slave에게 7비트(또는 10비트) 주소와 읽기/쓰기 비트를 전달합니다. Slave 는 수신한 주소와 자신의 주소를 비교하여 주소가 일치하면 SDA 라인을 1비트 동안 LOW로 유지하여 ACK 비트를 반환 합니다. 주소가 일치하기 않을 경우 슬레이브는 SDA 라인을 HIGH 로 유지 합니다. 그 다음에 Master 가 데이터 프레임 8비트를 보내거나 받습니다. 각 데이터 프레임이 전송되면 수신 장치는 다른 ACK 비트를 송신하여 데이터 송신이 정상적으로 전송됨을 알려줍니다. 데이터 정송을 중지하기 위해 마스터는 SCL 을 HIGH 로 전환 후 SDA를 HIGH 로 전환하여 슬레이브에 중지 신호를 전송합니다.
I2C Data Frame
장점 및 단점
- 장점
- 많은 장치 연결시 사용되는 포트 수가 적음
- 다중 마스터, 다중 슬레이브 통신을 지원
- 단점
- 풀업 저항기가 필요해 속도가 느림
- 풀업 저항으로 PCB 공간을 차지
- 반이중 방식의 통신으로 기기 수가 증가하면 구현이 복잡
Arduino Uno I2C Hardware
I2C Pinout
Arduino Uno 에서는 A4, A5번 핀이 I2C 포트로 사용이 가능합니다. Arduino Uno rev.3 이후 버전부터는 우측 핀 최상단 2핀이 A4, A5번 핀과 동일한 핀으로 할당되어 있습니다.
Arduino Uno I2C Pinout
아두이노 I2C 코딩
I2C 라이브러리
아두이노에서 I2C 통신을 사용하기 위해서 wire.h 라이브러리를 사용합니다. wire.h는 아두이노에 기본으로 내장되어 있는 라이브러리로, 별도의 라이브러리 설치 없이 코드 선언부에 #include <wire.h> 만 선언하면 됩니다.
아두이노 코딩을 하기 전에 내가 사용하는 아두이노 보드가 2Master 인지 Slave 인지 구분을 하고, Master -> Slave 데이터 쓰기으로 사용하는지 Master -> Slave 데이터 호출 인지 4가지로 구분하여 정리하면 좀 더 쉽게 I2C 코딩에 대해 감을 잡을 수 있습니다.
1. I2C Initialize
Wire.begin(): I2C Master 로 초기화Wire.begin(address): I2C 주소를 부여하여 초기화, Master/Slave 모두 사용 가능
Syntax
- Wire.begin()
- Wire.begin(address)
Parameters
- address : (Optional) 7 비트 slave address 값입니다. 생략할 경우 마스터로 인식 합니다.
- (optional) 7 비트 Slave Address 값 입니다.
- 생략할 경우 마스터로 인식 합니다.
Returns : None
Example
Wire.begin(): I2C를 초기화 하고, Master 로만 사용합니다.Wire.begin(13): I2C Address 를13로 초기화 하고, Master/Slave 모두 사용 가능합니다.
2. Master -> Slave 데이터 쓰기
Master 측 코드 : Master 데이터 송신
Wire.beginTransmission(address): Master -> Slave(address) 데이터 쓰기 모드를 시작 코드Wire.write(data): 데이터 송신 코드Wire.endTransmission(): 데이터 송신 종료 -> 해당 함수 실행되는 타이밍에 I2C 통신이 시작 됩니다.
Master Wrie 모드에서 Master 코드
void setup()안에서Wire.onReceive(handler): Slave 에서 데이터가 수신 될 때 호출할 함수를 지정void loop()에서 또는void handler()안에서Wire.available(): I2C 수신 버퍼에 저장된 데이터 수를 반환Wire.read(): I2C 수신 버퍼의 데이터를 읽고, 읽은 데이터 수신 버퍼에서 비우기
Master Wrie 모드에서 Slave 코드
3. Master -> Slave 데이터 호출
Master 측 코드 : Master 데이터 호출
Wire.requestFrom(address, dataSize): 지정된 주소의 Slave 에게dataSize크기의 데이터를 호출Wire.available(): I2C 수신 버퍼에 저장된 데이터 수를 반환Wire.read(): I2C 수신 버퍼에 데이터를 읽고, 읽은 데이터를 수신 버퍼에서 비우기
Master Read 모드에서 Master 코드
Slave 측 코드 : Slave 데이터 송신
void setup()안에서Wire.onRequest(handler):Slave로 부터 데이터 요청이 있을 때 호출할 함수(hanlder)를 지정void loop()에서 또는void handler()안에서Wire.write(value): I2C 데이터 송신
Master Read 모드에서 Slave 코드
마무리
I2C의 모드 종류에 따라 사용되는 아두이노 코드
에 대해 알아보았습니다. 다음 포스트는 이번 포스트에서 소개한 함수들을 사용하여 Arduino Uno 와 nodeMCU ESP32s 보드를 I2C 통신하는 예제에 대해 작성할 예정입니다. 참고해주세요. 끝까지 읽어주셔서 감사합니다.^^'Embedded > Arduino' 카테고리의 다른 글
아두이노 강좌 #18 I2C Character LCD 기본 함수 사용 방법 (JHD 162A LiquidCrystal_I2C) (0) | 2020.07.30 |
---|---|
아두이노 강좌 #17 I2C 통신으로 아두이노 우노와 ESP32 통신 하기 (0) | 2020.07.29 |
아두이노 코딩 : 조도센서(CDS,포토레지스터)로 LED Dimming 하기 (0) | 2020.07.26 |
아두이노 코딩 : 히스테리시스로 아날로그 입력 노이즈 처리 (0) | 2020.07.24 |
아두이노 코딩 : 엔터 입력시(문장단위) Serial Echo 프로그램, Putty 로 CR+LF 전송 (0) | 2020.07.23 |