아두이노에서 아두이노로의 MQTT 통신 | Arduino to Arduino MQTT Communication
이 튜토리얼에서는 다음을 배울 예정입니다:
- 두 아두이노 간의 MQTT를 통한 양방향 통신
- 예시 어플리케이션: MQTT를 통해 아두이노 #1에 연결된 버튼/스위치로 아두이노 #2에 연결된 LED를 제어합니다
준비물
2 | × | Arduino UNO R4 WiFi | Amazon | |
2 | × | USB Cable Type-C | 쿠팡 | Amazon | |
1 | × | (Recommended) Screw Terminal Block Shield for Arduino UNO R4 | 쿠팡 | Amazon | |
1 | × | (Recommended) Breadboard Shield For Arduino UNO R4 | 쿠팡 | Amazon | |
1 | × | (Recommended) Enclosure For Arduino UNO R4 | Amazon |
공개: 이 섹션에서 제공된 링크 중 일부는 제휴 링크입니다. 이 링크를 통해 구매한 경우 추가 비용없이 수수료를 받을 수 있습니다. 지원해 주셔서 감사합니다.
두 아두이노 간의 MQTT를 통한 통신
두 개의 Arduino 보드는 MQTT 서버를 통해 서로 통신할 수 있습니다. MQTT 서버를 사용하지 않고 두 Arduino가 직접 통신하기를 원한다면, Arduino간 TCP 클라이언트/서버 통신에 관한 튜토리얼을 참조하십시오.
Arduino #1과 Arduino #2가 MQTT 브로커를 통해 데이터를 교환할 때:
- 두 아두이노 모두 MQTT 브로커에 연결합니다.
- 아두이노 #2가 아두이노 #1에 데이터를 보내려면:
- 아두이노 #1은 예를 들어 arduino-1/data와 같은 주제를 구독합니다.
- 아두이노 #2는 아두이노 #1이 구독한 주제에 데이터를 발행하여 아두이노 #1에 데이터를 보낼 수 있습니다.
- 마찬가지로, 아두이노 #1이 아두이노 #2에 데이터를 보내려면:
- 아두이노 #2는 예를 들어 arduino-2/data와 같은 주제를 구독합니다.
- 아두이노 #1은 아두이노 #2가 구독한 주제에 데이터를 발행하여 아두이노 #2에 데이터를 보낼 수 있습니다.
이 방법을 따르면 두 개의 아두이노가 데이터를 양방향으로 교환할 수 있습니다.
예시 사용 사례
다음 애플리케이션을 실현해 봅시다: Arduino #1에 연결된 버튼/스위치가 MQTT를 통해 Arduino #2에 연결된 LED를 제어합니다.
위에서 언급했듯이, 우리가 사용할 수 있는 몇 가지 응용 프로토콜이 있습니다. 이 예시에서, 간단하게 만들기 위해, 우리는 스스로 프로토콜을 정의할 것입니다(자체 정의 프로토콜).
자체 정의 프로토콜
간단한 프로토콜을 정의해 보겠습니다:
- 아두이노 #1과 아두이노 #2가 MQTT 브로커(MQTT 서버)에 연결합니다.
- 아두이노 #1:
- 스위치의 상태가 변경될 때 아두이노 #1은 토픽에 MQTT 메시지를 발행합니다.
- 버튼/스위치가 켜질 때 MQTT 메시지 페이로드는 1입니다.
- 버튼/스위치가 꺼질 때 MQTT 메시지 페이로드는 0입니다.
- 아두이노 #2:
- 아두이노 #2는 토픽을 구독합니다
- 만약 아두이노 #2가 페이로드가 1인 MQTT 메시지를 받으면, LED를 켭니다.
- 만약 아두이노 #2가 페이로드가 0인 MQTT 메시지를 받으면, LED를 끕니다.
- 아두이노 #1 - 아두이노와 버튼 사이의 배선도
배선도
이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.
Arduino #2 - Arduino와 LED 사이의 배선도
이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.
아두이노 두 개 간의 MQTT를 통한 통신
아두이노 코드 #1
/*
* 이 Arduino 코드는 newbiely.kr 에서 개발되었습니다
* 이 Arduino 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다.
* 상세한 지침 및 연결도에 대해서는 다음을 방문하세요:
* https://newbiely.kr/tutorials/arduino/arduino-to-arduino-mqtt-communication
*/
// ARDUINO #1: 버튼/스위치에 연결되어 MQTT 발행자로 작동
#include <WiFiS3.h>
#include <MQTTClient.h>
#include <ezButton.h>
const int BUTTON_PIN = 7;
const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // 귀하의 WIFI SSID로 변경하세요
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // 귀하의 WIFI 비밀번호로 변경하세요
const char MQTT_BROKER_ADRRESS[] = "test.mosquitto.org"; // MQTT 브로커의 주소로 변경하세요
//const char MQTT_BROKER_ADRRESS[] = "192.168.0.26"; // MQTT 브로커의 IP 주소로 변경하세요
const int MQTT_PORT = 1883;
const char MQTT_CLIENT_ID[] = "arduino-001"; // 원하시는대로 변경하세요
const char MQTT_USERNAME[] = ""; // 필요하면 변경하세요, 필요 없으면 비워두세요
const char MQTT_PASSWORD[] = ""; // 필요하면 변경하세요, 필요 없으면 비워두세요
// Arduino가 발행/구독해야 하는 MQTT 토픽
const char MQTT_TOPIC[] = "arduino/command"; // 원하시는대로 변경하세요
WiFiClient network;
MQTTClient mqtt = MQTTClient(256);
ezButton button(BUTTON_PIN); // 7번 핀에 연결된 ezButton 생성
void setup() {
Serial.begin(9600);
button.setDebounceTime(100); // debounce 시간을 100 밀리초로 설정
Serial.println("ARDUINO #1: 버튼/스위치에 연결되어 MQTT 발행자로 작동");
int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED) {
Serial.print("Arduino - SSID에 연결을 시도하고 있습니다: ");
Serial.println(WIFI_SSID);
// WPA/WPA2 네트워크에 연결합니다. open 또는 WEP 네트워크를 사용하는 경우 이 줄을 변경하세요:
status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
// 연결을 위해 10초간 대기합니다:
delay(10000);
}
// 보드의 IP 주소를 출력합니다:
Serial.print("IP 주소: ");
Serial.println(WiFi.localIP());
connectToMQTT();
}
void loop() {
mqtt.loop();
button.loop(); // 반드시 loop() 함수를 먼저 호출해야 합니다
if (button.isPressed()) {
Serial.println("- 버튼이 눌렸습니다, 명령 전송: 1");
sendToMQTT('1');
}
if (button.isReleased()) {
Serial.println("- 버튼이 놓였습니다, 명령 전송: 0");
sendToMQTT('0');
}
}
void connectToMQTT() {
// MQTT 브로커에 연결
mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network);
Serial.print("Arduino - MQTT 브로커에 연결 중");
while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.print(".");
delay(100);
}
Serial.println();
if (!mqtt.connected()) {
Serial.println("Arduino - MQTT 브로커 연결 시간 초과!");
return;
}
Serial.println("Arduino - MQTT 브로커 연결 성공!");
}
void sendToMQTT(char command) {
char messageBuffer[1];
messageBuffer[0] = command;
mqtt.publish(MQTT_TOPIC, messageBuffer);
Serial.println("Arduino - MQTT로 발송됨:");
Serial.print("- 토픽: ");
Serial.println(MQTT_TOPIC);
Serial.print("- 페이로드:");
Serial.println(messageBuffer);
}
아두이노 코드 #2
/*
* 이 Arduino 코드는 newbiely.kr 에서 개발되었습니다
* 이 Arduino 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다.
* 상세한 지침 및 연결도에 대해서는 다음을 방문하세요:
* https://newbiely.kr/tutorials/arduino/arduino-to-arduino-mqtt-communication
*/
// ARDUINO #2: LED에 연결되어 MQTT 구독자로 작동함
#include <WiFiS3.h>
#include <MQTTClient.h>
const int LED_PIN = 9;
const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // WIFI SSID로 변경하세요
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // WIFI 비밀번호로 변경하세요
const char MQTT_BROKER_ADRRESS[] = "test.mosquitto.org"; // MQTT 브로커 주소로 변경하세요
//const char MQTT_BROKER_ADRRESS[] = "192.168.0.26"; // MQTT 브로커 IP 주소로 변경하세요
const int MQTT_PORT = 1883;
const char MQTT_CLIENT_ID[] = "arduino-002"; // 원하시는 대로 변경하세요
const char MQTT_USERNAME[] = ""; // 필요하면 변경하세요, 필요 없으면 비워두세요
const char MQTT_PASSWORD[] = ""; // 필요하면 변경하세요, 필요 없으면 비워두세요
// Arduino가 발행/구독해야 하는 MQTT 토픽
const char MQTT_TOPIC[] = "arduino/command"; // 원하시는 대로 변경하세요
WiFiClient network;
MQTTClient mqtt = MQTTClient(256);
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
Serial.println("ARDUINO #2: LED에 연결되어 MQTT 구독자로 작동함");
int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED) {
Serial.print("Arduino - SSID 연결 시도 중: ");
Serial.println(WIFI_SSID);
// WPA/WPA2 네트워크에 연결합니다. 오픈 또는 WEP 네트워크를 사용하는 경우 이 줄을 변경하세요:
status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
// 연결을 위해 10초간 대기:
delay(10000);
}
// 보드의 IP 주소를 출력합니다:
Serial.print("IP 주소: ");
Serial.println(WiFi.localIP());
connectToMQTT();
}
void loop() {
mqtt.loop();
}
void connectToMQTT() {
// MQTT 브로커에 연결
mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network);
// 들어오는 메시지를 위한 핸들러 생성
mqtt.onMessage(messageReceived);
Serial.print("Arduino - MQTT 브로커에 연결 중");
while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.print(".");
delay(100);
}
Serial.println();
if (!mqtt.connected()) {
Serial.println("Arduino - MQTT 브로커 연결 시간 초과!");
return;
}
// 토픽 구독, 들어오는 메시지는 messageReceived() 함수에서 처리됨
if (mqtt.subscribe(MQTT_TOPIC))
Serial.print("Arduino - 토픽 구독 성공: ");
else
Serial.print("Arduino - 토픽 구독 실패: ");
Serial.println(MQTT_TOPIC);
Serial.println("Arduino - MQTT 브로커 연결됨!");
}
void messageReceived(String &topic, String &payload) {
Serial.println("Arduino - MQTT로부터 수신됨:");
Serial.println("- 토픽: " + topic);
Serial.print("- 페이로드: ");
Serial.println(payload);
char command = payload[0];
if (command == '1') {
Serial.print("- 수신된 명령: ");
Serial.print(command);
Serial.println(" => LED 켜짐");
digitalWrite(LED_PIN, HIGH); // LED 켜기
} else if (command == '0') {
Serial.print("- 수신된 명령: ");
Serial.print(command);
Serial.println(" => LED 꺼짐");
digitalWrite(LED_PIN, LOW); // LED 끄기
} else {
Serial.print("- 지원되지 않는 명령 수신: ");
Serial.println(command);
}
}
사용 방법
- Arduino #1에 버튼/스위치 연결하기
- Arduino #2에 LED 연결하기
- Arduino IDE 열기 (Arduino IDE #1로 명명)
- PC에서 Arduino IDE 아이콘을 클릭하여 다른 Arduino IDE 창 열기 (Arduino IDE #2로 명명) (중요!(**))
- Arduino IDE의 왼쪽 네비게이션 바에 있는 Library Manager 아이콘을 클릭하여 라이브러리 관리자 열기
- 검색 상자에 MQTT 입력한 후, Joel Gaehwiler의 MQTT 라이브러리를 찾기
- Install 버튼을 클릭하여 MQTT 라이브러리 설치하기
검색 상자에 ezButton을 입력한 다음, ArduinoGetStarted에서 제공하는 버튼 라이브러리를 찾으세요.
ezButton 라이브러리를 설치하려면 설치하기 버튼을 클릭하세요.
- USB 케이블을 통해 아두이노 #1을 PC에 연결하고 아두이노 IDE #1에서 아두이노 #1의 COM 포트를 선택합니다
- USB 케이블을 통해 아두이노 #2을 PC에 연결하고 아두이노 IDE #2에서 아두이노 #2의 COM 포트를 선택합니다
- 아두이노 #1 코드를 복사하여 아두이노 IDE #1에 붙여넣고 저장합니다(이름: Arduino-1)
- 아두이노 #2 코드를 복사하여 아두이노 IDE #2에 붙여넣고 저장합니다(이름: Arduino-2)
- 두 코드의 WiFi 정보(SSID와 비밀번호)를 자신의 것으로 변경합니다.
- 두 코드의 MQTT 브로커 주소(도메인 이름 또는 IP 주소)를 변경합니다.
- 아두이노 #1 코드를 아두이노 #1에 업로드합니다
- 아두이노 #2 코드를 아두이노 #2에 업로드합니다
- 아두이노 IDE #1에서 시리얼 모니터를 엽니다
- 아두이노 IDE #2에서 시리얼 모니터를 엽니다
- 아두이노 #1의 버튼을 누르고 있으면 → 아두이노 #2의 LED 상태를 확인합니다(켜짐)
- 아두이노 #1의 버튼을 놓으면 → 아두이노 #2의 LED 상태를 확인합니다(꺼짐)
- 버튼을 여러 번 누르고, 누르고 있고, 놓습니다.
- 두 시리얼 모니터의 출력을 확인합니다
- 아두이노 #1의 시리얼 모니터
COM6
Arduino #1: CONNECTED TO A BUTTON/SWITCH, ACTED AS A MQTT PUBLISHER
Arduino - Attempting to connect to SSID: YOUR_WIFI_SSID
IP Address: 192.168.0.2
Arduino - Connecting to MQTT broker
Arduino - MQTT broker Connected!
- The button is pressed, send command: 1
Arduino - sent to MQTT:
- topic: arduino/command
- payload:1
- The button is released, send command: 0
Arduino - sent to MQTT:
- topic: arduino/command
- payload:0
Autoscroll
Clear output
9600 baud
Newline
아두이노 #2의 시리얼 모니터
COM6
Arduino #2: CONNECTED TO A LED, ACTED AS A MQTT SUBSCRIBER
Arduino - Attempting to connect to SSID: YOUR_WIFI_SSID
IP Address: 192.168.0.2
Arduino - Connecting to MQTT broker
Arduino - Subscribed to the topic: arduino/command
Arduino - MQTT broker Connected!
Arduino - received from MQTT:
- topic: arduino/command
- payload: 1
- Received command: 1 => Turned LED on
Arduino - received from MQTT:
- topic: arduino/command
- payload: 0
- Received command: 0 => Turned LED off
Autoscroll
Clear output
9600 baud
Newline