아두이노에서 MQTT 브로커에 접속하기 위한 클라이언트 라이브러리는 PubSubClient.h입니다.
PubSubClient.h 바로가기 다음 프로그램은 제12장의 프로그램 12-1 mqtt-led-control을 AimMqtt.h의 도움없이 직접 PubSubClient.h를 이용하여 구현한 것입니다.AP(공유기)에 접속하기: AP를 하나만 지정
WiFi.begin(AP_SSID,AP_PASS) 메소드로 WiFi에 접속합니다. WiFi.status()의 값이 WL_CONNECTED가 되면 WiFi 접속이 완료됩니다. WiFi.status()의 코드 값은 다음과 같이 정의되어 있습니다. 따라서 WiFi가 접속이 되면 WiFi.status()의 값은 3이 됩니다.
AP(공유기)에 접속하기: AP를 여러 개 지정
wifiMulti.addAP(AP_SSIDn,AP_PASSn) 메소드로 WiFi를 여러 개 지정한후 wifiMulti.run()으로 접속을 시도합니다. 이 때 가장 신호가 강한 AP(공유기)에 접속이 됩니다. wifiMulti.run()은 실행 결과를 숫자로 돌려주는데 그 값은 위의 WiFi.status()와 동일합니다.
WiFi에 접속이 되었다가 접속이 끊어진 경우 별도 명령문을 실행하지 않아도 WiFi에 자동으로 접속을 시도합니다. 따라서 WiFi에 다시 접속하기 위한 코드를 추가로 작성할 필요는 없습니다.
MQTT 브로커에 접속하기
client.connect(디바이스,사용자,비밀번호) 메소드를 사용하여 MQTT 브로커에 접속을 시도하고 성공 여부를 돌려 받습니다. MQTT에 접속되어 있는지는 client.connected() 메소드로 확인할 수 있습니다. 접속과 관련된 자세한 내용은 client.state()로 알 수 있습니다. 그 값은 다음과 같습니다.
MQTT 토픽이 수신될 때 callback 함수 사용하기
client.subscribe(토픽,QoS)로 구독한 토픽의 내용이 수신될 때마다 실행되는 함수입니다. 이 함수 프로토타입은 다음과 같습니다.
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';null로 끝나는 문자열인 topic과 newPayload을 String 속성으로 바꾼 후, 각 토픽에 맞는 후속처리를 하면 편합니다.