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

python-MQTT

ESP8266/ESP32 MQTT - MicroPython
ESP8266/ESP32 MQTT - MicroPython


  • MQTT 사용을 위한 준비
    • MQTT( Message Queuing Telemetry Transport)는 클라이언트에서 메시지를 발행(Publish)하고 수신(Subscribe) 할 수있는 시스템이다. Low-bandwidth 장치를 위해 설계된 간단한 메시징 프로토콜이기 때문에 사물 인터넷 애플리케이션에 적합하다. MQTT를 사용하면 여러 장치 사이에 명령을 보내 출력을 제어하고 센서 노드에서 데이터를 읽고 게시(Publish)하는 설정을 용이하게 할 수 있다.

    • MQTT 이해에 필요한 기본 개념(용어)
      • Publish/Subscribe
      • 장치(Device)는 주제(Topic)에 대한 메시지를 발행(Publish)하거나 메시지를 수신(Subscribe)하기 위해 특정 주제를 구독(subscribed) 할 수 있다.

      • Messages
      • 메시지는 장치간에 교환하려는 정보(명령 or 데이터)이다.

      • Topics
        • 주제(Topics)는 메시지를 게시 할 위치 또는 수신 메시지를 등록하는 방법이다.
        • 주제(Topics)는 슬래시(/)로 구분 된 문자열로 표시된다. 다음은 홈 오피스에서 램프를 제어하는 경우 주제를 만드는 예이다.

        오피스 램프를 제어하는 경우 Topic 예

        오피스 램프 제어 시나리오 예

        • MQTT Client 장치에서 Topic(home/studyRoom/lamp)에 대하여 "On" 및 "Off" 메시지를 발행(Publish)한다.
        • 램프를 제어하는 장치(ESP32, ESP8266 또는 기타 보드 일 수 있음)가 해당 Topic(home/studyRoom/lamp)를 구독한다.
        • 해당 Topic에 대한 새 메시지가 발행(Publish)되면 램프를 제어하는 장치(예: ESP32)는 "on"또는 "off"메시지를 수신(Subscribe)하고 램프를 켜거나 끄는 제어를 실행한다.
    • MQTT – Broker
    • 브로커는 기본적으로 모든 메시지를 수신하고, 메시지를 필터링하고, 해당 메시지에 관심이있는 Clients에게 메시지를 게시(Publish)한다.

      MQTT – Broker 예


    • Raspberry Pi에 Mosquitto Broker 설치하기
      • 주의: Mosquitto version 2.0.12는 umqtt.simple과 연결되지 않는다. Mosquitto version 2.0.11 까지만 사용 가능하다. 이 문제는 MicroPython standard library를 개선하여야 되는 문제이기 때문에 현재로서는 언제 개선될지 알 수 없음.

      • Raspberry Pi에 터미널을(Putty) 연결한다.
      • 터미널을(Putty)에서 다음 명령을 실행하여 Mosquitto Broker를 설치한다.
      • sudo apt update

        sudo apt install -y mosquitto mosquitto-clients

        주: 위 명령에 의하여 Mosquitto version 2.0.11 이 설치된다. 현재(2021.12.16일) 최신 버전은 Mosquitto version 2.0.12 이다. 현재는 Mosquitto를 2.0.12 버전으로 업그레이드하면 umqtt.simple과 연결되지 않는다.

      • Mosquitto 설치과정에서 패키지 관리자가 부팅 시 Mosquitto 서버를 자동 시작하도록 구성한다.
      • 만약 필요한 경우 Mosquitto 서버를 자동 시작 또는 중지하는 방법은 아래와 같다.
        • Raspberry Pi 시작시 자동으로 Mosquitto를 시작 시키는 명령은 아래와 같다.
        • sudo systemctl enable mosquitto.service

        • Raspberry Pi 자동 시작을 중지하는 명령은 아래와 같다.
        • sudo systemctl disable mosquitto.service

        • Mosquitto를 Restart 시키는 명령은 아래와 같다.
        • sudo systemctl restart mosquitto

        • Raspberry Pi 시작시 자동으로 Mosquitto를 시작 시키지 않고 Background에서 Daemon으로 실행 시키는 명령은 아래와 같다.
        • mosquitto -d

        • 아래 명령으로 mosquitto의 실행 여부를 확인할 수 있다.
        • sudo systemctl status mosquitto

        • 아래 명령으로 mosquitto의 Version과 정상 설치 여부를 확인한다.
        • mosquitto -v

        • 아래 명령으로 Raspberry Pi의 IP address를 확인할 수 있다.
        • hostname -I

        • 실행중인 mosquitto id 확인하기
        • ps -ef | grep mosquitto

        • 실행중인 프로세스를 종료(id 사용)하는 예
        • sudo kill 12345

      • 아래 명령어를 사용하여 Mosquitto의 상태(설치 및 실행 중 인지 확인)를할 수 있다.
      • sudo systemctl status mosquitto

        Mosquitto 서비스가 제대로 시작된 경우 녹색으로 강조된 “active (running)”이라는 텍스트가 메세지 중에 표시된다.

      • Mosquitto를 외부에서 연결할 수 있도록 허용하기
      • Mosquitto version 2.0.0 부터는 오직 localhost에서 만 연결할 수 있도록 초기 설정이 되어 있기 때문에 아래와 같이 외부에서 연결할 수 있도록 설정하여야 한다.

        연결 허용은 사용자 인증 없이 모든 사용자에게 연결을 허용하는 방법과 사용자의 이름과 비밀번호를 이용하여 인증된 사용자에게 만 연결을 허용하는 방법이 있다.

        • 인증 없이 모든 사용자에게 연결을 허용하기
          • 아래 명령으로 nano 편집기를 이용하여 mosquitto.conf의 아래에 "listener 1883 0.0.0.0" 와 "allow_anonymous true" 두줄을 추가한다.
          • sudo nano /etc/mosquitto/mosquitto.conf

            mosquitto.conf의 편집 결과 예는 아래와 같다.

          • CTRL-X, Y, Enter 를 입력하여 변경한 파일을 저장하고 nano 편집기를 종료한다.
          • 아래 명령으로 mosquitto을 다시 실행한다.
          • sudo systemctl restart mosquitto

          • 아래 명령으로 mosquitto의 실행 상태를 확인한다.
          • sudo systemctl status mosquitto

        • 사용자의 이름과 비밀번호를 이용하여 인증된 사용자에게 만 연결을 허용하기
          • Raspberry Pi 터미널(예: putty)에서 아래와 같은 명령으로 사용자를 등록하고 비밀번호를 설정한다.
          • sudo mosquitto_passwd -c /etc/mosquitto/passwd USERNAME

            위 명령에서 USERNAME은 본인의 사용자 이름을 사용한다. 위 명령을 실행하면 passwd를 입력하는 메세지가 출력되고 이 메세지에 따라 passwd를 입력한다.

            위 명령의 결과 /etc/mosquitto 폴더에 passwd 파일이 생성된다.

          • 아래 명령으로 nano 편집기를 이용하여 mosquitto.conf 파일을 열고 첫줄에 "per_listener_settings true"를 추가한다.
          • sudo nano /etc/mosquitto/mosquitto.conf

          • mosquitto.conf의 아래에 "allow_anonymous false", "listener 1883", "password_file /etc/mosquitto/passwd" 세줄을 추가한다.
          • mosquitto.conf의 편집 결과 예는 아래와 같다.

          • CTRL-X, Y, Enter 를 입력하여 변경한 파일을 저장하고 nano 편집기를 종료한다.
          • 아래 명령으로 mosquitto을 다시 실행한다.
          • sudo systemctl restart mosquitto

          • 아래 명령으로 mosquitto의 실행 상태를 확인한다.
          • sudo systemctl status mosquitto

    • umqttsimple library 설치하기
      • umqttsimple library 만들기
        • 아래 umqttsimple library를 다운로드 하여 저장(umqttsimple.py)한다.
        • umqttsimple library: umqttsimple.py

      • umqttsimple library를 ESP32/ESP8266에 설치하기
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • Thonny IDE의 "파일 -> 열기"를 실행하여 umqttsimple library(umqttsimple.py) 파일을 Open 한다.
        • Thonny IDE의 파일 메뉴 "...(으)로 저장"을 사용하여 umqttsimple.py 파일을 "MicroPython 장치"에 저장(Upload)한다.

        주: 최신 버전의 MicroPython firmware에는 umqtt.simple module(umqtt library)이 Built-In 되어 있기 때문에 umqttsimple library를 별도로 설치하지 않아도 된다. 필요한 경우"MicroPython Built-In Modules 확인 하기"를 참고하여 umqtt library 설치 여부를 확인(Module 이름: umqtt/simple)할 수 있다.

        주: MicroPython Built-In Modules을 사용하는 경우 다음과 같이 MQTTClient class를 import 한다.

        from umqtt.simple import MQTTClient


  • MQTT Broker를 사용한 메세지 전달과 장치 제어
    • 이 예는 2개의 장치(ESP32 or ESP8266 모듈)사이에 메세지를 주고 받는 예이다.

    • Broker를 사용한 메세지 전달 과제에 필요한 준비
      • Hardware
        • 2개의 ESP32 또는 ESP8266 개발보드: MQTT Client로 사용한다.
        • Raspberry Pi(MicroSD Card 16GB 이상): MQTT Broker를 설치한다.
      • Software
        • Python 3
        • Mosquitto Broker: Raspberry Pi에 설치
          • "Mosquitto Broker 설치하기" 참고요.
        • umqtttsimple library: ESP 개발보드에 설치
          • "umqtttsimple library 설치하기" 참고요.
    • Broker를 사용한 메세지 전달과 LED 제어
      • 버튼 스위치와 LED는 개발보드에 장착된 것을 사용하기 때문에 별도로 구성도에 포함하자 않음.

        주: ESP8266/ESP32 개발보드가 1개만 있는 경우에는 아래 "Android 휴대폰을 사용한 메세지 전달과 LED 제어 실험"을 참고하여 ESP#1 대신 Android 휴대폰을 사용할 수 있다.

      • ESP#1의 스위치(GPIO0)를 누르면 "LED Control" 주제(Topic)에 "LED Toggle"메시지를 게시(Publish)한다.
      • ESP#1은 ESP#2 보드에서 알림을 수신(Subscribed)하기 위해 "LED Status" 주제를 구독(Subscribe)한다.
      • ESP#2는 "LED Control" 주제(Topic)를 구독(Subscribe)한다. 이 주제(Topic)에 ESP#1 이 메세지를 게시하기 때문에 ESP#2는 ESP#1의 메시지를 수신하게 된다.
      • ESP#2는 메시지를 받으면 LED를 제어(Toggle)하고 "LED Status" 주제에 LED의 상태(LED on or off)를 메시지로 게시(Publish)한다. ESP#1은 해당 주제를 구독하므로 ESP#2 메시지를 수신하게 된다.

      1번 ESP 개발보드를 LED 제어 신호(Switch 사용) 입력 및 결과 모니터(1번 ESP의 LED)로 사용하고 2번 ESP 개발보드를 LED 제어와 결과 게시용으로 사용한다.

      프로그램 동작: 1번 ESP 개발보드의 Switch를 누르면 1번 보드는 "LED Control" 주제(Topic)에 "LED Toggle"메시지를 게시(Publish)한다. 2번 ESP 개발보드는 "LED Control" 주제(Topic)를 수신하여 LED를 Toggle 하고, 2번 보드 LED의 상태를 게시한다. 1번 개발보드는 2번 개발보드의 게시를 수신하여 1번 보드의 LED 상태를 2번 보드의 LED와 동일한 상태가 되도록 제어한다.

    • ESP#1 장치 프로그램
      • ESP#1 장치 프로그램: MQTT_led_control_ESP1.py

    • ESP#2 장치 프로그램
      • ESP#2 장치 프로그램: MQTT_led_control_ESP2.py

    • Broker를 사용한 메세지 전달과 LED 제어 실험
      • 실험을 위한 준비
        • 이 실험을 위하여는 Raspberry Pi: MicroSD Card(16GB 이상)가 필요하다.
        • 이 실험을 위하여는 2개의 ESP8266/ESP32 개발보드가 필요하다.
        • 주: ESP8266/ESP32 개발보드가 1개만 있는 경우에는 아래 "Android 휴대폰을 사용한 메세지 전달과 LED 제어 실험"을 참고하여 ESP#1 대신 Android 휴대폰을 사용할 수 있다.

        • 이 실험을 위하여는 무선공유기(예: iptime 공유기)가 필요하다.
        • Raspberry Pi에 Mosquitto Broker가 설치되어 있어야 한다.
        • Arduino IDE에 PubSubClient Library가 설치되어 있어야 한다.
        • ESP8266/ESP32 개발보드에 내장된 스위치와 LED를 사용하기 때문에 별도의 회로 연결은 필요 없다.
      • 실험 방법
        • "MQTT_led_control_ESP1.py" 프로그램을 다운로드하여 저장 한다.
        • "MQTT_led_control_ESP2.py" 프로그램을 다운로드하여 저장 한다.
        • Raspberry Pi를 실행하고 Mosquitto Broker가 실행되고 있는지 확인(위 "Mosquitto Broker 설치하기" 참고)한다. Mosquitto Broker는 Raspberry Pi가 시작할 때 자동 또는 시작한 다음 수동으로 시작할 수 있다.
        • Thonny IDE를 실행하고 멀티 인스턴스를 열기가 가능한지 확인한다. 만약 "1개의 Thonny 인스턴스만 허용"인 상태인 경우에는 아래와 같이 멀티 인스턴스 허용으로 설정을 변경한다.
        • 멀티 인스턴스 허용으로 설정을 변경하기
          • "도구 -> 옵션"을 실행하여 Thonny 옵션 창을 열고 "일반" 창을 선택하고, "1개의 Thonny 인스턴스만 허용"을 해제한다.
          • Thonny IDE를 종료하였다가 다시 실행하면 멀티 인스턴스를 열 수 있다.
        • 첫번째 ESP를 위한 Thonny IDE를 열고, Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 두번째 ESP를 위한 Thonny IDE를 열고, Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 두개의 ESP는 서로 다른 COM Port를 사용하기 때문에 두번째 ESP를 위한 Thonny IDE에서는 사용환경을 다시 설정하여야 한다.

        • 위 "umqtttsimple library 설치하기"를 참고하여 각 개발보드에 umqtttsimple library를 설치 한다. umqtttsimple library는 하나의 보드에 한번만 설치하면 됨.
        • 주: 최신 버전의 MicroPython firmware에는 umqtt.simple module(umqtt library)이 Built-In 되어 있기 때문에 umqttsimple library를 별도로 설치하지 않아도 된다.

        • 첫번째 ESP를 위한 Thonny IDE에서 "MQTT_led_control_ESP1.py"를 Open 한다.
        • 두번째 ESP를 위한 Thonny IDE에서 "MQTT_led_control_ESP2.py"를 Open 한다.
        • 각 Thonny IDE의 Scripts 편집 창 프로그램에서 본인의 무선 공유기 연결을 위한 네트워크 자격 증명(ssid와 password)과 브로커(mqtt_server) IP 주소(브로커(mqtt_server)가 설치된 Raspberry Pi IP 주소)를 설정하고 "MicroPython 장치"에 저장한다.
        • 사용자의 이름과 비밀번호를 이용한 인증을 사용하는 경우에는 사용자 이름과 비밀번호를 설정하고 "MicroPython 장치"에 저장한다.
        • 아래 명령으로 Raspberry Pi 터미널에서 브로커(mqtt_server)의 IP 주소 확인할 수 있다.
        • hostname -I

        • 각 Thonny IDE에서 "MicroPython 장치"에 저장한 프로그램을 실행한다.
        • 각 Thonny IDE에서 Python shell 창에서 MQTT 연결 메세지을 확인(경우에 따라 1 - 5Sec 정도 소요됨)한다.
        • 실험: ESP#1 개발보드의 GPIO0 버튼을 누르면 ESP#2 개발보드의 LED가 Toggle 되고, ESP#2 개발보드의 LED 상태가 다시 ESP#1 개발보드로 전달되어 ESP#1과 ESP#2 보드의 LED(GPIO2) 상태가 동일하게 된다.
    • Android 휴대폰을 사용한 메세지 전달과 LED 제어 실험
      • 위 실험 환경에 Android 휴대폰을 추가하여 Android 휴대폰을 이용하여 장치를 제어하는 실험이다.

        Android 휴대폰 또는 ESP1을 사용하여 ESP2의 LED를 제어하고, ESP2로 부터 실행 결과를 수신하여 ESP1의 LED와 Android 휴대폰에 표시하는 기능을 수행하도록 한다.

      • 실험을 을 한 시스템 구성 예
      • 주: ESP8266/ESP32 개발보드가 1개만 있는 경우에는 ESP#1을 사용하지 않고 Android 휴대폰과 ESP#2을 사용하여 실험할 수 있다.

      • Android 휴대폰에 MQTT dash 설치하기
        • Android 휴대폰에 MQTT client 앱(MQTT dash)을 설치하여 ESP2의 LED를 제어한다. MQTT dash는 Android 휴대폰에 설치하여 사용할 수 있는 무료 앱이다.

        • Play 스토어에서 "MQTT dash"를 검색하여 설치한다.
        • MQTT dash를 실행하면 MQTT 브로커 관리 창이 열린다. 이 창에서는 새로운 MQTT 브로커의 등록, MQTT 브로커 삭제, MQTT 브로커 리스트의 순서 변경 등을 할 수 있다.
      • MQTT client 등록하기
        • MQTT client 등록 설정 창 예

        • MQTT dash 앱을 시작하면 MQTT client 등록 창이 열린다.
        • 등록 창 우측 상단에 있는 + 를 누르면 MQTT client 등록 설정 창이 열린다.
        • Name: 본인이 알기 쉬운 이름을 입력한다. 예: ESP1 led
        • Address: MQTT 브로커가 설치된 Raspberry Pi의 IP Address 예: 192.168.0.18
        • 우측 상단의 플로피 디스크 심볼을 클릭하면 설정이 저장된다.
        • 주: 사용자 인증을 사용하지 안는 경우에는 User name과 Password는 Mosquitto 서버 설치시 "allow_anonymous true"로 설정하였기 때문에 입력하지 않아도 된다.

          주: 사용자 인증을 사용하는 경우에는 User name과 Password를 입력한다.

      • 등록된 MQTT client 설정하기
      • 등록된 MQTT client를 클릭하면 client 설정 창이 열린다. 등록된 MQTT client를 길게 누르면 등록된 MQTT client 편집창이 열린다.

          MQTT client 설정 창 예

             Name과 Topic을 등록하는예

             Payload와 Icons를 등록하는 예


          Client 설정 창에서 + 를 클릭하면 Choose type 창이 열린다.

          Choose type 창에서 Switch/button를 선택하면 MQTT Client 설정 창이 열린다. 설정 창에서 다음과 같이 설정한다.

        • Name: 본인이 알기 쉬운 이름을 입력한다. 예: ESP1 led
        • Topic(sub): LED Status
        • "Enable publishing" Box를 체크하고 Topic(pub)를 아래와 같이 입력한다.
          • Topic(pub): LED Control
      • Payload 와 Icon 설정하기
        • Payload 설정
          • On에 미리 설정된 "1"을 지우고 "LED on"을 입력한다.
          • Off에 미리 설정된 "0"을 지우고 "LED off"을 입력한다.
        • Icon image 설정
          • 현재 설정된 On icon(체크 표시된 사각형)을 길게 누루면 Icon 선택 창이 열린다. 이 창에서 On 상태의 전구 Icon을 선택한다.
          • Icon 아래 사각형을 길게 누르면 Color select 창이 열린다. 이 창에서 적색을 선택한다.
          • 현재 설정된 Off icon(빈 사각형)을 길게 누루면 Icon 선택 창이 열린다. 이 창에서 Off 상태의 전구 Icon을 선택한다.
          • Icon 아래 사각형을 길게 누르면 Color select 창이 열린다. 이 창에서 회색을 선택한다.
        • 우측 상단의 플로피 디스크 심볼을 클릭하면 설정이 저장되고 MQTT 브로커에 연결된다.
        • 주: Raspberry Pi에 Mosquitto Broker가 설치되어 실행되는 상태이어야 한다.

      • MQTT 브로커 환경에서 LED 제어 실험하기
        • MQTT client를 사용하여 LED를 제어하는 창 예

          위 "Broker를 사용한 메세지 전달과 LED 제어"를 참고하여 ESP1과 ESP2에 프로그램을 설치하고 실행한다.

        • ESP1 보드에서 ESP2의 LED 제어하기
          • ESP1 보드의 Switch를 누르면 메세지가 ESP2 전송되어 ESP2의 LED의 상태가 Toggle 된다.
          • ESP2에서 현재 LED의 상태를 전송한다.
          • ESP2의 메세지를 수신한 ESP1의 LED와 Android 휴대폰의 전구 심볼의 상태가 ESP2와 동일 하게 변동된다.
        • Android 휴대폰에서 ESP2의 LED 제어하기
          • Android 휴대폰의 전구 심볼을 누르면 메세지가 ESP2 전송되어 ESP2의 LED의 상태가 Toggle 된다.
          • ESP2에서 현재 LED의 상태를 전송한다.
          • ESP2의 메세지를 수신한 ESP1의 LED와 Android 휴대폰의 전구 심볼의 상태가 ESP2와 동일 하게 변동된다.

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