재료

  • USB 케이블 1개
  • 점프 와이어 4개
  • 아두이노 우노 2개

 앞에서 I2C 통신의 개념에 대해서 설명했으니 이제부터는 본격적으로 I2C 통신을 이용하여 아두이노  간에 통신하는 프로젝트를 진행해보도록 하겠습니다.

 I2C 통신은 SCL(Serial clock)과 SDA(Serial data)의 2개의 통신선을 이용하여 주변의 다른 장치들과 연결됩니다. 우리가 사용하고 있는 아두이노 우노에서는 아날로그 5번 핀이 SCL로 사용되고, 아날로그 4번 핀이 SDA로 사용됩니다. 먼저 아두이노 간 통신에 대해서 간단하게 실습하고, 응용 프로젝트를 통해서 LCD에 결과를 출력해보도록 합시다.




STEP1. 준비물

아두이노 보드 2개, USB 케이블 1개, 점프 와이어 4개



STEP2. 회로도




STEP3. 코드

먼저 Master 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <Wire.h>
#define SLAVE 4 // 슬레이브 주소
 
void setup() {
  Wire.begin(); // Wire 라이브러리 초기화
  Serial.begin(9600); // 직렬 통신 초기화
  Serial.println("I2C");
}
 
void loop() {
  i2c_communication(); // 슬레이브로 데이터 요구 및 수신 데이터 처리
  delay(1000);
}
 
void i2c_communication() {
  Wire.requestFrom(SLAVE, 1); // 1 바이트 크기의 데이터 요청
  char c = Wire.read(); // 수신 데이터 읽기
  Serial.println(c); // 수신 데이터 출력
}


그 다음 Slave 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <Wire.h>
#define SLAVE 4
byte count = 'A'// 카운터
 
void setup() {
  // Wire 라이브러리 초기화
  // 슬레이브로 참여하기 위해서는 주소를 지정해야 한다.
  Wire.begin(SLAVE);
  // 마스터의 데이터 전송 요구가 있을 때 처리할 함수 등록
  Wire.onRequest(sendToMaster);
}
 
void loop () {
}
 
void sendToMaster() {
  Wire.write(count++); // 카운터 값을 증가시키고 마스터로 전송
  
  if(count > 'Z'){
    count = 'A';
  }
}


한 쪽 아두이노 보드에 먼저 케이블을 연결하셔서 스케치를 업로드하시고, 그 다음에 다른 쪽 아두이노 보드에 케이블을 연결하신 후 스케치를 업로드하시면 됩니다. 다만 주의하실 점이, 케이블을 다른 아두이노에 연결할 때 케이블 포트 넘버가 바뀌게 됩니다. 그래서 다시 툴에 들어가서 포트를 연결해주신 후에 스케치를 업로드해주시면 됩니다.

 간단한 코드 설명을 하자면, slave가 입력을 하면 그 입력값을 받아와 master에서 출력을 해주는 코드입니다. slave가 A에서 Z까지의 문자를 반복해서 보내주고, master는 그 입력값을 받아와 시리얼 모니터에 출력해줍니다. Master에 맞는 포트로 연결하신 후에 시리얼 모니터를 켜시면 출력 결과를 확인할 수 있습니다.


STEP4. 결과 확인


 slave에서 보낸 값을 master가 읽어와서 serial monitor에 출력하는 것을 확인할 수 있습니다. 처음에는 A가 출력되어야 하는데, 이상한 사각형이 출력되는 것으로 보이네요. 이것은 아직 master로 입력값이 전송되지 않아서 이상한 문자가 출력되어 그렇습니다. Z까지 다 출력된 다음에는 A부터 출력되는 것을 아래의 사진을 통해서 확인할 수 있습니다.



STEP5. 응용

 이제는 slave에서 보낸 값을 master에서 읽어와서 LCD에 출력하도록 해봅시다.

우선 아래와 같이 회로를 구성해주세요.



LCD를 연결하는 부분은 출력을 담당할 부분이기 때문에 master에 꽂아주셔야 합니다. LCD 연결은 자주해보셨으니 어렵지 않으실거에요. LCD 연결은 항상 해왔던 것처럼 그대로 해주시면 됩니다. <LCD 구동하기>로 가시면 더 보기 쉽게 나와있습니다.

그런 후에 master코드를 업로드해주시고,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <Wire.h>
#include <LiquidCrystal.h>
#define SLAVE 4
 
LiquidCrystal lcd(12,11,5,4,3,2);
 
void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  lcd.begin(16,2);
  lcd.print("Hello, I2C!");
}
 
void loop() {
  // put your main code here, to run repeatedly:
  i2c_communication();
  delay(1000);
}
 
void i2c_communication() {
  Wire.requestFrom(SLAVE, 1); // 1 바이트 크기의 데이터 요청
  char c = Wire.read(); // 수신 데이터 읽기
 
  lcd.setCursor(0,1);
  lcd.print("Output : ");
  lcd.print(c);
}


slave 코드를 업로드해주세요.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <Wire.h>
#define SLAVE 4
byte count = 'A'// 카운터
 
void setup() {
  // Wire 라이브러리 초기화
  // 슬레이브로 참여하기 위해서는 주소를 지정해야 한다.
  Wire.begin(SLAVE);
  // 마스터의 데이터 전송 요구가 있을 때 처리할 함수 등록
  Wire.onRequest(sendToMaster);
}
 
void loop () {
}
 
void sendToMaster() {
  Wire.write(count++); // 카운터 값을 증가시키고 마스터로 전송
  
  if(count > 'Z'){
    count = 'A';
  }
}


그럼 LCD를 통해서 아래와 같은 결과가 출력되는 것을 확인할 수 있습니다.



댓글 1

손에 잡히는 아두이노

I2C 통신을 이용하여 아두이노 간 통신하기

by 김민정

MADE BY

김민정

사물인터넷, 아두이노