-
아두이노 I2C 통신 | LCD I2C 모듈Technology/Arduino 2024. 6. 14. 18:00
1. I2C 통신
두 장치가 일대일로 통신하는 시리얼 통신과는 다르게, I2C(Inter-Integrated Circuit) 통신은 한 컨트롤러(master)에 여러 개의 주변 장치(slave)를 연결하여 신호를 주고 받는다. I2C 통신은 데이터를 보내는 직렬 데이터 라인(Serial Data, SDA)과 데이터를 구분하는 직렬 클럭 라인(Serial Clock, SCL)으로 구성되어 있으며, 컨트롤러와 모든 주변 장치가 두 가닥의 신호선을 공유한다. 컨트롤러와 I2C 통신을 하는 모든 주변 장치는 자기만의 주소를 가지고 있는데, 통신할 때 해당 정보를 직렬 데이터 라인에 포함시켜 신호를 주고 받는다.
아두이노 플랫폼에서도 I2C 통신을 지원하므로, 아두이노 하드웨어에 I2C 통신을 위한 SDA핀과 SCL핀이 기본적으로 탑재되어 있다. 그러나 아두이노 우노는 제조사에 따라 해당 핀들이 구현되어 있지 않을 수 있는데, 이때 아두이노 우노의 아날로그 입력 A4번 핀을 SDA핀으로, A5번 핀을 SCL핀으로 사용할 수 있다.
2. I2C 주소 확인
아두이노 하드웨어로 주변 장치와 I2C 통신을 하기에 앞서, 해당 장치의 주소를 알아내야 한다. 아두이노 플랫폼에서는 I2C 통신을 위한 라이브러리를 기본적으로 제공하고 있으며, I2C 주소를 확인하기 위한 예제도 제공하고 있다. 주변 장치의 I2C 주소를 확인하는 예제는 아래에 첨부해놓았으니, 해당 프로그램을 실행시켜 시리얼 모니터에서 주변 장치의 I2C 주소를 확인하면 된다. 아래 링크로 접속하면 I2C 통신 라이브러리에 대한 설명과 사용방법을 확인할 수 있다.
3. LCD I2C 모듈
앞서 살펴보았던 LCD 모듈을 제어하기 위해서는 디지털 입출력 핀 6개를 사용해야 한다. 단독으로 사용할 때에는 크게 문제가 없겠지만, 다양한 센서와 구동기를 사용하는 프로젝트에서는 디지털 입출력 핀이 부족할 수 있다. 이때 I2C 통신을 지원하는 LCD 모듈을 사용하면 아날로그 입력 핀 2개로 LCD 모듈을 제어할 수 있다. I2C 통신 회로가 연결된 LCD 모듈은 아래 링크로 접속하면 구매할 수 있다.
4. 아두이노 라이브러리 추가
아두이노 플랫폼에서 I2C 통신을 이용해 LCD를 제어하더라도 사용자가 이를 직관적으로 다룰 수 있도록, LCD와 I2C 통신하는 라이브러리를 보유하고 있다. 그러나 앞서 사용해보았던 'LiquidCrystal' 라이브러리처럼 기본적으로는 제공되지 않기 때문에, 라이브러리를 IDE에 추가하는 과정이 필요하다. 아두이노 IDE 상단 툴바에서 '툴'을 선택한 뒤 '라이브러리 관리' 항목을 선택하자. 그러면 곧이어 '라이브러리 매니저' 창이 나타난다. '라이브러리 매니저' 창 오른쪽 상단에 라이브러리 이름을 입력하면 아두이노 플랫폼에서 지원하는 라이브러리를 검색할 수 있다. 해당 칸에 우리가 이번 예제에서 사용할 라이브러리 'LiquidCrystal I2C'를 입력하자. 라이브러리를 검색하면 입력한 검색어와 관련된 라이브러리 목록이 나타난다. LCD와 I2C 통신을 구현한 다양한 라이브러리가 있지만, 해당 예제에서는 라이브러리 'LiquidCrystal I2C' 버전 1.1.2를 설치하도록 하겠다. 아래 링크로 접속하면 해당 라이브러리에 대한 설명과 사용방법을 확인할 수 있다.
5. 예제
5.1. 회로 구성
5.2. 프로그램 작성 - I2C 주소 확인
#include <Wire.h> // I2C 통신 라이브러리 추가 void setup() { Wire.begin(); // I2C 통신 시작 Serial.begin(9600); // 시리얼 통신 시작 (통신 속도: 9600 bps) while (!Serial); // Leonardo: wait for serial monitor Serial.println("\nI2C Scanner"); // 시리얼 모니터에 문자열 출력 후 줄 바꿈 } void loop() { int nDevices = 0; // 정수형 변수 선언 후 0으로 초기화 Serial.println("Scanning..."); // I2C 주소 탐색 for (byte address = 1; address < 127; ++address) { Wire.beginTransmission(address); // 주소 address를 가진 장치에 전송 시작 byte error = Wire.endTransmission(); // 전송 종료 후 통신 결과를 바이트 변수에 저장 // 주변 장치를 찾아 I2C 통신에 성공했을 경우 if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) { Serial.print("0"); } Serial.print(address, HEX); Serial.println(" !"); ++nDevices; } // 주변 장치와의 I2C 통신에 오류가 있을 경우 else if (error == 4) { Serial.print("Unknown error at address 0x"); if (address < 16) { Serial.print("0"); } Serial.println(address, HEX); } } // I2C 통신에 성공한 주변 장치가 없을 경우 if (nDevices == 0) { Serial.println("No I2C devices found\n"); } else { Serial.println("done\n"); } delay(5000); // Wait 5 seconds for next scan }
5.3. 프로그램 작성 - LCD I2C 모듈 제어
#include <LiquidCrystal_I2C.h> // LCD I2C 라이브러리 추가 // LCD라는 이름의 LCD I2C 객체 생성 LiquidCrystal_I2C LCD(0x20, 16, 2); // I2C 주소, 열과 행의 개수 입력 void setup() { LCD.init(); // LCD 사용 시작 LCD.backlight(); // LCD 백라이트 켜기 LCD.print("HELLO WORLD!"); // LCD에 문자열 출력 delay(1000); // 1000 ms 대기 } void loop() { LCD.setCursor(0, 1); // LCD 커서를 0열 1행으로 이동 LCD.print("WELCOME TO THE VEDACUBE"); delay(1000); // LCD에 출력된 문자열을 왼쪽으로 13칸 이동 for (int i = 0; i < 7; i++) { LCD.scrollDisplayLeft(); delay(100); } delay(1000); // LCD에 출력된 문자열을 오른쪽으로 29칸 이동 for (int i = 0; i < 23; i++) { LCD.scrollDisplayRight(); delay(100); } // LCD에 출력된 문자열을 왼쪽으로 16칸 이동 for (int i = 0; i < 16; i++) { LCD.scrollDisplayLeft(); delay(100); } delay(1000); LCD.clear(); // LCD에 출력된 문자열을 모두 삭제 delay(1000); }
[함께 읽으면 좋은 페이지]
참고문헌
- 최훈. (2022). 팅커캐드 & 아두이노. 길벗캠퍼스.
- DroneBot Workshop. (2018). Using LCD Displays with Arduino. YouTube. https://www.youtube.com/watch?v=wEbGhYjn4QI. 2023.11.03.
- Rohde Schwarz. (2023). Understanding I2C. YouTube. https://www.youtube.com/watch?v=CAvawEcxoPU. 2024.11.22.
반응형'Technology > Arduino' 카테고리의 다른 글
아두이노 프로젝트 | 디지털 도어락 (0) 2024.06.28 아두이노 라이브러리 | 키패드 (0) 2024.06.21 아두이노 라이브러리 | LCD 모듈 (0) 2024.04.12 아두이노 프로젝트 | 디지털 타이머 (0) 2024.04.05 아두이노 프로젝트 | 디지털 카운터 (0) 2024.03.29