各記事リンク
本編へ
以前の記事からの続きで,前回までに用意・確認したCloudMQTT環境を使います.
これについては以前の記事を参照してください.
環境
- Raspberry Pi 3 Model B (2台)
- Raspbian stretch 9.4
- Ethernetでそれぞれインターネットに接続
- Mosquittoライブラリ(以前の記事でインストールを行ってください)
受信プログラム
受信側のRaspberry Piで以下のCプログラムを作成してください.
ファイル名はなんでも構いませんが,私は「MQTTsub.c」としました.
Cファイル
#include <stdio.h> #include <stdlib.h> #include <string.h> //strlen(); #include <stdio.h> #include <stdlib.h> #include <string.h> //strlen(); #include <unistd.h> //sleep(); #include <signal.h> //signal(); //mosquittoライブラリが必要です //$ sudo apt-get install software-properties-common //$ sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa //$ sudo apt-get install libmosquitto-dev #include <mosquitto.h> void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg); void endCatch(int); struct mosquitto *mosq; int main() { //↓↓↓ここからを編集する↓↓↓ //MQTT Brokerの設定 (CloudMQTT) const char *ip = "ほげほげ.cloudmqtt.com"; //サーバのIPアドレスまたはドメイン名 const int port = 54321; //サーバのポート番号 const char *username = "username"; //サーバのユーザネーム const char *password = "password"; //サーバのパスワード //MQTTの設定 const char *id = "RasPi2"; //発信者ごとに変える const char *topic = "topic1/sub1"; //送信するデータを区別するためのもの(受信側と統一する) //↑↑↑ここまでを編集する↑↑↑ //Ctrl + Cなどによって強制終了するときに、終了時用の処理を呼び出す設定 signal(SIGINT , endCatch ); printf( "Prepareing mosquitto...\n" ); //mosquittoの最初に呼び出す初期化関数 mosquitto_lib_init(); //mosquitto実態の作成 mosq = mosquitto_new(id, 0, NULL); //失敗してたら if(!mosq) { perror( "Failed to create mosquitto\n" ); mosquitto_lib_cleanup(); return -1; } //ユーザ名、パスワードを教える mosquitto_username_pw_set(mosq, username, password); //受信した時に自動で呼び出す関数を指定する mosquitto_message_callback_set( mosq, on_message ); //サーバーに接続する mosquitto_connect(mosq, ip, port, 60); printf( "Server (%s:%d) connected!\n", ip, port ); //購読登録する mosquitto_subscribe( mosq, NULL, topic, 0 ); //MQTTの受信を永久に待機する mosquitto_loop_forever(mosq, -1, 1); //(Ctrl+Cでプログラムを終了するまで) return 0; } //トピック受信時の処理 void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) { if(msg->payloadlen > 0) { //受信したpayloadには終端文字\0がないので追加する char msgtext[msg->payloadlen + 1]; strncpy(msgtext, msg->payload, msg->payloadlen); msgtext[msg->payloadlen] = '\0'; //文字列終端文字を追加 printf( "Message %s about %s received\n", msgtext, msg->topic ); } else { printf("(null) about %s\n", msg->topic); } } //プログラム終了時の処理 void endCatch(int sig) { mosquitto_destroy(mosq); mosquitto_lib_cleanup(); printf("End Program\n\n"); exit(0); }
ビルド
これをコマンドでビルドします.
Cファイルを作成した場所で以下のコマンドを実行します.
gcc MQTTsub.c -o MQTTsub -lmosquitto
コマンドの意味は
- gcc : C言語をビルドするコマンド
- MQTTsub.c : Cのファイル名(自分で作成したもの)
- -o : ビルドした後の実行ファイルの名前を指定
- MQTTsub : ビルドした後の実行ファイルの名前
- -lmosquitto : ライブラリ「mosquitto」を使用する
です.
エンターキーを押して,エラーなどが出なければ成功です.
実行
以下のコマンドでプログラムを実行します.
./MQTTsub
(実際にはRaspberry Piで実行します.私はSSHでMacからRaspberry Piをリモート制御しています.)
このように2行だけ出力されて停止するはずです.
データを受信すると,随時新しい行が追加されていきます.
送受信チェック
では作成した受信プログラムを送信プログラムとは違うRaspberry Piで実行してみましょう.
(同じRaspberry Piでも構いません.その場合はターミナルを2つ立ち上げてください.)
送信側でMQTTpubを受信側でMQTTsubをそのまま実行すれば良いです.
以下は左が受信側,右が送信側の画面です.
このように「Hello MQTT」という文字列が送信されていることがわかります.
なお,CloudMQTTはアメリカまたはヨーロッパのサーバを介するため,150〜400[ms]遅延します.
(当方ではアメリカで175[ms],ヨーロッパで350[ms]程度で比較的安定していました)
参考
MQTT Client -C言語- - Qiita http://altenergy-system.com/archives/4172