09주차 ‐ MQTT 실습 - gitjs523/SmartDevice2025 GitHub Wiki
- MQTT: Message Queuing Telemetry Transport. 사물 인터넷(IoT)응용 프로그램과 머신 투 머신(Machine-to-Machine) 통신을 위해 고안된 경량 메시지 통신 프로토콜.
- 발행(Publish) 와 구독(Subscribe) 기반으로 동작
- 낮은 대역폭, 높은 신뢰성, 적은 전력 소비가 필요한 환경에 최적화
- 장치는 메시지를 토픽 에 발행하고, 다른 장치들은 해당 토픽을 구독하여 메시지 수신
- 통신은 브로커(Broker)라는 중개 서버 이용
- 사용 예시:
- 스마트 홈(조명, 온도 제어)
- 차량 상태 모니터링
- 웨어러블 기기
- 통신 구조: [Publisher] → [Broker] → [Subscriber]
- Publisher: 특정 토픽에 메시지 발행
- Broker: 메시지를 수신 후 구독자에게 전달
- Subscriber: 관심 있는 토픽 구독하고 메시지 수신
- 경량 프로토콜: 최소한의 네트워크 트래픽
- 항상 연결 상태 유지: 장기 연결 기반 통신 지원
- 빠른 반응성: 실시간 데이터 전달 가능
- 저전력 소모: 배터리 기반 기기에 적합
- QoS(Quality of Service) 제공: 신뢰성 있는 데이터 전송 설정 가능
- 확장성: 수백만 개의 디바이스에 연결 가능
- Client: MQTT 통신에 참여하는 장치 또는 프로그램
- Broker: 클라이언트 간 메시지 중계 서버
- Publish: 토픽에 메시지를 보내는 행위
- Subscribe: 특정 토픽에 대해 메시지를 받겠다고 등록하는 행위
- Topic: 메시지를 주고받는 가상의 채널 경로
- Payload: 실제로 전송되는 데이터 내용
- QoS(Quality of Service): 메시지 전송의 신뢰성 수준 설정(예: 0 ~ 2 레벨로 설정)
- ESP32, ESP32 확장 쉴드, 초음파 센서 필요
- 실습 목표: 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초 대기
}
- 손을 초음파 센서에 가까이 위치해보며 거리 측정
20250511_220205.mp4
- 목표: 초음파 센서로 거리 측정한 값을 MQTT Explorer에서 확인해보기
- 라이브러리 설치: [PubSubClient by Nick O’Leary]
- WiFi 정보 설정: SSID, PASSWORD 수정
- MQTT Explorer 설치 및 실행
- 실행 후 초음파 센서 값을 "user1/esp32/ultra" 토픽으로 검색 후 Publish
사용한 코드
#include <WiFi.h> //Wi-Fi 연결 관련 라이브러리
#include <PubSubClient.h> //MQTT 프로토콜을 사용하기 위한 라이브러리
// 다음 변수들을 당신의 SSID와 비밀번호로 대체하세요.
const char* ssid = "YourSSID"; // 사용하는 WiFi 네트워크 이름 (SSID)
const char* password = "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;
}
20250511_224621.mp4
손을 가까이 하자 그래프의 값이 대체로 낮아졌다
- 준비물:
- ESP32
- ESP32 확장 쉴드
- 능동 부저: 전기 신호를 주면 소리가 나는 장치
사용한 코드
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 초 기다리기
}
20250511_230704.mp4
- 능동 부저를 MQTT Explorer와 연결하여 제어하기
- 토픽: "user1/esp32/buzzer" 구독해야 함
- 1 값을 넣으면 부저 켜짐/ 0 값을 넣으면 부저 꺼짐
사용한 코드
#include <WiFi.h>
#include <PubSubClient.h>
// 다음 변수들을 당신의 SSID와 비밀번호로 대체하세요.
const char* ssid = "YourSSID";
const char* password = "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);
}
}
}