9주차 ‐ MQTT 초음파센서 실습 - boguuu/SmartDevice_2025-1 GitHub Wiki

🖥️MQTT란?


  • **MQTT (Message Queuing Telemetry Transport)**는 사물인터넷(IoT)과 머신투머신(M2M) 통신을 위해 고안된 초경량 메시지 통신 프로토콜
  • 1999년 IBM에서 처음 개발되었으며, 낮은 대역폭, 높은 신뢰성, 적은 전력 소비가 필요한 환경에 최적화

MQTT 통신 구조


[Publisher] → [Broker] → [Subscriber]
  • Publisher: 특정 토픽에 메시지를 발행
  • Broker: 메시지를 수신하고, 구독자에게 전달
  • Subscriber: 관심 있는 토픽을 구독하고 메시지를 받음

1

MQTT의 특징


  • 📡 경량 프로토콜: 최소한의 네트워크 트래픽
  • 🔗 항상 연결 유지: 장기 연결 기반 통신 지원
  • 🏎️ 빠른 반응성: 실시간 데이터 전달 가능
  • 🔥 저전력 소모: 배터리 기반 기기에 적합
  • 🔒 QoS 제공: 신뢰성 있는 데이터 전송 설정 가능
  • 📈 확장성: 수백만 개 디바이스 연결 가능

MQTT의 주요 사용 사례


  • 스마트 홈 (예: 조명, 온도 제어)
  • 스마트 팩토리 (IoT 기반 생산 라인 모니터링)
  • 자동차(텔레매틱스, 차량 상태 모니터링)
  • 헬스케어 (웨어러블 기기 데이터 전송)

MQTT 주요 용어


용어 설명
Client MQTT 통신에 참여하는 장치 또는 프로그램
Broker 클라이언트 간 메시지 중계 서버
Publish 토픽에 메시지를 보내는 행위
Subscribe 특정 토픽에 대해 메시지를 받겠다고 등록하는 행위
Topic 메시지를 주고받는 가상의 채널 경로
Payload 실제로 전송되는 데이터 내용
QoS (Quality of Service) 메시지 전송의 신뢰성 수준 설정 (0, 1, 2 레벨)

HTTP


HTTP: (하이퍼텍스트 전송 프로토콜)는 클라이언트와 서버 간의 통신을 위한 인터넷 프로토콜

클라이언트가 웹 브라우저를 통해 서버에 요청(Request)을 보내면 서버는 이에 대한 응답(Response)을 제공하여 웹 페이지, 이미지, 동영상 등의 다양한 리소스를 전송하며, 이를 통해 웹 서비스, 애플리케이션 인터페이스(API), 데이터 전송 등 다양한 용도로 활용

MQTT vs HTTP 비교


항목 MQTT HTTP
통신 방식 게시-구독 비동기 통신 요청-응답 동기 통신
연결 유지 가능 (Persistent Connection) 요청마다 연결
대역폭 사용 매우 적음 상대적으로 많음
메시지 크기 작음
실시간성 높음 낮음
에너지 소모 적음 많음
적용 분야 IoT, M2M 웹 애플리케이션

1. 초음파 센서를 이용한 거리 측정


준비물


  • ESP32
  • ESP32 확장 쉴드
  • 초음파 센서

회로연결


2

동작 설명


  • Trig 핀: 초음파 신호 송신 (Output)
  • Echo 핀: 반사된 초음파 수신 (Input)
  • 거리 계산: Echo 핀으로 들어오는 신호 시간을 측정하여 거리 계산
💡

1초 간격으로 물체와 초음파 센서 사이의 거리가 출력

코드


const int trigPin = 12;  // 초음파 센서의 트리거 핀
const int echoPin = 14;  // 초음파 센서의 에코 핀

long duration;          // 음파의 왕복 시간(마이크로초)
float distanceCm;       // 거리(cm)
float distanceInch;     // 거리(인치)

void setup() {
  Serial.begin(115200); // 시리얼 통신 시작 (통신 속도: 115200bps)
  pinMode(trigPin, OUTPUT);  // 트리거 핀을 출력으로 설정
  pinMode(echoPin, INPUT);   // 에코 핀을 입력으로 설정
}

void loop() {
  digitalWrite(trigPin, LOW);           // 트리거 핀 LOW로 초기화
  delayMicroseconds(2);                 // 2 마이크로초 대기
  digitalWrite(trigPin, HIGH);          // 트리거 핀 HIGH로 설정하여 초음파 송신
  delayMicroseconds(10);                // 10 마이크로초 동안 
  digitalWrite(trigPin, LOW);           // 초음파 송신 종료
  
  duration = pulseIn(echoPin, HIGH);     // 에코 핀에서 초음파의 왕복 시간 측정
  
  distanceCm = duration * 0.034/2; // 거리 계산
  
  distanceInch = distanceCm * 0.393701; // 인치로 변환
  
  Serial.print("Distance: ");
  Serial.print(distanceCm);              // 거리 (cm)
  Serial.print("(cm)  ");
  Serial.print(distanceInch);            // 거리 (인치)
  Serial.println("(inch)");
  
  delay(1000);                           // 1초 대기
}

코드 설명


🔹 상수 및 변수 선언

const int trigPin = 12;  // 초음파 센서의 트리거 핀
const int echoPin = 14;  // 초음파 센서의 에코 핀
  • trigPin은 초음파를 발사하는 신호를 보내는 핀(D12)
  • echoPin은 반사되어 돌아온 초음파를 수신하는 핀(D14)
long duration;          // 초음파가 물체에 반사되어 돌아오는 데 걸린 시간 (단위: 마이크로초)
float distanceCm;       // 측정된 거리 (단위: 센티미터)
float distanceInch;     // 측정된 거리 (단위: 인치)
  • 초음파의 이동 시간을 저장하고, 그 시간을 거리로 환산할 변수들을 선언

🔹 setup() 함수

void setup() {
  Serial.begin(115200); // 시리얼 통신 시작 (컴퓨터와 ESP32 간의 통신속도 설정)
  pinMode(trigPin, OUTPUT);  // 트리거 핀을 출력 모드로 설정
  pinMode(echoPin, INPUT);   // 에코 핀을 입력 모드로 설정
}
  • Serial.begin(115200): PC와 ESP32가 데이터를 주고받기 위해 115200bps 속도로 시리얼 통신을 시작
  • pinMode(trigPin, OUTPUT): 트리거 핀은 신호를 보내는 역할이기 때문에 OUTPUT으로 설정
  • pinMode(echoPin, INPUT): 에코 핀은 신호를 받는 역할이기 때문에 INPUT으로 설정

🔹 loop() 함수 (반복 실행)

digitalWrite(trigPin, LOW);           // 먼저 트리거 핀을 LOW로 초기화
delayMicroseconds(2);                 // 2마이크로초 동안 대기
  • 초음파를 정확하게 발사하기 위해, 초기 상태를 LOW로 만들어 잠시 대기
digitalWrite(trigPin, HIGH);          // 트리거 핀을 HIGH로 설정하여 초음파 발사
delayMicroseconds(10);                // HIGH 상태를 10마이크로초 동안 유지
digitalWrite(trigPin, LOW);           // 초음파 발사를 마치고 다시 LOW로 설정
  • 트리거 핀을 HIGH로 짧게(10μs) 주는 순간 초음파가 센서에서 발사
  • 이 초음파는 물체에 닿은 후 반사되어 돌아옴
duration = pulseIn(echoPin, HIGH);     // echo 핀에서 HIGH 신호가 유지되는 시간 측정
  • pulseIn() 함수는 HIGH 신호가 유지된 시간(마이크로초) 을 측정
  • 이 시간은 초음파가 왕복하는 데 걸린 시간
distanceCm = duration * 0.034/2;
  • 초음파의 속도는 약 340m/s, 즉 0.034cm/μs
  • 왕복 거리를 측정했기 때문에, 2로 나누어 실제 물체까지의 거리(cm)를 측정

거리(cm) = (왕복 시간 × 음속(cm/μs)) ÷ 2

distanceInch = distanceCm * 0.393701;
  • 1cm = 0.393701인치 이므로, cm를 inch로 변환

🔹 측정 결과 출력

Serial.print("Distance: ");
Serial.print(distanceCm);
Serial.print("(cm)  ");
Serial.print(distanceInch);
Serial.println("(inch)");
  • 거리 측정 결과를 시리얼 모니터에 출력

  • 예를 들어:

    Distance: 25.67(cm)  10.10(inch)
    
    

🔹 다음 측정까지 1초 대기

delay(1000);
  • 1초(1000밀리초) 동안 기다린 다음, 다시 측정을 반복

📈 전체 흐름 요약

  1. 트리거 핀으로 초음파 발사
  2. 에코 핀으로 반사된 초음파 수신
  3. 반사 시간(duration)을 측정
  4. *거리(cm, inch)**로 변환
  5. 결과를 시리얼 모니터에 출력
  6. 1초 간격으로 반복
💡 초음파 거리 측정 공식

[ \text{거리(cm)} = \frac{\text{Duration(μs)} \times 0.034}{2} ]

[ \text{거리(inch)} = \text{거리(cm)} \times 0.393701 ]

실행과정


코드 업로드


3

실행 확인


4

2. 초음파 센서 값 Publish


💡 **ESP32가 초음파 거리 센서를 통해 측정한 값을**

MQTT 토픽(user1/esp32/ultra)에 1초마다 보내는 프로그램

주요설정


  • WiFi 정보 설정: SSID, PASSWORD 수정
  • MQTT 서버 주소 설정
  • MQTT Client 객체 생성
  • 고유한 Client ID 생성 후 서버 연결
💡 초음파 센서 값을`"user1/esp32/ultra"` 토픽으로 Publish

실행코드


#include <WiFi.h>          //Wi-Fi 연결 관련 라이브러리
#include <PubSubClient.h>  //MQTT 프로토콜을 사용하기 위한 라이브러리

// 다음 변수들을 당신의 SSID와 비밀번호로 대체하세요.
const char* ssid = "Your_SSID";          // 사용하는 WiFi 네트워크 이름 (SSID)
const char* password = "Your_Password";  // 사용하는 WiFi 네트워크 비밀번호

const int trigPin = 12;  // 초음파 센서의 트리거 핀
const int echoPin = 14;  // 초음파 센서의 에코 핀

// MQTT 브로커 IP 주소를 여기에 입력하세요 (예: "192.168.1.144")
const char* mqtt_server = "test.mosquitto.org";
const int mqttPort = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

long lastMsgTime = 0;

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqttPort);

  pinMode(echoPin, INPUT);  // 에코 핀을 입력으로 설정
  // 트리거 핀 초기화
  pinMode(trigPin, OUTPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
}

void setup_wifi() {
  delay(10);
  // Wi-Fi 네트워크에 연결 시작
  Serial.println();
  Serial.print("연결 중인 Wi-Fi: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Wi-Fi 연결됨");
  Serial.println("IP 주소: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // 연결이 될 때까지 반복
  while (!client.connected()) {
    Serial.print("MQTT 연결 시도 중...");
    // 랜덤 클라이언트 ID 생성
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    Serial.print("클라이언트 ID: ");
    Serial.println(clientId);
    // 연결 시도
    if (client.connect(clientId.c_str())) {
      Serial.println("연결됨");
    } else {
      Serial.print("실패, rc=");
      Serial.print(client.state());
      Serial.println(" 5초 후 다시 시도");
      // 5초 대기 후 다시 시도
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  // 클라이언트가 메시지를 처리하고 서버와 연결 유지
  client.loop();

  long now = millis();
  if (now - lastMsgTime > 1000) {  //1초 간격
    lastMsgTime = now;
    // 초음파 센서 값을 읽어옵니다.
    float sensorValue = readUltrasonicSensor();
    char sensorString[8];
    dtostrf(sensorValue, 1, 2, sensorString);
    client.publish("user1/esp32/ultra", sensorString);
  }
}

float readUltrasonicSensor() {
  // 트리거 핀을 10 마이크로초 동안 HIGH로 설정하여 초음파를 발사합니다.
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // 에코 핀에서 펄스의 지속 시간을 측정합니다.
  pinMode(echoPin, INPUT);
  float duration = pulseIn(echoPin, HIGH);

  // 소리의 속도를 기준으로 거리를 계산합니다.(343m/s로 가정)
  float distance = duration * 0.0343 / 2.0;

  return distance;
}

코드 설명


🔹 라이브러리 포함

#include <WiFi.h>          // Wi-Fi 연결용 라이브러리
#include <PubSubClient.h>  // MQTT 통신용 라이브러리
  • WiFi.h: ESP32를 Wi-Fi 네트워크에 연결하기 위해 필요
  • PubSubClient.h: MQTT 프로토콜로 브로커와 통신하기 위해 사용

🔹 Wi-Fi 및 MQTT 서버 정보 설정

const char* ssid = "Your_SSID";          // 연결할 Wi-Fi SSID (이름)
const char* password = "Your_Password";  // Wi-Fi 비밀번호
  • 여러분이 연결할 무선 인터넷 정보를 여기에 입력
const int trigPin = 12;  // 초음파 센서 트리거 핀 (ESP32의 D12)
const int echoPin = 14;  // 초음파 센서 에코 핀 (ESP32의 D14)
  • 초음파 센서의 Trig와 Echo 핀을 각각 어디에 연결했는지 설정
const char* mqtt_server = "test.mosquitto.org"; // MQTT 브로커 서버 주소
const int mqttPort = 1883; // MQTT 기본 포트 (1883)
  • test.mosquitto.org는 공개 MQTT 테스트 서버
  • 실제 환경에서는 내부 서버 IP나 클라우드 MQTT 서비스를 쓸 수도 있음

🔹 Wi-Fi 및 MQTT 클라이언트 객체 생성

WiFiClient espClient;
PubSubClient client(espClient);
  • espClient: Wi-Fi를 통한 기본 TCP/IP 클라이언트
  • client: 이 Wi-Fi 클라이언트를 기반으로 MQTT 클라이언트 객체를 생성

🔹 시간 관리 변수

long lastMsgTime = 0;
  • 마지막으로 메시지를 보낸 시간을 저장
  • 1초 간격으로 초음파 데이터를 Publish하기 위해 사용

🛠 setup() 함수

초기 설정

void setup() {
  Serial.begin(115200);         // 시리얼 통신 시작
  setup_wifi();                 // Wi-Fi 연결 시도
  client.setServer(mqtt_server, mqttPort); // MQTT 브로커 정보 설정

  pinMode(echoPin, INPUT);       // 에코 핀 입력 설정
  pinMode(trigPin, OUTPUT);      // 트리거 핀 출력 설정
  digitalWrite(trigPin, LOW);    // 트리거 핀 초기화 (LOW)
  delayMicroseconds(2);          // 약간의 대기
}

🌐 setup_wifi() 함수

Wi-Fi 연결을 담당

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("연결 중인 Wi-Fi: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password); // Wi-Fi 연결 시작

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);               // 0.5초마다 상태 확인
    Serial.print(".");         // 연결 진행 표시
  }

  Serial.println("");
  Serial.println("Wi-Fi 연결됨");
  Serial.print("IP 주소: ");
  Serial.println(WiFi.localIP()); // 할당된 IP 주소 출력
}
  • Wi-Fi에 연결될 때까지 기다리고, 연결되면 IP 주소를 출력

🔌 reconnect() 함수

MQTT 브로커와 재연결을 시도하는 함수

void reconnect() {
  while (!client.connected()) {        // MQTT 연결이 안 되어 있으면
    Serial.print("MQTT 연결 시도 중...");
    String clientId = "ESP32Client-";   // 클라이언트 ID를 랜덤 생성
    clientId += String(random(0xffff), HEX);

    if (client.connect(clientId.c_str())) {  // 연결 시도
      Serial.println("연결됨");
    } else {
      Serial.print("실패, rc=");
      Serial.print(client.state());     // 실패 상태 코드 출력
      Serial.println(" 5초 후 다시 시도");
      delay(5000);                      // 5초 후 재시도
    }
  }
}
  • MQTT 서버와 연결이 끊어졌을 때 자동으로 재연결

🔄 loop() 함수

ESP32가 계속 반복 실행하는 메인 코드

void loop() {
  if (!client.connected()) {  // MQTT 연결이 끊어졌으면
    reconnect();              // 재연결
  }
  client.loop();              // 클라이언트 통신 유지 (수신 등 처리)

  long now = millis();        // 현재 시간(밀리초) 읽기
  if (now - lastMsgTime > 1000) {  // 1초 경과했으면
    lastMsgTime = now;

    float sensorValue = readUltrasonicSensor();  // 초음파 센서 읽기
    char sensorString[8];                        // 문자열 버퍼
    dtostrf(sensorValue, 1, 2, sensorString);     // float 값을 문자열로 변환 (소수점 2자리)

    client.publish("user1/esp32/ultra", sensorString); // "user1/esp32/ultra" 토픽으로 Publish
  }
}
  • 1초 간격으로 초음파 거리를 측정해서 MQTT 브로커로 Publish

📏 readUltrasonicSensor() 함수

초음파 센서를 이용해 거리를 측정하는 함수

float readUltrasonicSensor() {
  digitalWrite(trigPin, HIGH);  // 트리거 핀 HIGH
  delayMicroseconds(10);        // 10μs 동안 유지
  digitalWrite(trigPin, LOW);   // 트리거 핀 LOW로 끄기

  pinMode(echoPin, INPUT);      // 에코 핀 입력모드
  float duration = pulseIn(echoPin, HIGH);  // echo 핀 HIGH 지속시간 측정

  float distance = duration * 0.0343 / 2.0;  // 거리(cm) 계산
  return distance;
}
  • 0.0343 cm/μs: 초음파 속도(공기 중) 기준
  • 시간 × 속도 / 2 = 거리(cm)

📈 전체 흐름 요약

  1. Wi-Fi 연결
  2. MQTT 브로커 연결
  3. 초음파 센서 거리 측정
  4. 거리 데이터를 MQTT 서버로 Publish
  5. 연결 끊기면 자동 재연결
  6. 1초마다 반복

실행과정


라이브러리 설치(PubSubClient by Nick O’Leary)


[PubSubClient by Nick O’Leary] 라이브러리 설치

5

코드 업로드


6

MQTT PC 클라이언트 설치


7

💡 이번 실습은 MQTT Explorer를 활용하였으며, 윈도우환경에서 실습

MQTT Explorer실행 및 설정


8

💡

Host 및 Port를 코드에서 작성한 것을 바탕으로 설정 const char* mqtt_server = "test.mosquitto.org"; // MQTT 브로커 서버 주소 const int mqttPort = 1883; // MQTT 기본 포트 (1883)

연결 후 토픽 로드 및 결과 확인


9

💡

client.publish("user1/esp32/ultra", sensorString); 코드에서의 토픽값은 user1/esp32/ultra로 경로 이동후 결과 확인

Measurement.of.distance.using.ultrasonic.sensor.mp4
❗ **카메라가 멀어지면서 숫자가 커짐**

3. 능동 부저 제어


👉

부저가 0.5초간 울리고 1초간 쉬는 패턴을 반복

준비물


  • ESP32
  • ESP32 확장 쉴드
  • 능동 부저

회로연결


10

ESP32 핀 능동 부저 핀
D2 S
5V Vcc
GND GND

동작설명


  • "부저" 대시보드 생성
  • 토글 위젯 추가 및 설정
  • 토글 상태 변경 → 부저 동작 확인
💡 능동 부저는 전기 신호만 주면 소리가 나는 장치

실행 코드


const int buzzerPin = 2; //led 핀 번호 설절
 
void setup (){
  pinMode (buzzerPin,OUTPUT );//buzzerPin 을 출력으로 설정
}
 
void loop (){
  digitalWrite (buzzerPin, HIGH ); //buzzerPin 에 HIGH 값 쓰기
  delay (500 ); // 0.5 초 기다리기
  digitalWrite (buzzerPin, LOW ); //buzzerPin 에 LOW 값 쓰기
  delay (1000 ); // 1 초 기다리기
}

코드 설명


🔧 변수 설정

const int buzzerPin = 2; // 부저에 연결된 핀 번호 설정
  • 부저를 연결할 핀 번호를 지정합니다. 여기서는 GPIO 2번 핀을 사용

🔨 setup() 함수

void setup() {
  pinMode(buzzerPin, OUTPUT); // buzzerPin을 출력으로 설정
}
  • buzzerPin출력(OUTPUT) 모드로 설정합니다. 부저에 전기 신호를 보낼 수 있도록 준비

🔁 loop() 함수

void loop() {
  digitalWrite(buzzerPin, HIGH); // 부저 ON
  delay(500); // 0.5초 동안 울림 🔊

  digitalWrite(buzzerPin, LOW); // 부저 OFF
  delay(1000); // 1초 동안 멈춤 🔕
}
  • digitalWrite(buzzerPin, HIGH) 부저를 켬
  • delay(500) 부저가 0.5초 동안 울림
  • digitalWrite(buzzerPin, LOW) 부저를 끕니다. 소리가 멈춤
  • delay(1000) 부저가 1초 동안 꺼진 상태로 유지

🔄 동작 반복

  • 위의 동작(0.5초 울림 → 1초 꺼짐)이 무한 반복

실행 방법


코드 업로드


11

결과 확인


Active.buzzer.control.mp4

4. 능동 부저 Subscriber


👉

MQTT Explorer를 통해 실시간으로 부저를 제어

실행 코드


#include <WiFi.h>
#include <PubSubClient.h>
 
// 다음 변수들을 당신의 SSID와 비밀번호로 대체하세요.
const char* ssid = "여기에_당신의_SSID_입력";
const char* password = "여기에_당신의_비밀번호_입력";

// MQTT 브로커 IP 주소를 여기에 입력하세요 (예: "192.168.1.144")
const char* mqtt_server = "test.mosquitto.org";
const int mqttPort = 1883 ;
const char * mqttTopic = "user1/esp32/buzzer"; // 사용자에 맞게 변경
const int buzzerPin = 2 ; // 부저에 연결된 GPIO 핀 번호
 
WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);
  // Wi-Fi 네트워크에 연결 시작
  Serial.println();
  Serial.print("연결 중인 Wi-Fi: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Wi-Fi 연결됨");
  Serial.println("IP 주소: ");
  Serial.println(WiFi.localIP());
}
 
void setup(){
    // 시리얼 통신 초기화
  Serial.begin(115200);
  // Wi-Fi 연결 설정
  setup_wifi();

  client.setServer(mqtt_server, mqttPort);
  client.setCallback(callback);
 
  // 부저 핀을 출력 모드로 설정
  pinMode(buzzerPin,OUTPUT);
}
 
void loop(){
  if(!client.connected()){
    reconnect();
  }
  client.loop();//MQTT 클라이언트를 유지하기 위해 호출
}
 
void callback(char*topic , byte *payload , unsigned int length){
  Serial.print("Receivedmessage: ");
  Serial.print(topic);
  Serial.print(" ");
  for(int i = 0 ; i <length;i++){
    Serial.print((char)payload[i]);
  }
  Serial.println();
 
  if(strcmp(topic, mqttTopic)== 0){
    if(payload[0] == '1'){
     // 부저를 켜는 코드 작성
     digitalWrite(buzzerPin, HIGH); 
    }else if(payload[0] == '0'){
     // 부저를 끄는 코드 작성
     digitalWrite(buzzerPin, LOW); 
    }
  }
}
 
void reconnect(){
  while(!client.connected()){
    Serial.print("Connectingto MQTT Broker...");
   String clientId = "ESP32Client-";
   clientId += String(random(0xffff), HEX);
    if(client.connect(clientId.c_str())){
     Serial.println("Connected to MQTT Broker");
     client.subscribe(mqttTopic);
    }else {
     Serial.print("Failed, rc=");
     Serial.print(client.state());
     Serial.println("Retrying in 5 seconds...");
     delay(5000);
    }
  }
}

코드 설명


📚 라이브러리 포함

#include <WiFi.h>
#include <PubSubClient.h>
  • WiFi.h: ESP32를 Wi-Fi 네트워크에 연결하는 데 필요한 라이브러리
  • PubSubClient.h: MQTT 프로토콜을 사용하여 ESP32가 서버와 통신할 수 있게 해주는 라이브러리

🌐 Wi-Fi 연결 정보 설정

const char* ssid = "여기에_당신의_SSID_입력";
const char* password = "여기에_당신의_비밀번호_입력";
  • ssid: Wi-Fi 네트워크의 이름(SSID)
  • password: Wi-Fi 네트워크의 비밀번호

🔌 MQTT 브로커 설정

const char* mqtt_server = "test.mosquitto.org";
const int mqttPort = 1883;
const char * mqttTopic = "user1/esp32/buzzer";
  • mqtt_server: MQTT 브로커의 IP 주소 또는 도메인 이름
  • mqttPort: MQTT 포트 번호 (기본값 1883)
  • mqttTopic: 부저를 제어할 MQTT 토픽 설정

🔔 부저 핀 설정

const int buzzerPin = 2;
  • buzzerPin: 부저가 연결된 GPIO 핀 번호

🌐 Wi-Fi 연결 함수 (setup_wifi)

void setup_wifi() {
  delay(10);
  Serial.println("연결 중인 Wi-Fi: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("Wi-Fi 연결됨");
  Serial.println("IP 주소: ");
  Serial.println(WiFi.localIP());
}
  • ESP32가 Wi-Fi 네트워크에 연결되도록 설정하는 함수
  • 연결되면 IP 주소가 시리얼 모니터에 출력

🔧 setup 함수

void setup(){
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqttPort);
  client.setCallback(callback);
  pinMode(buzzerPin, OUTPUT);
}
  • 시리얼 통신을 설정하고 📠, Wi-Fi 연결과 MQTT 클라이언트를 초기화
  • 부저 핀을 출력 모드로 설정

🔄 loop 함수

void loop(){
  if(!client.connected()){
    reconnect();
  }
  client.loop();
}
  • ESP32가 MQTT 브로커와 연결이 끊기면 reconnect() 함수로 재연결 시도
  • *client.loop()**를 통해 MQTT 메시지를 처리하고 서버와 연결을 유지

📨 콜백 함수 (callback)

void callback(char* topic, byte* payload, unsigned int length){
  Serial.print("Received message: ");
  Serial.print(topic);
  Serial.print(" ");
  for(int i = 0; i < length; i++){
    Serial.print((char)payload[i]);
  }
  Serial.println();

  if(strcmp(topic, mqttTopic) == 0){
    if(payload[0] == '1'){
      digitalWrite(buzzerPin, HIGH);
    }else if(payload[0] == '0'){
      digitalWrite(buzzerPin, LOW);
    }
  }
}
  • callback 함수는 MQTT 서버에서 수신한 메시지를 처리
  • 메시지가 '1'이면 부저를 켜고 🔊, '0'이면 부저를 끔

🔄 연결 재시도 함수 (reconnect)

void reconnect(){
  while(!client.connected()){
    Serial.print("Connecting to MQTT Broker...");
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    if(client.connect(clientId.c_str())){
      Serial.println("Connected to MQTT Broker");
      client.subscribe(mqttTopic);
    }else{
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" Retrying in 5 seconds...");
      delay(5000);
    }
  }
}
  • reconnect 함수는 MQTT 서버와의 연결이 끊어졌을 때 자동으로 다시 연결을 시도
  • 연결에 성공하면 부저 제어를 위한 토픽을 구독

📈 전체 흐름 요약

  1. Wi-Fi 연결 🌐 → ESP32가 Wi-Fi 네트워크에 연결됨
  2. MQTT 연결 📡 → MQTT 브로커와 연결하고, 특정 토픽(user1/esp32/buzzer)을 구독
  3. 메시지 수신 📨 → 해당 토픽에서 수신한 메시지에 따라 부저를 켜거나 끔:
    • '1'이면 부저 켬 🔊.
    • '0'이면 부저 끔 🔕.
  4. 연결 유지 🔗 → MQTT 클라이언트가 계속 연결을 유지하며 실시간으로 메시지를 처리

실행 과정


코드 업로드


12

MQTT Explorer실행 및 설정


13

💡

Host 및 Port를 코드에서 작성한 것을 바탕으로 설정 const char* mqtt_server = "test.mosquitto.org"; // MQTT 브로커 서버 주소 const int mqttPort = 1883; // MQTT 기본 포트 (1883)

TOPIC 설정


14

💡

const char * mqttTopic = "user1/esp32/buzzer"; 부저를 제어할 토픽은 user1/esp32/buzzer

0과 1을 PUBLISH 하며 결과 확인


buzzer.control.subscriber.mp4
⚠️ **GitHub.com Fallback** ⚠️