2018年8月26日日曜日

mbedでMQTTのパブリッシュとサブスクライブ

今回はmbedをつかっていきまぁす。
mbedの記事は今回がお初かと。

今回は備忘録臭が強めです(笑)
ethernetケーブルは100均のケーブルを剥いで使うもよし、
RJ45買うもよし、(当方ではHR911105Aを使用)
そんなかんじで配線してください。(適当)

こちらのコードを大体パクった感じですが、一部RTOS仕様にして、
パブリッシャーを関数にくるめただけです。

#include "easy-connect.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
#include "MQTTClient.h"
#include "rtos.h"
/**
* @brief入出力の宣言
*
*/
DigitalOut status_LED(LED4);
/**
* @brief MQTTのメッセージ購読時にコールバックされる関数
*
* @param md メッセージが格納されたデータ
*/
void messageArrived(MQTT::MessageData& md)
{
MQTT::Message &message = md.message;
printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
printf("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
}
/**
* @brief MQTTをQOS1でパブリッシュする関数
*
* @param client アクティブなMQTT::Client
* @param topic パブリッシュするトピック名
* @param mes  パブリッシュするメッセージの内容
* @return int パブリッシュが成功したかの判定
*/
int publisher(MQTT::Client<MQTTNetwork, Countdown> client, char* topic,char* mes){
MQTT::Message message;
message.qos = MQTT::QOS1;
message.retained = false;
message.dup = false;
message.payload = (void*)mes;
message.payloadlen = strlen(mes);
int rc = client.publish(topic, message);
return rc;
}
/**
* @brief MQTTの通信をメインに行うスレッド。RTOSにて常時実行
*
*/
void MQTT_Comm_thread()
{
char pubmsgs[100];
NetworkInterface* network = easy_connect(true);
while (!network) {
exit(-1);
}
MQTTNetwork mqttNetwork(network);
MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
const char* hostname = "10.42.0.1"; //ブローカーのアドレス
int port = 1883; //プローカーのポート
printf("Connecting to %s:%d\r\n", hostname, port);
int rc = mqttNetwork.connect(hostname, port);
if (rc != 0)
printf("rc from TCP connect is %d\r\n", rc);
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.MQTTVersion = 3;
data.clientID.cstring = "mbed-sample";
data.username.cstring = "testuser";
data.password.cstring = "testpassword";
if ((rc = client.connect(data)) != 0)
printf("rc from MQTT connect is %d\r\n", rc);
while(1){
rc = client.subscribe("mbed_test", MQTT::QOS1, messageArrived);
sprintf(pubmsgs,"{\"data\": [%d, %d, %d, %d], \"layout\": {\"dim\": [], \"data_offset\": 0}}",0,1,2,3);
rc = publisher(client,"mbed_json_data",pubmsgs);
}
if ((rc = client.disconnect()) != 0)
printf("rc from disconnect was %d\r\n", rc);
mqttNetwork.disconnect();
}
/**
* @brief エントリポイント
*
*/
int main(int argc, char **argv){
/* Start Thread */
Thread thread_comm(MQTT_Comm_thread);
while(1){
status_LED = !status_LED;
}
return 0;
}
view raw main.cpp hosted with ❤ by GitHub



いままで、マイコンとはUSB経由のシリアル通信でパソコンと
通信していたのですが、ポートが変わったり、
Ubuntuだとパーミッションなども気にしないといけなく、
結構うんざりしてたため、MQTTを用いた通信に踏み切ったわけです。
お察しだとは思いますが、MQTT-bridgeのROSパッケージのstd_msgs::Int32MultiArrayに
準拠したjsonの記述でパブリッシュのメッセージを記述しています(笑)
イーサネット特有の面倒くささなども出てきますが、
USBシリアル通信の癖の強さよりはマシかと。
んまぁ、おいおい使ってみてですかねぇ