ESP32를 MQTT에 연결하는 방법: ESP32 및 MQTT 초보자 가이드
아직도 HTTP 요청을 사용하여 IoT 장치를 제어하고 계신가요? ESP32가 서버에 "데이터가 있나요?"라고 지속적으로 요청(폴링)하는 경우 배터리 소모가 심하고 대역폭이 낭비될 수 있습니다.
이 튜토리얼에서는 MQTT(메시지 큐잉 텔레메트리 전송) 를 사용하여 여러분의 기술을 한 단계 업그레이드해 보겠습니다 . ESP32를 사용하여 센서 데이터를 대시보드로 전송하고, 명령을 수신하여 LED를 즉시 제어하는 시스템을 구축할 것입니다.
또한, 기기가 오프라인 상태가 되면 즉시 감지하는 "유언장(Last Will and Testament, LWT)"이라는 전문적인 IoT 기능을 구현할 예정입니다.
이미지 참고

MQTT를 사용하는 이유는 무엇일까요? (HTTP와 비교했을 때)
본격적인 연결 작업을 시작하기 전에 MQTT를 사용하는 이유를 이해하는 것이 중요합니다 .
- HTTP(기존 방식): 마치 우편함에 편지가 왔는지 확인하려고 5분마다 확인하는 것과 같습니다. 비효율적이고 피곤한 방식이죠.
- MQTT(IoT 방식): WhatsApp 알림을 떠올려 보세요. 메시지를 일일이 확인할 필요 없이, 메시지가 전송되는 즉시 도착합니다.
MQTT는 발행자/구독자 모델을 사용합니다 . ESP32는 누가 수신하고 있는지 알 필요가 없습니다 . 특정 토픽에 데이터를 "발행"하기만 하면 되고, 해당 토픽을 "구독"한 사람은 누구나 그 데이터를 수신합니다.

MQTT 브로커 및 클라이언트 4개
우리가 만들고 있는 것
- Publisher 게시자: ESP32는 5초마다 브로커에게 데이터(시뮬레이션된 온도, Wi-Fi 신호 강도 및 가동 시간)를 전송합니다.
- Subscriber 구독자: ESP32는 LED를 켜고 끄기 위해 "ON" 또는 "OFF" 명령을 수신합니다.
- LAST WILL: ESP32의 전원이 차단되면 시스템에서 자동으로 장치가 "오프라인" 상태임을 알려줍니다.
시각적인 학습을 선호하시는 분들을 위해 이 프로젝트의 모든 과정을 단계별로 담은 비디오 튜토리얼을 준비했습니다. 영상에서는 하드웨어 설정, 코드 로직에 대한 자세한 설명, 그리고 ESP32와 MQTT 브로커 간의 양방향 통신 과정을 실시간으로 보여드립니다.
필수 하드웨어
ESP32 개발 보드
LED 1개 (색상 무관)
330Ω 저항 1개
브레드보드와 점퍼선
마이크로 USB 케이블
소프트웨어 도구
아두이노 IDE (ESP32 코딩용)
MQTTX (데이터 시각화를 위한 무료 데스크톱 소프트웨어)
1단계: 회로
배선은 매우 간단합니다. ESP32의 GPIO 기능을 활용합니다.
LED 양극(+): GPIO 27 에 연결
LED 음극(-): 330Ω 저항을 통해 GND 에 연결하십시오 .
참고: 외부 LED를 사용하는 경우 LED가 타는 것을 방지하기 위해 저항을 직렬로 연결해야 합니다.

회로도
2단계: 코드 로직
PubSubClientMQTT 라이브러리를 사용하여 ArduinoJson데이터를 보기 좋게 포맷할 것입니다 .
코드의 핵심 개념:
1. 주제 구조: 우리는 경로 형식을 사용하여 데이터를 구성합니다: DeviceType/DeviceID/Function.
데이터 주제:ESP32/Unit1/data
명령 주제:ESP32/Unit1/command
상태 주제:ESP32/Unit1/status
2. 논블로킹 루프:delay(5000) ESP32의 핵심 동작을 일시 중지시키는 대신 타이머 검사를 사용합니다. 이를 통해 ESP32는 다음 온도 측정값을 전송하기 전에 LED 명령을 수신할 수 있습니다.
3. LAST WILL "마지막 유언": 연결 설정 중에 브로커에게 다음과 같이 알립니다. "예기치 않게 연결이 끊어지면 내 상태 토픽에 '오프라인' 메시지를 게시해 주세요."
깃허브
IoT_Bhai_Youtube_Channel/Mastering ESP32(English)/5. ESP32에서 MQTT 사용 방법 단계별 튜토리얼(코드 및 실험)/How_to_Use_MQTT_with_ESP32_Step_by_Step/How_to_Use_MQTT_with_ESP32_Step_by_Step.ino at main · ittipu/IoT_Bhai_Youtube_Channel
GitHub 계정을 만들어 ittipu/IoT_Bhai_Youtube_Channel 개발에 기여하세요.
깃허브 링크
Code
/*
* PROFESSIONAL MQTT EXPERIMENT - ESP32
* * Features:
* - Non-blocking Architecture (No delay())
* - Automatic Reconnection (WiFi & MQTT)
* - LWT (Last Will & Testament) for State Monitoring
* - JSON Data Serialization
* - Remote Command Handling
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// ==========================================
// 1. CONFIGURATION (Edit these)
// ==========================================
const char* ssid = "";
const char* password = "";
// MQTT Broker Settings (Using public HiveMQ for demo, change for production)
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_user = ""; // Leave blank for public brokers
const char* mqtt_pass = "";
// Unique Device ID (Must be unique on the broker)
const char* device_id = "ESP32_Pro_Unit_01";
// Topics (Structure: device_type/device_id/function)
const char* topic_telemetry = "esp32/unit01/data"; // Where we send sensor data
const char* topic_command = "esp32/unit01/cmd"; // Where we listen for commands
const char* topic_status = "esp32/unit01/status"; // LWT (Online/Offline)
// ==========================================
// 2. GLOBAL OBJECTS & VARIABLES
// ==========================================
WiFiClient espClient;
PubSubClient client(espClient);
// Timers for non-blocking delays
unsigned long lastMsgTime = 0;
const long interval = 5000; // Send data every 5 seconds
#define LED_PIN 2 // Onboard LED
// ==========================================
// 3. SETUP WIFI
// ==========================================
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to WiFi: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
// ==========================================
// 4. CALLBACK (Handle Incoming Messages)
// ==========================================
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
// Convert payload to string for easier handling
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// -- Command Logic --
// Example: If we receive "ON", turn on LED
if (String(topic) == topic_command) {
if (message == "ON") {
digitalWrite(LED_PIN, HIGH);
// Feedback: Publish new state immediately
client.publish(topic_telemetry, "{\"led\": \"ON\"}");
} else if (message == "OFF") {
digitalWrite(LED_PIN, LOW);
client.publish(topic_telemetry, "{\"led\": \"OFF\"}");
}
}
}
// ==========================================
// 5. RECONNECT (The Engine Room)
// ==========================================
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// --- LWT CONFIGURATION ---
// define Last Will: Topic, QoS, Retain, Message
// If this ESP32 dies, the Broker will post "offline" to the status topic automatically.
if (client.connect(device_id, mqtt_user, mqtt_pass, topic_status, 1, true, "offline")) {
Serial.println("connected");
// Once connected, publish an announcement that we are alive (Retained = true)
client.publish(topic_status, "online", true);
// Resubscribe to command topics
client.subscribe(topic_command);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000); // Blocking delay here is acceptable as we can't operate without connection
}
}
}
// ==========================================
// 6. MAIN SETUP
// ==========================================
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
// ==========================================
// 7. MAIN LOOP
// ==========================================
void loop() {
// Ensure we stay connected
if (!client.connected()) {
reconnect();
}
client.loop(); // Keep MQTT alive
// --- Non-Blocking Timer for Telemetry ---
unsigned long now = millis();
if (now - lastMsgTime > interval) {
lastMsgTime = now;
// Create a JSON Document
JsonDocument doc; // ArduinoJson v7
doc["device"] = device_id;
doc["uptime"] = millis() / 1000;
doc["wifi_rssi"] = WiFi.RSSI();
// Add dynamic data (simulated sensor)
doc["temp"] = random(20, 30);
// Serialize JSON to String
char buffer[256];
serializeJson(doc, buffer);
// Publish to MQTT
Serial.print("Publishing data: ");
Serial.println(buffer);
client.publish(topic_telemetry, buffer);
}
}
3단계: MQTTX를 이용한 시각화
이제 코드가 실행되었으니 데이터를 확인하고 LED를 제어할 방법이 필요합니다. MQTTX를 사용하겠습니다 .
1. 연결: MQTTX를 열고 동일한 브로커 URL( broker.hivemq.com) 및 포트(1883)를 사용하여 새 연결을 생성합니다.

1) 구독: "새 구독"을 클릭하고 입력하세요 ESP32/unit01/data. 5초마다 JSON 데이터가 도착하는 것을 즉시 확인할 수 있습니다.
2) 제어: 텍스트 입력 영역에서 주제를 로 변경합니다 ESP32/unit01/cmd. 입력 on하고 보내기를 누릅니다.

결과: ESP32의 LED가 즉시 켜져야 합니다!

LED 켜짐
"결정적 기능": 유언장 검증
이 부분이 실험에서 가장 흥미로운 부분입니다.
- ESP32/Unit01/statusMQTTX에서 해당 주제를 구독하세요 .
- "온라인"이라는 메시지가 표시될 것입니다 .
- 이제 ESP32에서 USB 케이블을 직접 뽑으세요 .
- MQTTX를 주시하세요. 장치가 작동하지 않더라도 브로커는 자동으로 상태 토픽에 "오프라인"을 게시합니다.

장치 상태(LWT)
이것이 바로 전문 IoT 대시보드가 센서의 배터리가 소진되었거나 연결이 끊어졌음을 감지하는 방식입니다.
결론
단순한 HTTP 요청을 넘어 MQTT를 사용하여 반응형 양방향 IoT 장치를 성공적으로 구축하셨습니다.
우리는 다음 내용을 다뤘습니다:
- 푸시 모델과 풀 모델의 효율성 비교.
- JSON 형식으로 데이터 포맷팅.
- "Last Will"을 사용하여 연결 상태를 확인합니다.
튜토리얼 원문 링크를 추가합니다. 읽어주셔서 감사합니다.
'ESP32' 카테고리의 다른 글
| ESP32-C6 핀 가이드 - 사용 필수 가이드 (0) | 2026.01.03 |
|---|---|
| ESP32 C3 Supermini 시작 가이드 (0) | 2026.01.02 |
| ESP32-C6 RGB LED 제어 (0) | 2026.01.01 |
| CrowPanel ESP32 Display 3.5인치 모듈 터치 기능 동작하지 않을 때 (0) | 2026.01.01 |
| ESP32 CrowPanel 3.5인치 디스플레이 디지털 시계 (0) | 2026.01.01 |
| ESP32 3.5inch TFT-LCD 개발 환경 설정 - 문서로 제공할 것 (0) | 2026.01.01 |
| ESP32 4G/5G 및 GPS 인터페이스 (0) | 2026.01.01 |
| ESP32 및 ESP8266을 이용한 MicroPython 프로그래밍 (0) | 2025.12.29 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
캐어랩