///
Search
📼

12.Arduino에 MQTT 사용하기

이전 자료

아두이노 실행하고 스케치 클릭 후 라이브러리 포함하기 다음 라이브러리 관리 클릭
실행화면
검색 창에 pubsubclient라고 검색해서 다운로드
MQTT 설치 할 때 예제로 배웠던 작업 mqtt_sub을 열고 아두이노 스케치에 파일 탭에서 예제 →PubSubClient→mqtt_esp8266 클릭
위의 예제를 통해서 나오는 소스 코드는 다음과 같다.
/* Basic ESP8266 MQTT example This sketch demonstrates the capabilities of the pubsub library in combination with the ESP8266 board/library. It connects to an MQTT server then: - publishes "hello world" to the topic "outTopic" every two seconds - subscribes to the topic "inTopic", printing out any messages it receives. NB - it assumes the received payloads are strings not binary - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led, else switch it off It will reconnect to the server if the connection is lost using a blocking reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to achieve the same result without blocking the main loop. To install the ESP8266 board, (using Arduino 1.6.4+): - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs": http://arduino.esp8266.com/stable/package_esp8266com_index.json - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266" - Select your ESP8266 in "Tools -> Board" */ #include <ESP8266WiFi.h> #include <PubSubClient.h> // Update these with values suitable for your network. const char* ssid = "wifiname"; const char* password = "wifipassword1234"; const char* mqtt_server = "192.168.0.41"; WiFiClient espClient; PubSubClient client(espClient); unsigned long lastMsg = 0; #define MSG_BUFFER_SIZE (50) char msg[MSG_BUFFER_SIZE]; int value = 0; void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } randomSeed(micros()); Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // Switch on the LED if an 1 was received as first character if ((char)payload[0] == '1') { digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) } else { digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Create a random client ID String clientId = "ESP8266Client-"; clientId += String(random(0xffff), HEX); // Attempt to connect if (client.connect(clientId.c_str())) { Serial.println("connected"); // Once connected, publish an announcement... client.publish("outTopic", "hello world"); // ... and resubscribe client.subscribe("inTopic"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void setup() { pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); unsigned long now = millis(); if (now - lastMsg > 2000) { lastMsg = now; ++value; snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value); Serial.print("Publish message: "); Serial.println(msg); client.publish("outTopic", msg); } }
Arduino
복사
위의 소스코드에서 우리가 바꿔줘야 하는 부분은 다음과 같다.
const char* ssid = "wifiname"; const char* password = "wifipassword1234"; const char* mqtt_server = "192.168.0.41";
Arduino
복사
wifiname 부분을 본인이 연결할 와이파이 이름으로 하고
wifipasword1234부분을 본인이 연결할 와이파이의 비밀번호를 입력한다.
그리고 마지막으로 mqtt server는 본인이 연결할 pc (window면 window, rasp 등등)의 ip를 입력한다.
본인의 pc의 ip를 모르겠다면 cmd 창에 ipconfig를 검색해 나오는 숫자를 작성한다.
필자는 iptime 공유기를 사용해서 192.168.0.41로 나온다.
그리고 이전에 실습한 mqtt client 단에서 한 작업에서 다음과 같은 명령어를 입력하여 실습을 해본다. (mqtt 수신자(구독자) 서버를 실행하는 작업)
mosquitto_sub –d –t outTopic
Arduino
복사
실행화면
그리고 소스코드를 돌려본다.
실행화면
정상적인면 mqtt 연결이 되야하는데 자꾸 이 문자만 출력이 된다.
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds Attempting MQTT connection...failed, rc=-2 try again in 5 seconds Attempting MQTT connection...failed, rc=-2 try again in 5 seconds Attempting MQTT connection...failed, rc=-2 try again in 5 seconds Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Arduino
복사
일단 다른 예제도 들고 왔다.

출처

소스코드

#include <ESP8266WiFi.h> #include <PubSubClient.h> // Update these with values suitable for your network. const char* ssid = "wifinave"; const char* password = "dsdq1963"; const char* mqtt_server = "192.168.0.41"; const char* clientName = "D1miniClientA"; WiFiClient espClient; PubSubClient client(espClient); unsigned long lastMsg = 0; #define MSG_BUFFER_SIZE (50) char msg[MSG_BUFFER_SIZE]; int value = 0; void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); 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.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // Switch on the LED if an 1 was received as first character if ((char)payload[0] == '1') { digitalWrite(14, HIGH); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) } else { digitalWrite(14, LOW); // Turn the LED off by making the voltage HIGH } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(clientName)) { Serial.println("connected"); // Once connected, publish an announcement... client.publish("outTopic", "hello world"); // ... and resubscribe client.subscribe("inTopic"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void setup() { pinMode(14, OUTPUT); // Initialize the BUILTIN_LED pin as an output Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); unsigned long now = millis(); if (now - lastMsg > 2000) { lastMsg = now; ++value; snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value); Serial.print("Publish message: "); Serial.println(msg); client.publish("outTopic", msg); } }
Arduino
복사
작성화면
이것도 똑같은 오류가 나온다...
그래서 윈도우 방화벽을 없에보았다.
실행 화면
그래도 오류...
그래서 이번에는 인바운드 규칙에 mqtt 1883 포트를 추가해보았다.

출처

윈도우즈에 Mosquitto나 Node-RED를 설치하면 포트번호 1883과 1880이 부여됩니다. 그러나 이 포트가 열려있지 않아서 접속이 불가능한 경우가 있습니다. 여기서는 포트를 열어서 사용하는 방법을 설명합니다.
1
실행화면 열기
+ R키를 눌러서 실행 화면을 엽니다.
열려 있는 실행화면
2
실행화면에 filewall.cpl 입력하기
실행화면의 입력란에 firewall.cpl을 입력하고 확인 버튼을 누릅니다.
filewall.cpl 을 입력한 실행화면
3
“방화벽” 에서 “고급 설정” 선택하기
firewall.cpl을 입력하여 실행하면 방화벽화면이 나오는데 여기서 고급 설정을 누릅니다.
방화벽 화면에서 고급 설정 선택하기
4
“인바운드 규칙”과 “새 규칙…”을 누르기
방화벽화면에서 고급 설정을 누르면 새로운 화면이 나오는데 여기서 인바운드 규칙과 새 규칙…을 차려대로 누릅니다.
인바운드 규칙과 새 규칙 누르기
이 이후에 자세한 작업은 블로그에서 찾아서 보도록 하자.
(중요) 윈도우에서 아두이노가 보내는 mqtt 연결 시도 조차 막는것 같다. 방화벽을 끄고, 인바운드 규칙을 1883으로하고, conf 파일까지 수정을 하였으나 잘 안되었음.
윈도우의 방화벽 관련 문제라고 인식 하였으며, 사물인터넷 프로젝트이므로 앞으로 mqtt 브로커는 라즈베리파이 측에서 하는 방향으로 하겠음