아두이노에서 MQTT 브로커에 접속하기 위한 클라이언트 라이브러리는 PubSubClient.h입니다.
PubSubClient.h 바로가기 다음 프로그램은 제12장의 프로그램 12-1 mqtt-led-control을 AimMqtt.h의 도움없이 직접 PubSubClient.h를 이용하여 구현한 것입니다.프로그램 mqtt-led-control-primitive
// topic
#define TOPIC_LED "led" // 1:ON, 0:OFF
#define TOPIC_LED_R "led-r" // LED 상태 응답
#define TOPIC_MSG "msg" // 진행 상태 보고
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호
#define AP_SSID1 "my-ssid1"
#define AP_PASS1 "my-pass1"
#define AP_SSID2 "my-ssid2" // 없으면 ""
#define AP_PASS2 "my-pass2" // 없으면 ""
#define AP_SSID3 "my-ssid3" // 없으면 ""
#define AP_PASS3 "my-pass3" // 없으면 ""
// MQTT 설정
#define SERVER "192.168.XXX.XXX"
#define PORT 1883
#define USER "user"
#define PASS "yourPass"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <PubSubClient.h>
WiFiClient espClient;
ESP8266WiFiMulti wifiMulti;
PubSubClient client;
// 라이브러리
#include <AimOutput.h>
#include <AimSerial.h>
#include <AimTimer.h>
// 오브젝트 생성
AimOutput led(LED_BUILTIN,LOW);
AimSerial mySerial;
AimTimer timerMsg(10);
void setup_wifi() {
randomSeed(micros());
delay(100);
// WiFi station mode
WiFi.mode(WIFI_STA);
wifiMulti.addAP(AP_SSID1,AP_PASS1);
wifiMulti.addAP(AP_SSID2,AP_PASS2);
wifiMulti.addAP(AP_SSID3,AP_PASS3);
Serial.printf("\nConnecting to [%s],[%s],[%s]\n",
AP_SSID1,AP_SSID2,AP_SSID3);
while (wifiMulti.run() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to [");
Serial.print(WiFi.SSID());
Serial.print("],IP=");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
String clientId = "ESP8266-";
clientId += String(random(0xffff), HEX);
Serial.printf("SERVER=[%s],PORT=%d\n",SERVER,PORT);
Serial.printf("device=[%s],USER=[%s],PASS=[***]\n",clientId.c_str(),USER);
// Attempt to connect
if (client.connect(clientId.c_str(),USER,PASS)) {
Serial.println("MQTT connected\n-----");
int QoS = 1;
client.subscribe(TOPIC_LED,QoS);
Serial.printf("SUB: [%s],[%d]\n",TOPIC_LED,QoS);
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
char newPayload[32];
int newLength = length;
if (newLength > 31 ) {
newLength = 31;
}
Serial.print("RCV: [");
Serial.print(topic);
Serial.print("]");
for (int i = 0; i < newLength; i++) {
newPayload[i] = (char)payload[i];
}
newPayload[newLength] = '\0';
Serial.print(",[");
Serial.print(newPayload);
Serial.println("]");
String topicS = String(topic);
String payloadS = String(newPayload);
if (topicS == TOPIC_LED) {
led.set(payloadS);
client.publish(TOPIC_LED_R,payloadS.c_str(),true);
Serial.printf("PUB: [%s],[%s]\n",topicS.c_str(),payloadS.c_str());
}
}
void setup() {
led.off();
Serial.begin(115200);
Serial.println();
mySerial.begin(mySerialCallback);
////mqtt.begin(myMqttSub,myMqttCallback);
setup_wifi();
client.setClient(espClient);
client.setServer(SERVER,PORT);
client.setCallback(callback);
}
void loop() {
mySerial.run();
if (!client.connected()) {
reconnect();
}
client.loop();
if (timerMsg.isOn()) {
static unsigned long value = 0;
String valueS = String(++value);
client.publish(TOPIC_MSG,valueS.c_str());
Serial.printf("PUB: [%s],[%s]\n",TOPIC_MSG,valueS.c_str());
}
}
//-----
// 시리얼 모니터에서 key,val이 입력될 때마다 수행
//-----
void mySerialCallback(const String& key,const String& val) {
if (key == TOPIC_LED) {
client.publish(TOPIC_LED,val.c_str(),true);
Serial.printf("PUB: [%s],[%s]\n",TOPIC_MSG,val.c_str());
}
}
// topic
#define TOPIC_LED "led" // 1:ON, 0:OFF
#define TOPIC_LED_R "led-r" // LED 상태 응답
#define TOPIC_MSG "msg" // 진행 상태 보고
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호
#define AP_SSID1 "my-ssid1"
#define AP_PASS1 "my-pass1"
#define AP_SSID2 "my-ssid2" // 없으면 ""
#define AP_PASS2 "my-pass2" // 없으면 ""
#define AP_SSID3 "my-ssid3" // 없으면 ""
#define AP_PASS3 "my-pass3" // 없으면 ""
// MQTT 설정
#define SERVER "192.168.XXX.XXX"
#define PORT 1883
#define USER "user"
#define PASS "yourPass"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <PubSubClient.h>
WiFiClient espClient;
ESP8266WiFiMulti wifiMulti;
PubSubClient client;
// 라이브러리
#include <AimOutput.h>
#include <AimSerial.h>
#include <AimTimer.h>
// 오브젝트 생성
AimOutput led(LED_BUILTIN,LOW);
AimSerial mySerial;
AimTimer timerMsg(10);
void setup_wifi() {
randomSeed(micros());
delay(100);
// WiFi station mode
WiFi.mode(WIFI_STA);
wifiMulti.addAP(AP_SSID1,AP_PASS1);
wifiMulti.addAP(AP_SSID2,AP_PASS2);
wifiMulti.addAP(AP_SSID3,AP_PASS3);
Serial.printf("\nConnecting to [%s],[%s],[%s]\n",
AP_SSID1,AP_SSID2,AP_SSID3);
while (wifiMulti.run() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to [");
Serial.print(WiFi.SSID());
Serial.print("],IP=");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
String clientId = "ESP8266-";
clientId += String(random(0xffff), HEX);
Serial.printf("SERVER=[%s],PORT=%d\n",SERVER,PORT);
Serial.printf("device=[%s],USER=[%s],PASS=[***]\n",clientId.c_str(),USER);
// Attempt to connect
if (client.connect(clientId.c_str(),USER,PASS)) {
Serial.println("MQTT connected\n-----");
int QoS = 1;
client.subscribe(TOPIC_LED,QoS);
Serial.printf("SUB: [%s],[%d]\n",TOPIC_LED,QoS);
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
char newPayload[32];
int newLength = length;
if (newLength > 31 ) {
newLength = 31;
}
Serial.print("RCV: [");
Serial.print(topic);
Serial.print("]");
for (int i = 0; i < newLength; i++) {
newPayload[i] = (char)payload[i];
}
newPayload[newLength] = '\0';
Serial.print(",[");
Serial.print(newPayload);
Serial.println("]");
String topicS = String(topic);
String payloadS = String(newPayload);
if (topicS == TOPIC_LED) {
led.set(payloadS);
client.publish(TOPIC_LED_R,payloadS.c_str(),true);
Serial.printf("PUB: [%s],[%s]\n",topicS.c_str(),payloadS.c_str());
}
}
void setup() {
led.off();
Serial.begin(115200);
Serial.println();
mySerial.begin(mySerialCallback);
////mqtt.begin(myMqttSub,myMqttCallback);
setup_wifi();
client.setClient(espClient);
client.setServer(SERVER,PORT);
client.setCallback(callback);
}
void loop() {
mySerial.run();
if (!client.connected()) {
reconnect();
}
client.loop();
if (timerMsg.isOn()) {
static unsigned long value = 0;
String valueS = String(++value);
client.publish(TOPIC_MSG,valueS.c_str());
Serial.printf("PUB: [%s],[%s]\n",TOPIC_MSG,valueS.c_str());
}
}
//-----
// 시리얼 모니터에서 key,val이 입력될 때마다 수행
//-----
void mySerialCallback(const String& key,const String& val) {
if (key == TOPIC_LED) {
client.publish(TOPIC_LED,val.c_str(),true);
Serial.printf("PUB: [%s],[%s]\n",TOPIC_MSG,val.c_str());
}
}
// topic #define TOPIC_LED "led" // 1:ON, 0:OFF #define TOPIC_LED_R "led-r" // LED 상태 응답 #define TOPIC_MSG "msg" // 진행 상태 보고 // 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호 #define AP_SSID1 "my-ssid1" #define AP_PASS1 "my-pass1" #define AP_SSID2 "my-ssid2" // 없으면 "" #define AP_PASS2 "my-pass2" // 없으면 "" #define AP_SSID3 "my-ssid3" // 없으면 "" #define AP_PASS3 "my-pass3" // 없으면 "" // MQTT 설정 #define SERVER "192.168.XXX.XXX" #define PORT 1883 #define USER "user" #define PASS "yourPass" #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <PubSubClient.h> WiFiClient espClient; ESP8266WiFiMulti wifiMulti; PubSubClient client; // 라이브러리 #include <AimOutput.h> #include <AimSerial.h> #include <AimTimer.h> // 오브젝트 생성 AimOutput led(LED_BUILTIN,LOW); AimSerial mySerial; AimTimer timerMsg(10); void setup_wifi() { randomSeed(micros()); delay(100); // WiFi station mode WiFi.mode(WIFI_STA); wifiMulti.addAP(AP_SSID1,AP_PASS1); wifiMulti.addAP(AP_SSID2,AP_PASS2); wifiMulti.addAP(AP_SSID3,AP_PASS3); Serial.printf("\nConnecting to [%s],[%s],[%s]\n", AP_SSID1,AP_SSID2,AP_SSID3); while (wifiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("\nConnected to ["); Serial.print(WiFi.SSID()); Serial.print("],IP="); Serial.println(WiFi.localIP()); } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.println("Attempting MQTT connection..."); String clientId = "ESP8266-"; clientId += String(random(0xffff), HEX); Serial.printf("SERVER=[%s],PORT=%d\n",SERVER,PORT); Serial.printf("device=[%s],USER=[%s],PASS=[***]\n",clientId.c_str(),USER); // Attempt to connect if (client.connect(clientId.c_str(),USER,PASS)) { Serial.println("MQTT connected\n-----"); int QoS = 1; client.subscribe(TOPIC_LED,QoS); Serial.printf("SUB: [%s],[%d]\n",TOPIC_LED,QoS); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void callback(char* topic, byte* payload, unsigned int length) { char newPayload[32]; int newLength = length; if (newLength > 31 ) { newLength = 31; } Serial.print("RCV: ["); Serial.print(topic); Serial.print("]"); for (int i = 0; i < newLength; i++) { newPayload[i] = (char)payload[i]; } newPayload[newLength] = '\0'; Serial.print(",["); Serial.print(newPayload); Serial.println("]"); String topicS = String(topic); String payloadS = String(newPayload); if (topicS == TOPIC_LED) { led.set(payloadS); client.publish(TOPIC_LED_R,payloadS.c_str(),true); Serial.printf("PUB: [%s],[%s]\n",topicS.c_str(),payloadS.c_str()); } } void setup() { led.off(); Serial.begin(115200); Serial.println(); mySerial.begin(mySerialCallback); ////mqtt.begin(myMqttSub,myMqttCallback); setup_wifi(); client.setClient(espClient); client.setServer(SERVER,PORT); client.setCallback(callback); } void loop() { mySerial.run(); if (!client.connected()) { reconnect(); } client.loop(); if (timerMsg.isOn()) { static unsigned long value = 0; String valueS = String(++value); client.publish(TOPIC_MSG,valueS.c_str()); Serial.printf("PUB: [%s],[%s]\n",TOPIC_MSG,valueS.c_str()); } } //----- // 시리얼 모니터에서 key,val이 입력될 때마다 수행 //----- void mySerialCallback(const String& key,const String& val) { if (key == TOPIC_LED) { client.publish(TOPIC_LED,val.c_str(),true); Serial.printf("PUB: [%s],[%s]\n",TOPIC_MSG,val.c_str()); } }
AP(공유기)에 접속하기: AP를 하나만 지정
AP를 한 개만 지정할 때 WiFi 접속 코드의 일부
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호
#define AP_SSID "my-ssid"
#define AP_PASS "my-pass"
#include <ESP8266WiFi.h>
WiFiClient espClient;
void setup_wifi() {
delay(100);
// WiFi station mode
WiFi.mode(WIFI_STA);
WiFi.begin(AP_SSID,AP_PASS);
Serial.printf("\nConnecting to [%s]\n",AP_SSID);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to [");
Serial.print(WiFi.SSID());
Serial.print("],IP=");
Serial.println(WiFi.localIP());
}
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호
#define AP_SSID "my-ssid"
#define AP_PASS "my-pass"
#include <ESP8266WiFi.h>
WiFiClient espClient;
void setup_wifi() {
delay(100);
// WiFi station mode
WiFi.mode(WIFI_STA);
WiFi.begin(AP_SSID,AP_PASS);
Serial.printf("\nConnecting to [%s]\n",AP_SSID);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to [");
Serial.print(WiFi.SSID());
Serial.print("],IP=");
Serial.println(WiFi.localIP());
}
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호 #define AP_SSID "my-ssid" #define AP_PASS "my-pass" #include <ESP8266WiFi.h> WiFiClient espClient; void setup_wifi() { delay(100); // WiFi station mode WiFi.mode(WIFI_STA); WiFi.begin(AP_SSID,AP_PASS); Serial.printf("\nConnecting to [%s]\n",AP_SSID); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("\nConnected to ["); Serial.print(WiFi.SSID()); Serial.print("],IP="); Serial.println(WiFi.localIP()); }
WiFi.status()의 값
typedef enum {
WL_NO_SHIELD = 255,
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL = 1,
WL_SCAN_COMPLETED = 2,
WL_CONNECTED = 3,
WL_CONNECT_FAILED = 4,
WL_CONNECTION_LOST = 5,
WL_DISCONNECTED = 6
} wl_status_t;
typedef enum {
WL_NO_SHIELD = 255,
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL = 1,
WL_SCAN_COMPLETED = 2,
WL_CONNECTED = 3,
WL_CONNECT_FAILED = 4,
WL_CONNECTION_LOST = 5,
WL_DISCONNECTED = 6
} wl_status_t;
typedef enum { WL_NO_SHIELD = 255, WL_IDLE_STATUS = 0, WL_NO_SSID_AVAIL = 1, WL_SCAN_COMPLETED = 2, WL_CONNECTED = 3, WL_CONNECT_FAILED = 4, WL_CONNECTION_LOST = 5, WL_DISCONNECTED = 6 } wl_status_t;
AP(공유기)에 접속하기: AP를 여러 개 지정
AP를 여러개 지정할 때 WiFi 접속 코드의 일부
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호
#define AP_SSID1 "my-ssid1"
#define AP_PASS1 "my-pass1"
#define AP_SSID2 "my-ssid2" // 없으면 ""
#define AP_PASS2 "my-pass2" // 없으면 ""
#define AP_SSID3 "my-ssid3" // 없으면 ""
#define AP_PASS3 "my-pass3" // 없으면 ""
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
WiFiClient espClient;
ESP8266WiFiMulti wifiMulti;
void setup_wifi() {
delay(100);
// WiFi station mode
WiFi.mode(WIFI_STA);
wifiMulti.addAP(AP_SSID1,AP_PASS1);
wifiMulti.addAP(AP_SSID2,AP_PASS2);
wifiMulti.addAP(AP_SSID3,AP_PASS3);
Serial.printf("\nConnecting to [%s],[%s],[%s]\n",
AP_SSID1,AP_SSID2,AP_SSID3);
while (wifiMulti.run() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to [");
Serial.print(WiFi.SSID());
Serial.print("],IP=");
Serial.println(WiFi.localIP());
}
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호
#define AP_SSID1 "my-ssid1"
#define AP_PASS1 "my-pass1"
#define AP_SSID2 "my-ssid2" // 없으면 ""
#define AP_PASS2 "my-pass2" // 없으면 ""
#define AP_SSID3 "my-ssid3" // 없으면 ""
#define AP_PASS3 "my-pass3" // 없으면 ""
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
WiFiClient espClient;
ESP8266WiFiMulti wifiMulti;
void setup_wifi() {
delay(100);
// WiFi station mode
WiFi.mode(WIFI_STA);
wifiMulti.addAP(AP_SSID1,AP_PASS1);
wifiMulti.addAP(AP_SSID2,AP_PASS2);
wifiMulti.addAP(AP_SSID3,AP_PASS3);
Serial.printf("\nConnecting to [%s],[%s],[%s]\n",
AP_SSID1,AP_SSID2,AP_SSID3);
while (wifiMulti.run() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to [");
Serial.print(WiFi.SSID());
Serial.print("],IP=");
Serial.println(WiFi.localIP());
}
// 무선 공유기(AP,엑세스 포인트)의 이름과 비밀번호 #define AP_SSID1 "my-ssid1" #define AP_PASS1 "my-pass1" #define AP_SSID2 "my-ssid2" // 없으면 "" #define AP_PASS2 "my-pass2" // 없으면 "" #define AP_SSID3 "my-ssid3" // 없으면 "" #define AP_PASS3 "my-pass3" // 없으면 "" #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> WiFiClient espClient; ESP8266WiFiMulti wifiMulti; void setup_wifi() { delay(100); // WiFi station mode WiFi.mode(WIFI_STA); wifiMulti.addAP(AP_SSID1,AP_PASS1); wifiMulti.addAP(AP_SSID2,AP_PASS2); wifiMulti.addAP(AP_SSID3,AP_PASS3); Serial.printf("\nConnecting to [%s],[%s],[%s]\n", AP_SSID1,AP_SSID2,AP_SSID3); while (wifiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("\nConnected to ["); Serial.print(WiFi.SSID()); Serial.print("],IP="); Serial.println(WiFi.localIP()); }
WiFi에 접속이 되었다가 접속이 끊어진 경우 별도 명령문을 실행하지 않아도 WiFi에 자동으로 접속을 시도합니다. 따라서 WiFi에 다시 접속하기 위한 코드를 추가로 작성할 필요는 없습니다.
MQTT 브로커에 접속하기
MQTT 브로커에 접속하는 코드의 일부
// MQTT 설정
#define SERVER "192.168.XXX.XXX"
#define PORT 1883
#define USER "user"
#define PASS "yourPass"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <PubSubClient.h>
WiFiClient espClient;
ESP8266WiFiMulti wifiMulti;
PubSubClient client;
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
String clientId = "ESP8266-";
clientId += String(random(0xffff), HEX);
Serial.printf("SERVER=[%s],PORT=%d\n",SERVER,PORT);
Serial.printf("device=[%s],USER=[%s],PASS=[***]\n",clientId.c_str(),USER);
// Attempt to connect
if (client.connect(clientId.c_str(),USER,PASS)) {
Serial.println("MQTT connected\n-----");
int QoS = 1;
client.subscribe(TOPIC_LED,QoS);
Serial.printf("SUB: [%s],[%d]\n",TOPIC_LED,QoS);
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// MQTT 설정
#define SERVER "192.168.XXX.XXX"
#define PORT 1883
#define USER "user"
#define PASS "yourPass"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <PubSubClient.h>
WiFiClient espClient;
ESP8266WiFiMulti wifiMulti;
PubSubClient client;
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
String clientId = "ESP8266-";
clientId += String(random(0xffff), HEX);
Serial.printf("SERVER=[%s],PORT=%d\n",SERVER,PORT);
Serial.printf("device=[%s],USER=[%s],PASS=[***]\n",clientId.c_str(),USER);
// Attempt to connect
if (client.connect(clientId.c_str(),USER,PASS)) {
Serial.println("MQTT connected\n-----");
int QoS = 1;
client.subscribe(TOPIC_LED,QoS);
Serial.printf("SUB: [%s],[%d]\n",TOPIC_LED,QoS);
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// MQTT 설정 #define SERVER "192.168.XXX.XXX" #define PORT 1883 #define USER "user" #define PASS "yourPass" #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <PubSubClient.h> WiFiClient espClient; ESP8266WiFiMulti wifiMulti; PubSubClient client; void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.println("Attempting MQTT connection..."); String clientId = "ESP8266-"; clientId += String(random(0xffff), HEX); Serial.printf("SERVER=[%s],PORT=%d\n",SERVER,PORT); Serial.printf("device=[%s],USER=[%s],PASS=[***]\n",clientId.c_str(),USER); // Attempt to connect if (client.connect(clientId.c_str(),USER,PASS)) { Serial.println("MQTT connected\n-----"); int QoS = 1; client.subscribe(TOPIC_LED,QoS); Serial.printf("SUB: [%s],[%d]\n",TOPIC_LED,QoS); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } }
client.state() 값
// Possible values for client.state()
#define MQTT_CONNECTION_TIMEOUT -4
#define MQTT_CONNECTION_LOST -3
#define MQTT_CONNECT_FAILED -2
#define MQTT_DISCONNECTED -1
#define MQTT_CONNECTED 0
#define MQTT_CONNECT_BAD_PROTOCOL 1
#define MQTT_CONNECT_BAD_CLIENT_ID 2
#define MQTT_CONNECT_UNAVAILABLE 3
#define MQTT_CONNECT_BAD_CREDENTIALS 4
#define MQTT_CONNECT_UNAUTHORIZED 5
// Possible values for client.state()
#define MQTT_CONNECTION_TIMEOUT -4
#define MQTT_CONNECTION_LOST -3
#define MQTT_CONNECT_FAILED -2
#define MQTT_DISCONNECTED -1
#define MQTT_CONNECTED 0
#define MQTT_CONNECT_BAD_PROTOCOL 1
#define MQTT_CONNECT_BAD_CLIENT_ID 2
#define MQTT_CONNECT_UNAVAILABLE 3
#define MQTT_CONNECT_BAD_CREDENTIALS 4
#define MQTT_CONNECT_UNAUTHORIZED 5
// Possible values for client.state() #define MQTT_CONNECTION_TIMEOUT -4 #define MQTT_CONNECTION_LOST -3 #define MQTT_CONNECT_FAILED -2 #define MQTT_DISCONNECTED -1 #define MQTT_CONNECTED 0 #define MQTT_CONNECT_BAD_PROTOCOL 1 #define MQTT_CONNECT_BAD_CLIENT_ID 2 #define MQTT_CONNECT_UNAVAILABLE 3 #define MQTT_CONNECT_BAD_CREDENTIALS 4 #define MQTT_CONNECT_UNAUTHORIZED 5
MQTT 토픽이 수신될 때 callback 함수 사용하기
callback함수
void callback(char* topic, byte* payload, unsigned int length) {
char newPayload[32];
int newLength = length;
if (newLength > 31 ) {
newLength = 31;
}
Serial.print("RCV: [");
Serial.print(topic);
Serial.print("]");
for (int i = 0; i < newLength; i++) {
newPayload[i] = (char)payload[i];
}
newPayload[newLength] = '\0';
Serial.print(",[");
Serial.print(newPayload);
Serial.println("]");
String topicS = String(topic);
String payloadS = String(newPayload);
if (topicS == TOPIC_LED) {
led.set(payloadS);
client.publish(TOPIC_LED_R,payloadS.c_str(),true);
Serial.printf("PUB: [%s],[%s]\n",topicS.c_str(),payloadS.c_str());
}
}
void callback(char* topic, byte* payload, unsigned int length) {
char newPayload[32];
int newLength = length;
if (newLength > 31 ) {
newLength = 31;
}
Serial.print("RCV: [");
Serial.print(topic);
Serial.print("]");
for (int i = 0; i < newLength; i++) {
newPayload[i] = (char)payload[i];
}
newPayload[newLength] = '\0';
Serial.print(",[");
Serial.print(newPayload);
Serial.println("]");
String topicS = String(topic);
String payloadS = String(newPayload);
if (topicS == TOPIC_LED) {
led.set(payloadS);
client.publish(TOPIC_LED_R,payloadS.c_str(),true);
Serial.printf("PUB: [%s],[%s]\n",topicS.c_str(),payloadS.c_str());
}
}
void callback(char* topic, byte* payload, unsigned int length) { char newPayload[32]; int newLength = length; if (newLength > 31 ) { newLength = 31; } Serial.print("RCV: ["); Serial.print(topic); Serial.print("]"); for (int i = 0; i < newLength; i++) { newPayload[i] = (char)payload[i]; } newPayload[newLength] = '\0'; Serial.print(",["); Serial.print(newPayload); Serial.println("]"); String topicS = String(topic); String payloadS = String(newPayload); if (topicS == TOPIC_LED) { led.set(payloadS); client.publish(TOPIC_LED_R,payloadS.c_str(),true); Serial.printf("PUB: [%s],[%s]\n",topicS.c_str(),payloadS.c_str()); } }
void callback(char* topic, byte* payload, unsigned int length);
void callback(char* topic, byte* payload, unsigned int length);
void callback(char* topic, byte* payload, unsigned int length);
첫 번째 매개변수는 topic이며 null로 끝나는 문자열입니다. 문제는 두 번째 매개변수인 payload의 속성이 byte* 이라는 점입니다. 그래서 null로 끝나는 문자열로 처리할 수 없기 때문에 세 번째 매개변수로 length를 지정하고 있습니다. 결국 payload를 null로 끝나는 문자열로 바꾸는 루틴이 추가로 필요합니다. 그 방법은 byte를 char로 형변환하여 복사하고 값의 끝에 \0를 삽입하여 null로 끝나는 문자열로 바꾸는 것입니다.
for (int i = 0; i < newLength; i++) {
newPayload[i] = (char)payload[i];
}
newPayload[newLength] = '\0';
for (int i = 0; i < newLength; i++) {
newPayload[i] = (char)payload[i];
}
newPayload[newLength] = '\0';
for (int i = 0; i < newLength; i++) { newPayload[i] = (char)payload[i]; } newPayload[newLength] = '\0';null로 끝나는 문자열인 topic과 newPayload을 String 속성으로 바꾼 후, 각 토픽에 맞는 후속처리를 하면 편합니다.
함수 setup() 안에 꼭 두어야 할 코드
setup() 코드의 일부
void setup() {
setup_wifi();
client.setClient(espClient);
client.setServer(SERVER,PORT);
client.setCallback(callback);
}
void setup() {
setup_wifi();
client.setClient(espClient);
client.setServer(SERVER,PORT);
client.setCallback(callback);
}
void setup() { setup_wifi(); client.setClient(espClient); client.setServer(SERVER,PORT); client.setCallback(callback); }
함수 loop() 안에 꼭 두어야 할 코드
loop() 코드의 일부
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void loop() { if (!client.connected()) { reconnect(); } client.loop(); }