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

python-i2c

ESP32 I2C - MicroPython
ESP32 I2C(Inter-Integrated Circuit) 통신 - MicroPython


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

        참고자료: ATmega128 I2C 통신

      • I2C object 생성자(Constructors): class machine.I2C(id=- 1, *, scl, sda, freq=400000)
        • id: I2C 장치의 식별자 이다. id 가 -1(기본값)인 경우 I2C는 소프트웨어로 구현된다. 이 경우 SCL 및 SDA에 핀을 활당하여야 한다. id에 허용되는 다른 값은 특정 보드에 따라 다르며 scl 및 sda 지정은 경우에 따라 필수 또는 허용되지 않을 수 있다. ESP32 모듈을 사용하는 경우에는 I2C 번호(Software I2C인 경우 생략할 수 있음)와 scl와 sda 핀을 지정하여야 한다.
        • scl: SCL 선의 Pin 객체이다.
        • sda: SDA 선의 Pin 객체이다.
        • freq: SCL clock rate
      • 일반적인 Method
        • I2C.init(scl, sda, *, freq=400000): I2C 버스를 초기화한다.
        • I2C.deinit(): I2C bus를 Turn off 한다.
        • I2C.scan(): 0x08과 0x77(포함) 사이의 모든 I2C 주소를 스캔하고 응답하는 주소 목록을 반환한다. 장치는 주소(write bit 포함)가 버스로 전송된 후 SDA 라인을 로우로 하면 응답한다.
      • I2C 기본 동작
        • start(): 버스에 START 조건을 생성한다.(SCL이 높은 동안 SDA가 낮음으로 전환됨).
        • stop(): 버스에 STOP 조건을 생성한다.(SCL이 높은 동안 SDA가 높음으로 전환됨).
        • readinto(buf, nack=True): 버스에서 테이터(Byte)를 읽어 buf에 저장한다. 읽은 바이트 수는 buf의 길이 이다. ACK는 마지막 바이트를 수신 한 후에 버스로 전송된다. 마지막 바이트가 수신 된 후, nack가 참이면 NACK가 전송되고 그렇지 않으면 ACK가 전송된다.(이 경우 슬레이브는 연속되는 호출에서 더 많은 바이트를 읽을 것이라고 가정한다).
        • I2C.write(buf): buf에서 버스에 테이터(Byte)를 Write 한다. 각 테이터(Byte)를 Write한 다음 ACK가 수신되었는지 확인하고 NACK가 수신되면 나머지 테이터(Byte) 전송을 중지한다. 이 함수는 수신 된 ACK 수를 반환한다.
      • 표준 Bus 동작
        • 다음 Method는 슬레이브 장치를 대상으로 하는 표준 I2C 읽기 및 쓰기 Method 이다.

        • I2C.readfrom(addr, nbytes, stop=True): addr로 지정된 슬레이브에서 n 바이트를 읽는다. stop이 참이면 전송이 끝날 때 STOP 조건이 생성된다. 읽은 데이터가있는 바이트 열 객체를 반환한다.
        • I2C.readfrom_into(addr, buf, stop=True): addr에 의해 지정된 슬레이브에서 테이터(Byte)를 읽어 buf에 저장한다. 읽은 바이트 수는 buf의 길이 이다. stop이 참이면 전송이 끝날 때 STOP 조건이 생성한다. 이 메서드는 None을 반환한다.
        • I2C.writeto(addr, buf, stop=True): buf에 저장된 테이터(Byte)를 addr로 지정된 슬레이브에 write 한다. Bus에 데이터(Byte)를 write한 다음 NACK가 수신되면 나머지 테이터는 전송되지 않는다. stop이 True이면 전송이 끝날 때 STOP 조건이 생성된다. 이 함수는 수신 된 ACK 수를 반환한다.
        • I2C.writevto(addr, vector, stop=True): 벡터에 포함 된 테이터(Byte)를 addr로 지정된 슬레이브에 write 한다. 벡터는 Tuple 또는 Object 목록이어야 한다. addr가 한 번 전송 된 다음 벡터 내의 각 객체로 부터 테이터(Byte)가 순차적으로 Write 된다. 벡터의 객체는 길이가 0 바이트 일 수 있으며이 경우 데이터는 출력되지 않는다. 벡터의 객체 중 하나에서 테이터(Byte)를 쓴 다음 NACK가 수신되면 나머지 테이터(Byte)와 나머지 객체는 전송되지 않는다. stop이 참이면 NACK가 수신 되더라도 전송이 끝날 때 STOP 조건이 생성된다. 이 함수는 수신 된 ACK 수를 반환한다.
      • Memory 동작
        • 일부 I2C 장치는 읽고 쓸 수있는 메모리 장치(or 레지스터 세트)역할을 한다. 이 경우 Slave address와 Memory address가 필요하다. 다음 Method는 이러한 장치와 통신하기 위한 기능이다.

        • I2C.readfrom_mem(addr, memaddr, nbytes, *, addrsize=8)
          • addr로 지정한 슬레이브의 메모리 주소(memaddr)에서 시작하여 n 바이트를 읽는다. 인수 addrsize는 주소 크기를 비트 단위로 지정한다. 읽은 데이터가 저장된 바이트 열 객체를 반환한다.
        • I2C.readfrom_mem_into(addr, memaddr, buf, *, addrsize=8)
          • addr로 지정한 슬레이브의 메모리 주소(memaddr)에서 데이터(Byte)를 읽어 buf에 저장한다. 읽은 바이트 수는 buf의 길이 이다. 인수 addrsize는 주소 크기를 비트 단위로 지정한다(ESP8266에서 이 인수는 인식되지 않으며 주소 크기는 항상 8 비트이다). 이 메서드는 None을 반환한다.
        • I2C.writeto_mem(addr, memaddr, buf, *, addrsize=8)
          • addr로 지정한 슬레이브의 메모리 주소(memaddr)에 buf에 저장된 데이터(Byte)를 순차적으로 Write 한다. 인수 addrsize는 주소 크기를 비트 단위로 지정한다(ESP8266에서 이 인수는 인식되지 않으며 주소 크기는 항상 8 비트이다). 이 메서드는 None을 반환한다.

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

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


    • 프로그램 예: DS1621을 사용한 온도 측정
      • 윗 I2C 통신을 이용한 측정 과 제어 시스템 구성 예에서 ESP32 개발보드를 Master로 디지털 온도 센서(DS1621)를 Slave device로 사용 한다. 이 예에서는 이해를 쉽게하기 위하여 온도측정에 필요한 최소한의 기능만 구현한다. 확장된 기능은 DS1621 Library를 사용하는 예를 참고 바람.

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

      • 실험 방법
        • 위 프로그램(python_i2c_ds1621_basic.py)을 Download 하여 저장한다.
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • Thonny IDE의 "파일 -> 열기"를 실행하여 python_i2c_ds1621_basic.py 파일을 Open 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 프로그램이 실행되면 750mSec 주기로 온도가 측정되어 콘솔창에 출력된다. DS1621 칩 위애 손을 대고 있으면 체온에 의하여 변동된 온도(보통 상승)가 출력된다.

    • 프로그램 예: DS1621을 사용한 온도 측정(DS1621 Library 사용)
    • 이 예에서는 DS1621 기능을 대부분 사용하기 위하여 DS1621 Library를 사용한다.

      • DS1621 Library를 사용한 프로그램 예
      • 실험을 위한 준비는 위 "DS1621을 사용한 온도 측정"을 참고 할 것.
      • 실험 방법
        • "python_ds1621_library_basic_esp32.py" 프로그램 파일을 Download하여 저장한다.
        • "DS1621.py" Library 파일을 Download하여 저장한다.
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • Thonny IDE의 "파일 -> 열기"를 실행하여 DS1621.py 파일을 Open 한다.
        • Thonny IDE의 "...(으)로 저장" 기능을 사용하여 DS1621.py 파일을 "MicroPython 장치"에 저장(Upload)한다.
        • Thonny IDE의 "파일 -> 열기"를 실행하여 python_ds1621_library_basic_esp32.py 파일을 Open 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 프로그램이 실행되면 750mSec 주기로 온도가 측정되어 콘솔창에 출력된다. DS1621 칩 위애 손을 대고 있으면 체온에 의하여 변동된 온도(보통 상승)가 출력된다.

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

      • 프로그램 예
      • 실험을 위한 준비
        • ESP32 개발보드와 ATmega128 보드의 I2C 통신선 연결
          • ESP32 개발보드 SDA(GPIO4) <-> ATmega128 보드 SDA(PD1) : 2-wire serial 통신을 위한 Data input/output pin.
          • ESP32 개발보드 SCL(GPIO5) <-> ATmega128 보드 SCL(PD0) : 2-wire serial 통신을 위한 Clock input/output pin.
          • ESP32 개발보드 GND <-> ATmega128 보드 GND : Ground pin.
          • 전원 연결: ESP32 개발보드는 3.3V, ATmega128 보드는 5V를 사용하는 경우가 많기 때문에 주의가 필요함. 이 경우는 각각 전원을 연결하고 GND 선만 공통으로 연결한다.
      • 실험 방법
        • "python_i2c-avr_master_basic.py" 프로그램 파일을 Download하여 저장한다.
        • cho_avr_i2c_slave_basic.zip 파일을 Download 하여 여기에 포함된 cho_avr_i2c_slave_basic.hex을 ATmega128 보드에 설치한다.
        • ATmega128 보드의 UART0를 PC에 연결(USB - UART 변환 모듈 사용)하고 프로그램을 실행한다. PC에서 터미널 프로그램을 실행(ATmega128 보드의 COM 포트 번호 확인이 필요함. Baud rate: 19200)하고 ATmega128 보드의 Reset 버튼을 누르면 "I2C testing." 메세지가 출력된다.
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • Thonny IDE의 "파일 -> 열기"를 실행하여 python_i2c-avr_master_basic.py 파일을 Open 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 프로그램이 실행되면 Thonny IDE의 Python shell 창에 "Input Command: " 메세지가 출력 된다. Thonny IDE의 Python shell 창에 문자열을 입력하고 "Enter" 버튼을 클릭하면 입력한 문자열이 ATmega128 보드에 전송되어 ATmega128 보드 터미널 창에 출력되고, ATmega128 보드에서 ESP32 개발보드로 "AVR i2c testing" 메세지가 자동으로 전송된다. 그 결과 Thonny IDE의 Python shell 창에 "AVR i2c testing" 메세지가 출력된다.

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

      • 프로그램 예
      • 실험을 위한 준비는 "Master(ESP32) - Slave(ATmega128) I2C 통신 예"를 참고 바람.
      • 실험 방법
        • "python_i2c_avr_master_led.py" 프로그램 파일을 Download하여 저장한다.
        • cho_avr_i2c_slave_led.zip 파일을 Download 하여 여기에 포함된 cho_avr_i2c_slave_led.hex을 ATmega128 보드에 설치한다.
        • ATmega128 보드의 UART0를 PC에 연결(USB - UART 변환 모듈 사용)하고 프로그램을 실행한다. PC에서 터미널 프로그램을 실행(ATmega128 보드의 COM 포트 번호 확인이 필요함. Baud rate: 19200)하고 ATmega128 보드의 Reset 버튼을 누르면 "I2C LED control" 메세지가 출력된다.
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • Thonny IDE의 "파일 -> 열기"를 실행하여 python_i2c_avr_master_led.py 파일을 Open 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 프로그램이 실행되면 Thonny IDE의 Python shell 창에 "Input Command(L:Left, - - -, G:Get LED): " 메세지가 출력 된다. Thonny IDE의 Python shell 창에 LED 제어 명령(예: L)을 입력하고 "Enter" 버튼을 클릭하면 입력한 명령이 ATmega128 보드에 전송되어 ATmega128 보드의 LED Array가 좌측으로 순차적으로 점멸한다.

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

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


  • ESP32 I2C 관련 페이지 보기