Chapter 12. MQTT와 Adafruit IO 클라우드 연동

IoT의 핵심 프로토콜인 MQTT를 학습합니다. 내 방의 센서 데이터를 전 세계 어디서든 스마트폰 대시보드로 모니터링할 수 있는 시스템을 구축합니다.

Pico 2 W MQTT 클라우드 흐름도 Pico가 센서 데이터를 Adafruit IO MQTT 브로커로 발행하고, 대시보드의 LED 명령을 구독해 제어합니다. 센서 노드 MQTT Broker 클라우드 대시보드 Pico 2 W DHT11 + LED Publish / Subscribe temperature humidity led/cmd Adafruit IO MQTT Broker feeds로 데이터 중계 24.5 C 58 % LED ON 스마트폰 / 웹 대시보드 Publish는 센서 데이터 전송, Subscribe는 클라우드 명령 수신입니다. 두 방향을 구분하면 IoT 구조가 훨씬 선명해집니다.

12.1 Adafruit IO 설정 및 연결 구성

1. Adafruit IO에 가입하여 AIO Key를 복사해 두세요.
2. Thonny의 [Tools] -> [Manage Packages]에서 umqtt.simple을 검색해 설치해야 합니다.

항목 설정값 역할
DHT11 DataGP15온습도 측정
상태 LEDLED클라우드 명령 확인
MQTT Feedtemperature, humidity, led-cmd데이터 전송과 원격 제어

12.2 MQTT 발행과 구독 소스 코드

import time
import machine
import network
import dht
from umqtt.simple import MQTTClient

# Wi-Fi & Adafruit IO 설정
WIFI_SSID = "your_wifi_name"
WIFI_PASS = "your_wifi_password"
AIO_USER = "your_username"
AIO_KEY = "your_aio_key"

BROKER = "io.adafruit.com"
CLIENT_ID = "pico2-weather-node"
TEMP_FEED = AIO_USER + "/feeds/temperature"
HUM_FEED = AIO_USER + "/feeds/humidity"
LED_CMD_FEED = AIO_USER + "/feeds/led-cmd"

sensor = dht.DHT11(machine.Pin(15))
led = machine.Pin("LED", machine.Pin.OUT)

def connect_wifi():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(WIFI_SSID, WIFI_PASS)
    print("Wi-Fi 연결 중...")

    for _ in range(20):
        if wlan.isconnected():
            print("Wi-Fi Connected:", wlan.ifconfig()[0])
            return
        time.sleep(0.5)

    raise RuntimeError("Wi-Fi connection failed")

def on_message(topic, msg):
    command = msg.decode().strip().lower()
    print("수신:", topic.decode(), command)

    if command in ("on", "1", "true"):
        led.on()
    elif command in ("off", "0", "false"):
        led.off()

def connect_mqtt():
    client = MQTTClient(CLIENT_ID, BROKER, user=AIO_USER, password=AIO_KEY)
    client.set_callback(on_message)
    client.connect()
    client.subscribe(LED_CMD_FEED)
    print("MQTT Connected and subscribed:", LED_CMD_FEED)
    return client

connect_wifi()
client = connect_mqtt()
last_publish = time.ticks_ms()

while True:
    try:
        # 구독한 led-cmd feed에 새 명령이 있는지 확인합니다.
        client.check_msg()

        if time.ticks_diff(time.ticks_ms(), last_publish) >= 10000:
            sensor.measure()
            temp = sensor.temperature()
            hum = sensor.humidity()

            client.publish(TEMP_FEED, str(temp))
            client.publish(HUM_FEED, str(hum))
            print(f"Published: {temp}C, {hum}%")
            last_publish = time.ticks_ms()

        time.sleep(0.1)

    except OSError as e:
        print("MQTT 오류, 재연결 시도:", e)
        time.sleep(3)
        connect_wifi()
        client = connect_mqtt()

💡 Feed 이름 확인

Adafruit IO에서 temperature, humidity, led-cmd feed를 먼저 만들어 두세요. 대시보드 버튼에서 led-cmdon 또는 off를 보내면 Pico의 내장 LED가 반응합니다.

12.3 동작 흐름

Pico는 10초마다 DHT11 값을 읽어 온도와 습도 feed로 발행합니다. 동시에 led-cmd feed를 구독하고 있다가 클라우드 대시보드에서 명령이 들어오면 내장 LED를 켜거나 끕니다. 이 구조가 IoT에서 가장 기본적인 양방향 통신 패턴입니다.