- I2C 통신 프로토콜이란?
- I2C 통신은 어떻게 작동합니까?
- I2C 통신은 어디에서 사용합니까?
- Arduino의 I2C
- 필요한 구성 요소
- 회로도
- 작업 설명
- Arduino의 I2C 프로그래밍
- 마스터 Arduino 프로그래밍 설명
- 슬레이브 Arduino 프로그래밍 설명
이전 튜토리얼에서 Arduino의 SPI 통신에 대해 배웠습니다. 오늘은 또 다른 직렬 통신 프로토콜 인 I2C (Inter Integrated Circuits)에 대해 알아 보겠습니다 . I2C와 SPI를 비교하면 I2C는 와이어가 2 개 뿐인 반면 SPI는 4 개를 사용하고 I2C는 다중 마스터와 슬레이브를 가질 수있는 반면 SPI는 하나의 마스터와 다중 슬레이브를 가질 수 있습니다. 따라서 마스터가되어야하는 프로젝트에 하나 이상의 마이크로 컨트롤러가 있으며 I2C가 사용됩니다. I2C 통신은 일반적으로 자이로 스코프, 가속도계, 기압 센서, LED 디스플레이 등과 통신하는 데 사용됩니다.
이러한면에서 의 Arduino I2C 튜토리얼 우리가 사용하는 두 기판 들간의 Arduino I2C 통신을 전위차계를 사용하여 서로에게 전송할 수 (0 ~ 127)의 값. 각 Arduino에 연결된 16x2 LCD에 값이 표시됩니다. 여기서 하나의 Arduino는 마스터로 작동하고 다른 하나는 슬레이브로 작동합니다. 이제 I2C 통신에 대한 소개부터 시작하겠습니다.
I2C 통신 프로토콜이란?
IIC라는 용어는“ Inter Integrated Circuits ”를 의미합니다. 일반적으로 I2C 또는 I 제곱 C로 표시되거나 일부 장소에서는 2 선 인터페이스 프로토콜 (TWI)로 표시되지만 모두 동일한 의미입니다. I2C는 동기식 통신 프로토콜입니다. 즉, 정보를 공유하는 두 장치 모두 공통 클럭 신호를 공유해야합니다. 정보를 공유하기위한 전선이 두 개 뿐이며 그중 하나는 콕 신호에 사용되고 다른 하나는 데이터 송수신에 사용됩니다.
I2C 통신은 어떻게 작동합니까?
I2C 통신은 Phillips에 의해 처음 도입되었습니다. 앞서 말했듯이 두 개의 와이어가 있으며이 두 개의 와이어는 두 장치에 연결됩니다. 여기서 한 장치를 마스터 라고 하고 다른 장치를 슬레이브 라고합니다. 통신은 마스터와 슬레이브 사이에서 항상 발생해야합니다. I2C 통신의 장점은 하나 이상의 슬레이브를 마스터에 연결할 수 있다는 것입니다.
완전한 통신은 직렬 클럭 (SCL)과 직렬 데이터 (SDA)라는 두 개의 와이어를 통해 이루어집니다.
직렬 클럭 (SCL): 마스터에서 생성 된 클럭 신호를 슬레이브와 공유합니다 .
직렬 데이터 (SDA): 마스터와 슬레이브간에 데이터를 전송합니다.
주어진 시간에 마스터 만 통신을 시작할 수 있습니다. 버스에는 하나 이상의 슬레이브가 있으므로 마스터는 다른 주소를 사용하여 각 슬레이브를 참조해야합니다. 주소가 지정되면 해당 특정 주소를 가진 슬레이브 만 정보로 응답하고 나머지는 종료합니다. 이렇게하면 동일한 버스를 사용하여 여러 장치와 통신 할 수 있습니다.
I2C 의 전압 레벨은 미리 정의되어 있지 않습니다. I2C 통신은 유연합니다. 즉, 5v 볼트로 구동되는 장치는 I2C에 5v를 사용할 수 있으며 3.3v 장치는 I2C 통신에 3v를 사용할 수 있습니다. 그러나 서로 다른 전압에서 실행되는 두 장치가 I2C를 사용하여 통신해야하는 경우 어떻게해야합니까? 5V I2C 버스는 3.3V 디바이스에 접속 될 수 없다. 이 경우 전압 시프터는 두 I2C 버스 사이의 전압 레벨을 일치시키는 데 사용됩니다.
거래를 구성하는 몇 가지 조건이 있습니다. 전송 초기화는 SDA의 하강 에지로 시작되며, 이는 마스터가 SDA를 로우로 설정하는 동안 SCL을 하이로 남겨 두는 아래 다이어그램에서 '시작'조건으로 정의됩니다.
아래 그림과 같이
SDA의 하강 에지는 START 조건에 대한 하드웨어 트리거입니다. 그런 다음 동일한 버스의 모든 장치가 청취 모드로 들어갑니다.
같은 방식으로 SDA의 상승 에지는 위의 다이어그램에서 'STOP'상태로 표시된 전송을 중지합니다. 여기서 마스터는 SCL을 high로 남겨두고 SDA를 해제하여 HIGH로 이동합니다. 따라서 SDA의 상승 에지는 전송을 중지합니다.
R / W 비트는 다음 바이트의 전송 방향을 나타내며 HIGH이면 슬레이브가 전송하고 낮 으면 마스터가 전송 함을 의미합니다.
각 비트는 각 클록 사이클에서 전송되므로 바이트를 전송하는 데 8 클록 사이클이 걸립니다. 각 바이트가 전송되거나 수신 된 후 ACK / NACK (승인 / 승인되지 않음)에 대해 9 번째 클럭 사이클이 유지됩니다. 이 ACK 비트는 상황에 따라 슬레이브 또는 마스터에 의해 생성됩니다. ACK 비트의 경우 SDA는 9 번째 클럭주기 에서 마스터 또는 슬레이브에 의해 로우로 설정됩니다. 따라서 ACK로 간주되고 그렇지 않으면 NACK로 간주됩니다.
I2C 통신은 어디에서 사용합니까?
I2C 통신은 근거리 통신 에만 사용됩니다. 그것은 스마트하게 만들기 위해 동기화 된 클럭 펄스를 가지고 있기 때문에 확실히 어느 정도 신뢰할 수 있습니다. 이 프로토콜은 주로 마스터에 정보를 전송해야하는 센서 또는 기타 장치와 통신하는 데 사용됩니다. 마이크로 컨트롤러가 최소한의 전선 만 사용하여 다른 많은 슬레이브 모듈과 통신해야 할 때 매우 편리합니다. 장거리 통신을 원하는 경우 RS232를 사용하고보다 안정적인 통신을 원하는 경우 SPI 프로토콜을 시도해야합니다.
Arduino의 I2C
아래 이미지는 Arduino UNO에있는 I2C 핀을 보여줍니다.
I2C 라인 | Arduino의 핀 |
SDA | A4 |
SCL | A5 |
두 개의 Arduino를 사용하여 I2C 프로그래밍을 시작하기 전에. Arduino IDE에서 사용되는 Wire 라이브러리 에 대해 배워야합니다.
라이브러리
1. Wire.begin (주소):
사용: 이 라이브러리는 I2C 장치와 통신하는 데 사용됩니다. 이것은 와이어 라이브러리를 시작하고 I2C 버스를 마스터 또는 슬레이브로 결합합니다.
주소: 7 비트 슬레이브 주소는 선택 사항이며 주소가 지정되지 않은 경우 이와 같이 마스터로 버스에 연결됩니다.
2. Wire.read ():
용도: 이 함수는 requestFrom () 호출 후 슬레이브 장치에서 마스터 장치 로 전송되었거나 마스터에서 슬레이브로 전송 된 바이트를 마스터 또는 슬레이브 장치에서 수신 한 바이트를 읽는 데 사용됩니다.
3. Wire.write ():
사용: 이 기능은 슬레이브 또는 마스터 장치에 데이터를 쓰는 데 사용됩니다.
Slave to Master: Slave는 마스터에서 Wire.RequestFrom () 을 사용할 때 데이터를 마스터에 씁니다.
마스터에서 슬레이브로: 마스터에서 슬레이브 장치로 전송하기 위해 Wire.write () 는 Wire.beginTransmission () 및 Wire.endTransmission () 호출 사이에 사용됩니다 .
Wire.write () 는 다음과 같이 작성할 수 있습니다.
- Wire.write (값)
value: 단일 바이트로 보낼 값.
- Wire.write (문자열):
string: 일련의 바이트로 보낼 문자열.
- Wire.write (데이터, 길이):
data: 바이트로 보낼 데이터 배열
길이: 전송할 바이트 수.
4. Wire.beginTransmission (주소):
사용: 이 기능은 주어진 슬레이브 주소로 I2C 장치로 전송을 시작하는 데 사용됩니다. 이후 write () 함수로 전송할 바이트 큐를 만든 다음 endTransmission () 함수를 호출하여 전송합니다. 장치의 7 비트 주소가 전송됩니다.
5. Wire.endTransmission ();
사용: 이 함수는 beginTransmission ()에 의해 시작된 슬레이브 장치로의 전송을 종료하고 Wire.write ()에 의해 대기열에있는 바이트를 전송하는 데 사용됩니다 .
6. Wire.onRequest ();
사용: 이 함수는 마스터가 슬레이브 장치에서 Wire.requestFrom () 을 사용하여 데이터를 요청할 때 호출됩니다. 여기에 Wire.write () 함수를 포함하여 데이터를 마스터로 보낼 수 있습니다.
7. Wire.onReceive ();용도: 이 함수는 슬레이브 장치가 마스터로부터 데이터를 수신 할 때 호출됩니다. 여기에 Wire.read (); 마스터에서 보낸 데이터를 읽는 기능.
8. Wire.requestFrom (주소, 수량);
사용: 이 기능은 마스터에서 슬레이브 장치에서 바이트를 요청하는 데 사용됩니다. Wire.read () 함수 는 슬레이브 장치에서 보낸 데이터를 읽는 데 사용됩니다.
주소: 바이트를 요청할 장치의 7 비트 주소
수량: 요청할 바이트 수
필요한 구성 요소
- Arduino Uno (2-Nos)
- 16X2 LCD 디스플레이 모듈
- 10K 전위차계 (4-Nos)
- 브레드 보드
- 전선 연결
회로도
작업 설명
Arduino에서 I2C 통신 을 시연 하기 위해 두 개의 16X2 LCD 디스플레이가 서로 연결된 두 개의 Arduino UNO를 사용하고 두 arduino에서 두 개의 전위차계를 사용하여 마스터에서 슬레이브로, 슬레이브에서 마스터로의 전송 값 (0 ~ 127)을 결정합니다. 전위차계.
전위차계를 사용하여 arduino 핀 A0의 입력 아날로그 값을 (0 ~ 5V)에서 가져와 Analog to Digital 값 (0 ~ 1023)으로 변환합니다. 그런 다음 I2C 통신을 통해 7 비트 데이터 만 보낼 수 있으므로 이러한 ADC 값은 (0 ~ 127)로 추가 변환됩니다. I2C 통신은 두 arduino의 A4 및 A5 핀에서 두 개의 와이어를 통해 이루어집니다.
Slave Arduino의 LCD 값은 마스터 측에서 POT를 변경하여 변경되며 그 반대의 경우도 마찬가지입니다.
Arduino의 I2C 프로그래밍
이 튜토리얼에는 마스터 Arduino 용 프로그램과 슬레이브 Arduino 용 프로그램이 있습니다. 양측을위한 완전한 프로그램 은 데모 비디오 와 함께이 프로젝트의 끝에 제공됩니다.
마스터 Arduino 프로그래밍 설명
1. 먼저 I2C 통신 기능을 사용하기위한 Wire 라이브러리 와 LCD 기능을 사용하기위한 LCD 라이브러리 를 포함 해야 합니다. 16x2 LCD 용 LCD 핀도 정의합니다. 여기에서 Arduino와 LCD 인터페이스에 대해 자세히 알아보십시오.
#포함
2. void setup ()에서
- Baud Rate 9600에서 직렬 통신을 시작합니다.
Serial.begin (9600);
- 다음으로 핀 (A4, A5)에서 I2C 통신을 시작합니다.
Wire.begin (); // 핀 (A4, A5)에서 I2C 통신 시작
- 다음으로 LCD 디스플레이 모듈을 16X2 모드로 초기화하고 환영 메시지를 표시하고 5 초 후에 지 웁니다.
lcd.begin (16,2); // LCD 디스플레이 초기화 lcd.setCursor (0,0); // 디스플레이 첫 줄에 커서 설정 lcd.print ("Circuit Digest"); // LCD에 CIRCUIT DIGEST를 출력합니다. lcd.setCursor (0,1); // 디스플레이의 두 번째 줄에 커서를 설정합니다. lcd.print ("I2C 2 ARDUINO"); // LCD delay (5000); 에 I2C ARDUINO를 출력합니다 . // 5 초간 지연 lcd.clear (); // LCD 디스플레이를 지 웁니다.
3. void loop ()에서
- 먼저 슬레이브에서 데이터를 가져와야하므로 슬레이브 주소 8과 함께 requestFrom ()을 사용하고 1 바이트를 요청합니다.
Wire.requestFrom (8,1);
받은 값은 Wire.read ()를 사용하여 읽습니다.
바이트 MasterReceive = Wire.read ();
- 다음으로 핀 A0에 연결된 마스터 arduino POT에서 아날로그 값을 읽어야합니다.
int potvalue = analogRead (A0);
이 값을 1 바이트로 0에서 127로 변환합니다.
바이트 MasterSend = map (potvalue, 0,1023,0,127);
- 다음으로 변환 된 값을 보내야하므로 8 개의 주소로 슬레이브 arduino로 전송을 시작합니다.
Wire.beginTransmission (8); Wire.write (MasterSend); Wire.endTransmission ();
- 다음으로 500 마이크로 초의 지연으로 슬레이브 arduino에서 수신 된 값을 표시하고 해당 값을 지속적으로 수신하고 표시합니다.
lcd.setCursor (0,0); // LCD의 첫 번째 줄에 Currsor를 설정합니다. lcd.print (">> Master <<"); // Prints >> Master << at LCD lcd.setCursor (0,1); // LCD의 두 번째 줄에 커서를 설정합니다. lcd.print ("SlaveVal:"); // SlaveVal 인쇄: LCD에서 lcd.print (MasterReceive); // Slave로부터받은 MasterReceive를 LCD에 출력 Serial.println ("Master Received From Slave"); // 직렬 모니터에 인쇄 Serial.println (MasterReceive); 지연 (500); lcd.clear ();
슬레이브 Arduino 프로그래밍 설명
1. 마스터와 동일하게 먼저 I2C 통신 기능을 사용하기위한 Wire 라이브러리 와 LCD 기능을 사용하기위한 LCD 라이브러리 를 포함 해야 합니다. 16x2 LCD 용 LCD 핀도 정의합니다.
#포함
2. void setup ()에서
- Baud Rate 9600에서 직렬 통신을 시작합니다.
Serial.begin (9600);
- 다음으로 슬레이브 주소가 8 인 핀 (A4, A5)에서 I2C 통신을 시작합니다. 여기서 슬레이브 주소를 지정하는 것이 중요합니다.
Wire.begin (8);
다음으로 Slave가 master로부터 값을 받고 Master가 Slave로부터 값을 요청할 때 함수를 호출해야합니다.
Wire.onReceive (receiveEvent); Wire.onRequest (requestEvent);
- 다음으로 LCD 디스플레이 모듈을 16X2 모드로 초기화하고 환영 메시지를 표시하고 5 초 후에 지 웁니다.
lcd.begin (16,2); // LCD 디스플레이 초기화 lcd.setCursor (0,0); // 디스플레이 첫 줄에 커서 설정 lcd.print ("Circuit Digest"); // LCD에 CIRCUIT DIGEST를 출력합니다. lcd.setCursor (0,1); // 디스플레이의 두 번째 줄에 커서를 설정합니다. lcd.print ("I2C 2 ARDUINO"); // LCD delay (5000); 에 I2C ARDUINO를 출력합니다 . // 5 초간 지연 lcd.clear (); // LCD 디스플레이를 지 웁니다.
3. 다음으로 요청 이벤트에 대한 기능과 수신 이벤트에 대한 기능이 있습니다.
요청 이벤트
슬레이브에서 마스터 값을 요청하면이 기능이 실행됩니다. 이 함수는 Slave POT에서 입력 값을 가져와 7 비트로 변환하여 해당 값을 마스터로 보냅니다.
void requestEvent () { int potvalue = analogRead (A0); 바이트 SlaveSend = map (potvalue, 0,1023,0,127); Wire.write (SlaveSend); }
수신 이벤트
마스터가 슬레이브 주소 (8)로 데이터를 슬레이브로 전송하면이 기능이 실행됩니다. 이 함수는 master에서받은 값을 읽고 byte 유형의 변수에 저장 합니다.
void receiveEvent (int howMany { SlaveReceived = Wire.read (); }
4. Void loop ()에서:
마스터로부터받은 값을 LCD 디스플레이 모듈에 지속적으로 표시합니다.
void loop (void) { lcd.setCursor (0,0); // LCD의 첫 번째 줄에 Currsor를 설정합니다. lcd.print (">> Slave <<"); // Prints >> Slave << at LCD lcd.setCursor (0,1); // LCD의 두 번째 줄에 커서를 설정합니다. lcd.print ("MasterVal:"); // MasterVal 인쇄: LCD에서 lcd.print (SlaveReceived); // Master로부터받은 SlaveReceived 값을 LCD에 출력 Serial.println ("Slave Received From Master:"); // 직렬 모니터에 인쇄 Serial.println (SlaveReceived); 지연 (500); lcd.clear (); }
에 의해 한쪽에서 전위차계 회전, 다른 측면에서 LCD에 다양한 값을 볼 수 있습니다:
그래서 이것이 Arduino에서 I2C 통신이 이루어지는 방식입니다. 여기에서는 두 개의 Arduino를 사용하여 데이터 전송뿐만 아니라 I2C 통신을 사용하여 데이터를 수신하는 것을 보여줍니다. 이제 모든 I2C 센서를 Arduino에 연결할 수 있습니다.
마스터 및 슬레이브 Arduino의 전체 코딩은 데모 비디오와 함께 아래에 제공됩니다.