이 블로그는 Web 환경을 이용한 원격 제어 기술에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 WiFi Module과 Raspberry Pi, Raspberry Pi Pico, ATmega128 보드, Arduino Mega 보드(ATmega2560)를 사용 합니다.

i2c-arduino

ESP32 I2C - Arduino
ESP8266/ESP32 I2C(Inter-Integrated Circuit) 통신 - Arduino


  • ESP8266/ESP32 I2C 통신
    • ESP8266/ESP32 I2C 개요
      • I2C는 2개의 Bus line을 사용하여 장치 간 통신을 한다. SCL(클럭)과 SDA(데이터) 2개의 통신 선을 사용한다.

        I2C는 프로세서 및 마이크로 컨트롤러에 저속 주변 장치(외부 EEPROM, 디지털 온도 센서, LCD 컨트롤러, OLED 디스플레이, RTC 등)를 부착하는 데 널리 사용된다.

        참고자료: ATmega128 I2C 통신

      • I2C 동작 모드 와 통신 속도
        • 원래 I2C 버스의 동작 속도는 100kbit/s 이다. 그러나 시간이 지남에 따라 몇 가지 사양이 추가되어 현재는 아래와 같이 5가지 작동 속도를 갖는다. 표준 모드, 고속 모드(Fm), 고속 모드 플러스(Fm+) 및 고속 모드(Hs 모드)

        • Standard-Mode(Sm): 최대 100kbit/s의 비트 전송률
        • Fast-Mode(Fm): 최대 400kbit/s의 비트 전송률
        • Fast-Mode Plus(Fm+): 최대 1Mbit/s의 비트 전송률
        • High-speed Mode(Hs-mode): 최대 3.4Mbit/s의 비트 전송률
        • Ultra Fast-Mode(UFm): 최대 5 Mbit/s의 비트 전송률. 이 모드는 단방향 버스(Unidirectional bus)만 지원한다.
        • 주: 실제 본인이 사용하는 I2C 모듈이 지원하는 동작 모드를 알기 위하여는 데이터시트를 참조해야 한다.

      • I2C 장치 주소 지정(Addressing)
        • I2C 표준은 2개의 주소 지정 모드를 지원한다.

        • 기본 모드(default mode)는 7비트 주소 지정 모드로 최대 127개의 다른 장치와 통신할 수 있다(0x00 주소는 I2C 표준에 의해 예약됨).
        • 또한 주소를 지정할 수 있는 장치의 수를 크게 확장하는 10비트 주소 지정 모드가 있다. 실제 버스에 열결할 수 있는 장치의 수는 버스 커패시턴스(Bus capacitance)에 의해 제한을 받으며 경우에 따라 I2C 버스 브리지/멀티플렉서를 사용하여야 한다.
      • ESP8266/ESP32 I2C 모듈
        • ESP32 SoC에는 2개(ESP8266은 1개)의 I2C 인터페이스 컨트롤러(I2C0, I2C1)가 있다. 두개의 컨트롤러는 기능이 동일하며 각 I2C 컨트롤러의 주요 기능은 다음과 같다.

        • 마스터(Master) 모드와 슬레이브(Slave) 모드 모두를 지원한다.
        • 다중 마스터(multi-master) 및 다중 슬레이브(multi-slave) 통신 지원
        • 표준 모드 지원(100kbit/s)
        • Fast-Mode(Fm) 모드 지원(400kbit/s)
        • 7비트 Addressing 과 10비트 Addressing 지원
      • ESP8266/ESP32 I2C 기본 핀
        • 모든 ESP8266/ESP32 주변 장치는 GPIO 매트릭스를 통해 내부적으로 함께 연결되어 원칙적으로 임의의 GPIO Pin을 I2C 통신에 사용할 수 있다.

        • Arduino 환경에서는 ESP32는 Default I2C0 pins으로 SCA는 GPIO21, SCL은 GPIO22를 사용하고, ESP8266는 Default I2C0 pins으로 SCA는 GPIO4, SCL은 GPIO5를 사용한다.
        • Arduino Wire library를 사용할 때 Wire.begin(); 함수를 사용하면 Default I2C0 pins을 사용하게 된다.
        • Wire.begin(SDA_0, SCL_0); 형태의 함수를 사용하면 직접 사용자가 GPIO 핀(SDA, SCL)을 지정하여 사용할 수 있다.
        • 또한 TwoWire 개체를 사용하여 직접 사용자가 GPIO 핀을 지정하여 사용할 수 있다.
      • ESP8266/ESP32 기본 I2C 핀(SDA, SCL Pin) 변경하기
        • Arduino Core I2C driver 사용하기
          • Arduino Core I2C 드라이버 "Wire.h"를 include 하면 기본적으로 I2C0 가 I2C 장치로 설정되고(SDA & SCL) 라인은 Default I2C0 pins이 기본으로 설정된다.
          • 그러나 아래 예와 같이 I2C 기본 핀을 변경하여 SDA 와 SCL 신호를 원하는 GPIO 핀으로 라우팅할 수 있다.
          • Wire.begin(SDA0_Pin, SCL0_Pin);

            위에서 SDA0_Pin은 SDA에 사용할 GPIO Pin 번호이고, SCL0_Pin은 SCL에 사용할 GPIO Pin 번호이다.

        • TwoWire object 사용하기
        • 아래 예와 같이 TwoWire object를 사용하면 보다 유연하게 I2C 설정을 변경할 수 있다.


    • Arduino에서 자주 사용하는 Wire Library 함수
      • Wire.begin()
      • I2C 통신을 초기화하고, 활성화하는 함수이다. I2C 모듈을 마스터 또는 슬레이브로 설정한다. 이 함수는 보통 한 번만 호출되어야 한다.

        • Wire.begin(): I2C 통신을 초기화하고 마스터 모드로 설정한다.
        • Wire.begin(address): I2C 통신을 초기화하고 슬레아브 모드로 설정한다.
        • Returns: None
      • Wire.requestFrom()
      • 마스터가 슬레이브 장치에서 Data(Bytes)를 요청하는 데 사용한다. 그런 다음 available() 또는 read() 함수를 사용하여 Bytes를 검색할 수 있다.

        • Wire.requestFrom(address, quantity)
          • address: Bytes를 요청할 장치의 7비트 주소
          • quantity: 요청하는 Bytes 수
        • requestFrom()의 동작을 변경하는 부울 인수
        • Arduino 1.0.1부터 requestFrom()은 특정 I2C 장치와의 호환성을 위해 동작을 변경하는 부울 인수를 허용한다.

          • true: 요청 후 중지 메시지를 보내 버스를 해제(stop은 true에 해당함)한다.
          • false: false는 request 후 restart 메시지를 다시 보내 계속해서 연결을 활성 상태로 유지한다.
          • 주: 동작을 변경하는 부울 인수가 생략된 경우 Default 값은 true 이다.

        • Wire.requestFrom(address, quantity, stop)
          • stop: 요청 후 중지 메시지를 보내 버스를 해제(stop은 true에 해당함)한다. 동작을 변경하는 부울 인수를 true로 설정한 경우와 동일하다.
        • Returns: 슬레이브 장치에서 반환된 바이트 수가 Return 된다.
      • Wire.beginTransmission(address)
      • 주어진 주소의 I2C 슬레이브 장치로 전송을 시작한다. 이 명령 후 write() 함수를 사용하여 전송할 바이트를 큐(queue)에 넣고 endTransmission()을 호출하여 전송한다.

        • address: 전송할 장치의 7비트 주소
        • Returns: None
      • Wire.endTransmission()
      • beginTransmission()에 의해 시작된 슬레이브 장치로의 전송을 종료하고 write()에 의해 대기 중인 바이트를 전송다.

        • endTransmission()의 동작을 변경하는 부울 인수
        • Arduino 1.0.1부터 endTransmission()()은 특정 I2C 장치와의 호환성을 위해 동작을 변경하는 부울 인수를 허용한다.

          • true: 요청 후 중지 메시지를 보내 버스를 해제(stop은 true에 해당함)한다.
          • false: false인 경우 endTransmission()은 전송 후 restart 메시지를 보낸다. 버스가 해제되지 않아 다른 마스터 장치가 메시지 간에 전송하는 것을 방지할 수 있다. 이를 통해 하나의 마스터 장치가 제어 중에 여러번 전송할 수 있다.
          • 주: 동작을 변경하는 부울 인수가 생략된 경우 Default 값은 true 이다.

        • Wire.endTransmission(stop)
          • stop: 전송 후 중지 메시지를 보내 버스를 해제(stop은 true에 해당함)한다. 동작을 변경하는 부울 인수를 true로 설정한 경우와 동일하다.
        • Returns: 전송 상태를 나타내는 바이트
          • 0: 성공
          • 1: 데이터가 너무 길어 전송 버퍼에 맞지 않음
          • 2: 주소 전송 시 NACK 수신
          • 3: 데이터 전송 시 NACK 수신
          • 4: 기타 오류
      • Wire.write()
      • 마스터 모드에서는 마스터에서 슬레이브 장치로의 전송을 위해 Data(Bytes)를 큐(Queue)에 넣는다. beginTransmission() 함수와 endTransmission() 함수 사이에 위치한다. Wire.write() 함수로 큐(Queue)에 저장된 데이터는 endTransmission() 함수가 호출될 때 한꺼번에 전송된다.

        슬레이브 모드에서는 마스터의 요청에 대한 응답으로 슬레이브 장치의 데이터를 전송하기 위하여 사용된다.

        • Wire.write(value)
          • value: 전송할 값(Single byte data)
        • Wire.write(string)
          • string: 전송할 문자열(Byte 단위)
        • Wire.write(data, length)
          • data: 전송할 데이터 배열(Byte 단위)
          • length: 전송할 바이트 수
        • Returns
          • byte: write() 함수가 Write한 바이트 수. Return 값을 읽는 것은 선택 사항이다.
      • Wire.available()
      • read()로 읽을 수 있는 바이트 수를 반환한다. 이 함수는 마스터 장치 requestFrom() 함수를 실행한 다음, 또는 슬레이브에서 onReceive() 핸들러(Handler) 내부에서 호출되어야 한다.

        • Returns
          • byte: 읽을 수 있는 바이트 수
        • 슬레이브에서 Wire.available() 함수 이용 예
          • 아래 예와 같이 onReceive() 핸들러(Handler) 내부에서 호출되어야 한다.
      • Wire.read()
      • requestFrom() 호출 후 슬레이브 장치에서 마스터로 전송되었거나 마스터에서 슬레이브로 전송된 바이트를 읽는다.

        • Returns
          • 수신된 바이트 데이터
      • Wire.SetClock(clockFrequency)
      • I2C 통신을 위한 클럭 주파수를 수정한다. I2C 슬레이브 장치에는 최소 작동 클럭 주파수가 없지만 일반적으로 100KHz를 사용한다.

        • clockFrequency: ESP32에서는 100kbit/s(Standard-Mode) 또는 400kbit/s(Fast-Mode)를 사용한다.
        • Returns: None
      • Wire.onReceive(handler)
      • 슬레이브 장치가 마스터로부터 전송된 데이터를 수신할 때 호출될 함수(handler)를 등록한다.

        • handler: 슬레이브가 데이터를 수신할 때 호출되는 함수.
        • 이 함수는 하나의 int 매개변수(마스터에서 읽은 바이트 수)를 갖는다.
        • 예: void myHandler(int numBytes)
        • Returns: None
      • Wire.onRequest(handler)
      • 마스터가 슬레이브 장치에 데이터를 요청할 때 호출할 함수를 등록한다.

        • handler: 호출될 함수는 매개변수를 사용하지 않으며 아무 것도 반환하지 않는다.
        • 예: void myHandler()
        • Returns: None

    • I2C 통신을 이용한 측정 과 제어 시스템 구성 예
    • I2C 통신을 이용한 측정 과 제어 시스템 구성도

      주: I2C Pull-Up 저항은 ESP 모듈에 내장되어 있기 때문에 이 구성도에는 생략되었음.


    • ESP8266/ESP32 I2C Address scanner
      • 다음 프로그램은 I2C Bus에 연결된 모든 장치의 주소(7비트 = 0x00을 제외한 127개의 가능한 주소)를 확인한다. I2C 장치에 주소를 전송한 다음 ACK가 있으면 해당 주소에 작동하는 I2C 장치가 있다는 의미이므로 주소를 출력한다. ACK(NACK)이 수신되지 않으면 다음 주소로 이동한다.

      • I2C Bus에 연결된 모든 장치를 검색하는 프로그램 예: i2c-address-scanner.ino
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 주: ESP8266 Node MCU 보드를 사용하는 경우 툴 -> 보드: "보오드 이름" -> NodeMCU 1.0(ESP-12E Module)를 선택하고, NodeMCU-32S 보드를 사용하는 경우 툴 -> 보드: "보오드 이름" -> NodeMCU-32S를 선택한다. 기타 보드를 사용하는 경우 자신이 사용하는 보오드 이름을 확인 하여야 한다.

        • 위 프로그램을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • SDA와 SCL의 Pin 번호를 자신의 보드에 맞게 편집한다. ESP32인 경우 21번, 22번, ESP8266인 경우 4번, 5번을 사용한다.
        • 편집 창의 프로그램을 File name "i2c-address-scanner.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면(NodeMCU ESP8266 개발보드는 GPIO0를 프로그램에서 제어하기 때문에 GPIO0 SW를 누르지 않아도 됨) 개발 보드에 업로드가 시작된다.
          • 업로드가 완료되면 자동으로 프로그램이 시작된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열리고 I2C Bus에 연결된 I2C 모듈의 주소가 출력된다. 필요한 경우 보드레이트를 115200로 설정한다. 시리얼 모니터 창이 열리기 전에 프로그램이 종료된 상태이면 개발 보드의 Reset SW를 사용하여 프로그램을 다시 실행한다.
    • DS1621을 사용한 온도 측정
      • 윗 I2C 통신을 이용한 측정 과 제어 시스템 구성 예에서 ESP8266/ESP32 개발보드를 Master로 디지털 온도 센서(DS1621)를 Slave device로 사용 한다. 이 예에서는 이해를 쉽게하기 위하여 온도측정에 필요한 최소한의 기능만 구현한다.

      • DS1621을 사용한 온도 측정 프로그램(Wire Library 사용) 예: i2c-ds1621-wire.ino

      • DS1621을 사용한 온도 측정 프로그램(TwoWire object 사용) 예: i2c-ds1621-two-wire.ino
      • 실험을 위한 준비
        • ESP8266/ESP32 개발보드와 온도 센서(DS1621)의 I2C 통신선 연결
          • ESP8266/ESP32 개발보드 SDA(GPIO4 or GPIO21) <-> DS1621 SDA(Pin1) : 2-wire serial 통신을 위한 Data input/output pin.
          • ESP8266/ESP32 개발보드 SCL(GPIO5 or GPIO22) <-> DS1621 SCL(Pin2) : 2-wire serial 통신을 위한 Clock input/output pin.
          • ESP8266/ESP32 개발보드 3.3V(or 5V) <-> DS1621 VDD(Pin8) : VDD pin.
          • ESP8266/ESP32 개발보드 GND <-> DS1621 GND(Pin4) : Ground pin.
        • 온도센서 번호(번지) 설정 하기
          • DS1621의 Pin7(A0), Pin6(A1), Pin5(A2)를 사용하여 온도 센서의 번호(번지)를 설정 한다.
          • 온도 센서의 번호(번지)를 설정 예
          • 0번(이 예에서는 0번 장치를 0x48 번지로 설정 하였다.): A0 <- GND, A1 <- GND, A2 <- GND

      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램(i2c-ds1621-wire or i2c-ds1621-two-wire)을 복사하여 Arduino IDE의 편집 창에 복사한다.
        • SDA와 SCL의 Pin 번호를 자신의 보드에 맞게 편집한다. ESP32인 경우 21번, 22번, ESP8266인 경우 4번, 5번을 사용한다.
        • 편집 창의 프로그램을 File name "i2c-ds1621-wire.ino" or "i2c-ds1621-two-wire.ino"로 저장 한다.
        • 실험
          • "업로드" Icon을 클릭하면 프로그램이 컴파일되고 개발보드로 전송이 시작되는 매세지(Connecting... )가 출력된다.
          • "Connecting... " 메세지가 출력된 다음 약 2Sec 동안 개발보드의 GPIO0 SW를 누르고 있으면(NodeMCU ESP8266 개발보드는 GPIO0를 프로그램에서 제어하기 때문에 GPIO0 SW를 누르지 않아도 됨) 개발 보드에 업로드가 시작된다.
          • 업로드가 완료되면 자동으로 프로그램이 시작된다.
          • "툴 -> 시리얼 모니터"를 실행하면 시리얼 모니터 창이 열리고 1초 간격으로 측정 결과가 출력된다. 필요한 경우 보드레이트를 115200로 설정한다.
          • DS1621 칩 위애 손을 대고 있으면 체온에 의하여 변동된 온도(보통 상승)가 출력된다.

        주: i2c-ds1621-wire.ino 과 i2c-ds1621-two-wire.ino는 동일한 기능을 실행하는 프로그램이다. TwoWire object를 사용하는 방식이 I2C 모듈의 선택 기능 등에서 보편성을 갖는다.


    • Master(ESP8266/ESP32) - Slave(ATmega128) I2C 통신 예
    • 이 예는 Master와 Slave(ESP8266/ESP32 개발보드를 Master로 ATmega128 보드를 Slave로 사용) 사이에 Data 통신을 하는 예 이다.

      • 프로그램 예
        • ESP8266/ESP32 개발보드 프로그램: i2c-avr_master_basic.ino
        • ATmega128 보드 프로그램: i2c-avr-slave-basic-arduino.ino
        • ATmega128 보드 프로그램(HEX): i2c-avr-slave-basic-arduino-atmega128.hex
      • 실험을 위한 준비
        • ESP8266/ESP32 개발보드와 ATmega128 보드의 I2C 통신선 연결
          • ESP8266/ESP32 개발보드 SDA(GPIO4 or GPIO21) <-> ATmega128 보드 SDA(PD1) : 2-wire serial 통신을 위한 Data input/output pin.
          • ESP8266/ESP32 개발보드 SCL(GPIO5 or GPIO22) <-> ATmega128 보드 SCL(PD0) : 2-wire serial 통신을 위한 Clock input/output pin.
          • ESP8266/ESP32 개발보드 GND <-> ATmega128 보드 GND : Ground pin.
          • 전원 연결: ESP8266/ESP32 개발보드는 3.3V, ATmega128 보드는 5V를 사용하는 경우가 많기 때문에 주의가 필요함. 이 경우는 각각 전원을 연결하고 GND 선만 공통으로 연결한다.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램(i2c-avr_master_basic.ino)을 Arduino IDE의 편집 창에 복사한다.
        • SDA와 SCL의 Pin 번호를 자신의 보드에 맞게 편집한다. ESP32인 경우 21번, 22번, ESP8266인 경우 4번, 5번을 사용한다.
        • i2c-avr_master_basic.ino을 저장한다.
        • "i2c-avr_master_basic.ino" 프로그램을 컴파일하여 ESP8266/ESP32에 Upload 한다.
        • ATmega128을 위한 별도의 Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램(i2c-avr-slave-basic-arduino.ino)을 복사하여 Arduino IDE의 편집 창에 복사한다음 저장한다.
        • "i2c-avr-slave-basic-arduino.ino" 프로그램을 컴파일하여 ATmega128에 Upload 한다.
        • 참고자료: Arduino 개발 환경에서 ATmega128보오드를 이용한 개발 예

          주: Arduino 개발 환경에서 ATmega128보오드를 이용한 개발환경이 준비되지 못한 경우 위 "i2c-avr-slave-basic-arduino-atmega128.hex" 파일을 Download 하여 ATmega128보오드에 설치 한다.

        • 실험
          • ESP8266/ESP32를 위한 Arduino IDE에서 "툴 -> 시리얼 모니터"를 실행하여 시리얼 모니터를 Open 한다.
          • ATmega128를 위한 Arduino IDE에서 "툴 -> 시리얼 모니터"를 실행하여 시리얼 모니터를 Open 한다. Arduino 개발 환경에서 ATmega128보오드를 이용한 개발환경이 준비되지 못한 경우 별도의 모니터 프로그램을 ATmega129의 UART0에 연결한다.
          • ESP8266/ESP32를 위한 Arduino IDE의 시리얼 모니터에서 메세지를 입력하면 ATmega128에 전송되어 ATmega128 시리얼 모니터 창에 메세지가 출력된다.
          • 메서지를 수신한 ATmega128에서 "AVR i2c testing" 메세지를 ESP32에 전송하고, ESP32의 시리얼 모니터 창에 "AVR i2c testing" 메세지가 출력된다.

    • I2C 통신(Master(ESP8266/ESP32) - Slave(ATmega128))을 이용한 LED 제어
    • 이 예는 ESP8266/ESP32 개발보드(Master)에서 I2C 통신을 이용하여 ATmega128 보드(Slave)의 LED를 제어하는 예 이다.

      • 프로그램 예
        • ESP8266/ESP32 개발보드 프로그램: i2c-avr-led-master.ino
        • ATmega128 보드 프로그램: i2c-avr-slave-led-arduino.ino
        • ATmega128 보드 프로그램(HEX): i2c-avr-slave-led-arduino.ino-atmega128.hex
      • 실험을 위한 준비는 "Master(ESP32) - Slave(ATmega128) I2C 통신 예"를 참고 바람.
      • 실험 방법
        • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 위 프로그램(i2c-avr-led-master.ino)을 Arduino IDE의 편집 창에 복사한다.
        • SDA와 SCL의 Pin 번호를 자신의 보드에 맞게 편집한다. ESP32인 경우 21번, 22번, ESP8266인 경우 4번, 5번을 사용한다.
        • i2c-avr-led-master.ino을 저장한다.
        • "i2c-avr-led-master.ino" 프로그램을 컴파일하여 ESP8266/ESP32에 Upload 한다.
        • ATmega128을 위한 별도의 Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다. ESP8266/ESP32와 다른 COM Port를 사용하여야 한다.
        • 위 프로그램(i2c-avr-slave-led-arduino.ino)을 복사하여 Arduino IDE의 편집 창에 복사한다음 저장한다.
        • "i2c-avr-slave-led-arduino.ino" 프로그램을 컴파일하여 ATmega128에 Upload 한다.
        • 참고자료: Arduino 개발 환경에서 ATmega128보오드를 이용한 개발 예

          주: Arduino 개발 환경에서 ATmega128보오드를 이용한 개발환경이 준비되지 못한 경우 위 "i2c-avr-slave-led-arduino.ino-atmega128.hex" 파일을 Download 하여 ATmega128보오드에 설치한다.

        • 실험
          • ESP8266/ESP32를 위한 Arduino IDE에서 "툴 -> 시리얼 모니터"를 실행하여 시리얼 모니터를 Open 한다.
          • ESP8266/ESP32를 위한 Arduino IDE의 시리얼 모니터에서 아래와 같은 Command를 입력(전송)하면 ATmega128에 전송되어 ATmega128의 LED를 제어하고 그 결과가 LED에 출력된다.
            • 'L': Left shift
            • 'R': Right shift
            • 'B': Blinking
            • 'S'+ Data: Set LED new data, Set command 예: S01010101
            • 'G': Get LED ststus

            주: 이 실험을 위하여는 ATmega128 보드의 PORTF에 LED Array가 연결되어 있어야 함.

            참고자료: Bit 정보를 보기 위한 8 Bits LED Bar 만들기

            주: 디버깅이 필요한 경우 ATmega129의 UART0에 모니터 프로그램을 연결하여 사용한다.

    • I2C 통신(Master(ESP8266/ESP32) - Slave(LCD 모듈))을 이용한 LCD Display 제어
    • 장치 제어에 사용하는 Microcontroller는 I/O Port의 수가 제한되어 있기 때문에 LCD 모듈 제어(보통 8 Bits 가 필요)와 같이 많은 I/O Ports를 필요로 하는 장치의 제어를 위하여 I2C 통신을 사용한 I/O Port 확장(8 Bits) 모듈을 사용 한다. 이 예는 I2C 통신을 사용한 I/O Port 확장(8 Bits) 모듈(PCF8574)을 이용하여 LCD 모듈을 제어하는 기술에 대하여 설명 한다.

      • I2C 통신을 사용한 LCD 모듈
        • I2C 통신을 사용한 I/O Port 확장(8 Bits) 모듈
          • SCL, SDA Pin은 I2C 통신에 사용 된다.
          • P0 - P7은 8 Bit Input/Output Port로 I/O Port 확장에 사용 한다.
          • A0 - A2는 Address를 설정하기 위하여 사용 한다.

        I2C 통신을 이용한 I/O Port 확장 Chip(PCF8574)의 Block diagram


        • I2C 통신을 사용한 LCD 모듈
          • I2C - LCD Module은 I2C - I/O Expander(PCF8574)와 LCD의 Contrast를 조정하는 회로(가변저항 포함), Backlight Control 회로로 구성 되어 LCD 모듈을 제어 한다.
          • I2C - LCD Module은 Microcontroller로 부터 I2C 통신을 이용하여 Data를 수신하고, 이 Data를 이용하여 LCD Module을 제어 한다.
          • I2C - LCD Module과 LCD Module은 함께 조립되어 판매 하기 때문에 이용자는 Microcontroller(AVR)과 I2C - LCD Module 사이의 4선(SCL, SDA, VCC, GND) 만 연결하면 된다.

          I2C 통신을 사용한 LCD 제어 시스템 구성도


          I2C - LCD Module 과 LCD Module(1602)을 통합한 제품 예

      • I2C - LCD Library를 사용한 프로그램 예
        • LCD Library 설치하기
          • "스케치 -> 라이브러리 포함하기 -> 라이브러리 관리..."를 실행하면 "라이브러리 매니저" 창이 열린다.
          • "라이브러리 매니저" 창에서 "TwiLiquidCrystal"을 검색하여 "TwiLiquidCrystal by Amakazim" Library를 설치한다.
          • 주: "TwiLiquidCrystal" 검색에서 여러 개의 Library가 List되는 경우 Library 설명에 "HD44780 based LCD" 이 포함된 Library를 설치하여야 한다.

            참고자료: "TwiLiquidCrystal" 검색 결과에서 "More info"를 클릭하면 "Arnakazim's TwiLiquidCrystal Arduino Library" Source code를 다운로드 할 수 있다.


        • TwiLiquidCrystal Library에 구현된 자주 사용하는 함수 예.
        • begin(uint8_t cols, uint8_t rows, uint8_t font = LCD_5x8DOTS)

          clear()

          home()

          setCursor(uint8_t col, uint8_t row = 0)

          backlight()

          noBacklight()

          sendCmd(uint8_t data)

          send(uint8_t byte)

          createChar(uint8_t index, uint8_t character[])

          command(uint8_t value)

          scrollDisplayLeft(void)

          scrollDisplayRight(void)

          cursor()

          noCursor()

          blink()

          noBlink()


          참고자료: 전체 함수는TwiLiquidCrystal.h를 참고바람.


        • LCD에 문자열을 출력하는 프로그램 예: i2c-LCD-HD44780-basic.ino
        • 이 예는 TwiLiquidCrystal Library를 사용하여 PCF8574를 통해 연결된(I2C) LCD Display(HD44780 호환)에 문자열을 출력하는 예 이다.

        • 실험을 위한 준비
          • ESP8266/ESP32 개발보드와 LCD 모튤의 I2C 통신선 연결
            • ESP8266/ESP32 개발보드 SDA(GPIO4 or GPIO21) <-> I2C 통신을 위한 I/O Port 확장 모듈(PCF8574)의 SDA Pin
            • ESP8266/ESP32 개발보드 SCL(GPIO5 or GPIO22) <-> I2C 통신을 위한 I/O Port 확장 모듈(PCF8574)의 SCL Pin
            • ESP8266/ESP32 개발보드 GND <-> I2C 통신을 위한 I/O Port 확장 모듈(PCF8574)의 Ground pin.
            • 전원 연결: ESP8266/ESP32 개발보드 5V <-> I2C 통신을 위한 I/O Port 확장 모듈(PCF8574)의 Vcc
        • 실험 방법
          • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
          • 위 프로그램(i2c-LCD-HD44780-basic.ino)을 Arduino IDE의 편집 창에 복사한다.
          • SDA와 SCL의 Pin 번호를 자신의 보드에 맞게 편집한다. ESP32인 경우 21번, 22번, ESP8266인 경우 4번, 5번을 사용한다.
          • i2c-LCD-HD44780-basic.ino을 저장한다.
          • "i2c-LCD-HD44780-basic.ino" 프로그램을 컴파일하여 ESP8266/ESP32에 Upload 한다.
          • 실험
            • 프로그램이 시작되면 LCD Display의 첫줄에 "LCD testing" 메세지가 출력된다.
            • 1초 간격으로 2번째 줄 첫자 위치에 Reset 부터 현재까지의 Sec 값이 출력된다.

      • LCD에 Custom char를 출력하고 제어하는 프로그램 예: i2c-LCD-HD44780-custom-char.ino
        • 이 예는 TwiLiquidCrystal Library를 사용하여 PCF8574를 통해 연결된(I2C) LCD Display(HD44780 호환)에 Custom char를 출력하고 제어하는 예 이다.


        • 실험을 위한 준비는 위 "LCD에 문자열을 출력하는 프로그램 예"와 같다.
        • 실험 방법
          • Arduino IDE를 실행하고 Arduino IDE의 툴 메뉴에서 사용 환경(보드와 COM Port 선택)이 바르게 되어 있는지 확인한다.
          • 위 프로그램(i2c-LCD-HD44780-custom-char.ino)을 Arduino IDE의 편집 창에 복사한다.
          • SDA와 SCL의 Pin 번호를 자신의 보드에 맞게 편집한다. ESP32인 경우 21번, 22번, ESP8266인 경우 4번, 5번을 사용한다.
          • 자신이 사용하는 LCD 모듈의 Slave 주소를 확인하여 설정한다. 보통 PCF8574를 사용한 경우에는 0x27 번지이고, PCF8574A를 사용한 경우에는 0x3f 번지이다.
          • i2c-LCD-HD44780-custom-char.ino을 저장한다.
          • "i2c-LCD-HD44780-custom-char.ino" 프로그램을 컴파일하여 ESP8266/ESP32에 Upload 한다.
          • 실험
            • 프로그램이 시작되면 LCD Display의 첫줄에 커서가 출력되고 "LED testing" 메세지가 출력된다.
            • 두번째 줄에는 Custom char와 "Hello, World" 문자열, Custom char 가 출력된 다음 LCD Display에 출력된 문자가 우측으로 Scrolling 된다. 자세한 내용은 프로그램 참고요.

  • ESP8266/ESP32 I2C 관련 페이지 보기