9주차 스마트디바이스(MQTT) - jungjaeyeol/jyeol03 GitHub Wiki
MQTT는 Message Queuing Telemetry Transport의 약자로, 경량의 발행/구독(Publish/Subscribe) 기반 메시징 프로토콜입니다.
IoT(사물인터넷) 환경에서 센서나 소형 디바이스 간의 통신에 최적화되어 있으며,
낮은 대역폭, 낮은 전력 소비, 불안정한 네트워크 환경에서도 안정적인 메시지 전달을 지원합니다.
- 경량성: 최소한의 오버헤드로 메시지를 전송하여 네트워크 자원을 적게 사용
- 발행/구독 모델: 메시지를 직접 주고받는 것이 아니라, 중간 브로커를 통해 연결
-
QoS(Quality of Service) 레벨 지원:
-
0
: 한 번만 전송 (보장 없음) -
1
: 최소 한 번 전달 (중복 가능) -
2
: 정확히 한 번 전달 (가장 안전)
-
- 유지 연결(Keep Alive) 및 Last Will 메시지 기능
-
TCP/IP 기반 통신, 기본 포트는
1883
(TLS 보안은8883
)
Publisher ──► Broker ──► Subscriber
yaml 복사 편집
- Publisher: 메시지를 발행하는 클라이언트
- Subscriber: 특정 주제(Topic)를 구독하는 클라이언트
- Broker: 메시지를 중개하여 배포하는 서버
- TLS/SSL 암호화로 데이터 보안 강화
- 사용자 인증(Authentication), 권한 부여(Authorization) 가능
- 보안이 중요한 환경에서는 Mosquitto 등에서 인증서 기반 구성 권장
- 스마트 홈 자동화
- 환경 센서 모니터링
- 산업 자동화 및 원격 제어 시스템
- 차량 텔레메트리
- 모바일 앱의 실시간 알림 기능
- 코드
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초 대기
}
- 실습 결과
- MQTT Explorer 프로그램 필요
- 라이브러리에서 Pubsubclient 설치
- 코드
#include <WiFi.h> //Wi-Fi 연결 관련 라이브러리
#include <PubSubClient.h> //MQTT 프로토콜을 사용하기 위한 라이브러리
// 다음 변수들을 당신의 SSID와 비밀번호로 대체하세요.
const char* ssid = "iPhone03"; // 사용하는 WiFi 네트워크 이름 (SSID)
const char* password = "jjy031024"; // 사용하는 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;
}
- 실습 결과
KakaoTalk_20250510_165236869.mp4
-
부저가 소리가 울리고, 1초간 꺼진 상태를 유지 하는 반복하는 실습
-
코드
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 초 기다리기
}
- 실습 결과
KakaoTalk_20250510_165752998.mp4
-
MQTT Explorer 를 사용한 실습
-
코드
#include <WiFi.h>
#include <PubSubClient.h>
// 다음 변수들을 당신의 SSID와 비밀번호로 대체하세요.
const char* ssid = "iPhone03";
const char* password = "jjy031024";
// 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);
}
}
}
- 실습 결과
KakaoTalk_20250510_171348395.mp4
-
MQTT Explorer 사용 처음에
test.mosquitto.org
를 Host에 넣는다. - Port는
1883
으로 고정한다. - 라이브러리에서 Pubsubclieny by Nick O' ... 를 다운받아야한다.