【XR806开发板试用】自带mqtt调试教学
-
。
- 1、下载代码
mkdir xr806_openharmony cd xr806_openharmony repo init -u ssh://git@gitee.com/openharmony-sig/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify -m devboard_xr806.xml repo sync -c repo forall -c 'git lfs pull' **最近仓库在整合,如果下载不了可以去论坛找一下临时仓替换即可**
- 2、环境配置
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-env-setup.md#/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-env-setup-linux.md
- 3、编译准备
https://xr806.docs.aw-ol.com/study/soft_compile/
要注意的是教程里面的这一步文件名是错的,要把deconfig替换成defconfig
之后的make menuconfig这一步不用修改,直接选择save生成.config文件即可
如果出现了
可以打开
/device/xradio/xr806/xr_shylark/project/image_cfg/readme.md
查看解决教程或者根据报错代码修改
/device/xradio/xr806/xr_shylark/project/demo/wlan_ble_demo/image/xr806/image/image_wlan_ble.cfg文件
这是我的修改过的cfg文件,可以编译通过
- 4、固件烧录
https://xr806.docs.aw-ol.com/study/soft_flash/ 根据教程烧录即可,使用波特率921600可以烧录更快
windows下如果烧录时报错,可以跟我这样设置
-
5、使用串口进行调试,波特率设置115200,这里使用的是windows下的SSCOM
调试时如果不出现消息可以点击,打开串口->重新插拔数据线->按下复位键(XR806右下角) -
6、这里使用ubuntu下的mosquito作为服务端
ubuntu安装mosquitto可以参考这个链接 https://www.cnblogs.com/guyk/p/12405938.html
开启mosquito服务 mosquitto -c /etc/mosquitto/mosquitto.conf -d
如果显示1883端口已占用,可以强制结束mosquito后台然后重启服务,这里我使用1884端口
开启服务后板子就可以连接虚拟机进行操作了,可以在mosquito下进行订阅发布信息
如果想要在windows环境下进行订阅发布,可以下载MQTT.fx工具http://mqttfx.jensd.de/index.php/download
- 7、mqtt代码烧录
XR806文件夹里面,是有很多例程的,这里的代码参考自/device/xradio/xr806/xr_shylark/project/example/mqtt/main.c
#include <stdio.h> #include "ohos_init.h" #include "kernel/os/os.h" #include <string.h> #include "wifi_device.h" #include "wifi_hotspot.h" #include "common/framework/platform_init.h" #include "net/wlan/wlan.h" #include "common/framework/net_ctrl.h" #include "net/mqtt/MQTTClient-C/MQTTClient.h" #define WIFI_DEVICE_CONNECT_AP_SSID "Redmi" #define WIFI_DEVICE_CONNECT_AP_PSK "00000000" #define MQTT_DEMO_THREAD_STACK_SIZE (8 * 1024) /* ssl need more stack */ static OS_Thread_t mqtt_demo_thread; static OS_Thread_t g_main_thread; static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer; static Client mqtt_demo_client; static Network mqtt_demo_network; #define MQTT_DEMO_CLIENT_ID "mqt" #define MQTT_DEMO_HOST_NAME "192.168.43.251" #define MQTT_DEMO_PORT "1884" #define MQTT_DEMO_USERNAME "root" #define MQTT_DEMO_PASSWORD "" #define MQTT_DEMO_TOPIC "/vo84Hm3xbUj/xr806_senor_set0/data" #define MQTT_DEMO_BUF_SIZE (2*1024) #define WIFI_START 1 #define MQTT_DEMO_MSG_TEXT "mqtt demo test" void wifi_scan_connect(){ if(WIFI_SUCCESS != EnableWifi()){ printf("Error:wifi enable fail!\n"); return; } if(WIFI_SUCCESS != Scan()){ printf("Error:wifi scan fail!\n"); } printf("WIFI SCAN STARTED!\n"); OS_Sleep(3); WifiScanInfo scan_result[30]; unsigned int scan_num = 30; if(WIFI_SUCCESS != GetScanInfoList(scan_result, &scan_num)){ printf("Error: get scan result fail!\n"); return; } printf("Scan successful,you've got:\n"); for(int i = 0;i < scan_num;i++){ printf("SSID: %s ",scan_result[i].ssid); printf("RSSI: %d",scan_result[i].rssi); } printf("Scan End \n"); const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID; const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK; printf("Connecting..."); if(WIFI_STA_ACTIVE == IsWifiActive()){ printf("Wifi is active.\n"); } OS_Sleep(1); WifiDeviceConfig config = {0}; int netId = 0; int i; for(i = 0;i < scan_num;i++){ if(0 == strcmp(scan_result[i].ssid, ssid_want_connect)){ memcpy(config.ssid, scan_result[i].ssid, WIFI_MAX_SSID_LEN); memcpy(config.bssid, scan_result[i].bssid, WIFI_MAC_LEN); strcpy(config.preSharedKey, psk); config.securityType = scan_result[i].securityType; config.wapiPskType = WIFI_PSK_TYPE_ASCII; config.freq = scan_result[i].frequency; break; } } if(i >= scan_num){ printf("Error: No SSID SET FOUND!\n"); return; } printf("Found Correct SSID in Scan List!\n"); if(WIFI_SUCCESS != AddDeviceConfig(&config, &netId)){ printf("Error: Add Device config failed!\n"); return; } printf("Add Device Config successful!\n"); if(WIFI_SUCCESS != ConnectTo(netId)){ printf("Error: Connect to Wifi FAILED!\n"); return; } printf("Connect to %s successful!\n",config.ssid); OS_Sleep(3); } static int mqtt_demo_init(void) { char *send_buf; char *recv_buf; /* init client id */ mqtt_demo_connectData.clientID.cstring = MQTT_DEMO_CLIENT_ID; /* init keep alive interval */ mqtt_demo_connectData.keepAliveInterval = 30; // 30s /* enable session reuse */ mqtt_demo_connectData.cleansession = 0; /* set mqtt version */ mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1 /* send/recv buffer must free when mqtt deinit */ send_buf = malloc(MQTT_DEMO_BUF_SIZE); if (send_buf == NULL) { printf("no memory\n"); return -1; } recv_buf = malloc(MQTT_DEMO_BUF_SIZE); if (recv_buf == NULL) { free(send_buf); printf("no memory\n"); return -1; } /* init network */ NewNetwork(&mqtt_demo_network); /* init mqtt client object */ MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000, (unsigned char *)send_buf, MQTT_DEMO_BUF_SIZE, (unsigned char *)recv_buf, MQTT_DEMO_BUF_SIZE); /** * set will function, when this client disconnect, * server will sent the message to every client in MQTT_DEMO_TOPIC */ mqtt_demo_connectData.willFlag = 1; mqtt_demo_connectData.will.topicName.cstring = MQTT_DEMO_TOPIC; mqtt_demo_connectData.will.message.cstring = "I am disconnected"; mqtt_demo_connectData.will.retained = 0; mqtt_demo_connectData.will.qos = 0; /* set username and password */ mqtt_demo_connectData.username.cstring = MQTT_DEMO_USERNAME; mqtt_demo_connectData.password.cstring = MQTT_DEMO_PASSWORD; return 0; } static int mqtt_demo_connect(char *host_name, char *host_port) { int ret = -1; /* need connect the server in tcp level first, if use ssl, use TLSConnectNetwork() */ ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port)); if (ret != 0) { printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port); goto exit; } /* if tcp level connected, then connect mqtt level */ ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData); if (ret != 0) { printf("mqtt connect faild, ret:%d\n", ret); /* disconnect the tcp level */ mqtt_demo_network.disconnect(&mqtt_demo_network); goto exit; } printf("mqtt connected\n"); exit: return ret; } static void mqtt_demo_msg_cb(MessageData *data) { printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data, data->message->payloadlen, (char *)data->message->payload); } static int mqtt_demo_subscribe(char *topic) { int ret = -1; if (mqtt_demo_client.isconnected) { /* set the message callback */ ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb); if (ret != 0) printf("mqtt subscribe faild ret:%d\n", ret); } return ret; } static int mqtt_demo_unsubscribe(char *topic) { int ret = -1; if (mqtt_demo_client.isconnected) { ret = MQTTUnsubscribe(&mqtt_demo_client, topic); if (ret != 0) printf("mqtt unsubscribe faild, ret:%d\n", ret); } return ret; } static int mqtt_demo_publish(char *topic, char *msg) { int ret = -1; MQTTMessage message; memset(&message, 0, sizeof(message)); message.qos = 0; message.retained = 0; /* disable retain the message in server */ message.payload = msg; message.payloadlen = strlen(msg); ret = MQTTPublish(&mqtt_demo_client, topic, &message); if (ret != 0) printf("mqtt publish faild, ret:%d\n", ret); return ret; } static int mqtt_demo_disconnect(void) { int ret = -1; if (mqtt_demo_client.isconnected) { /* need disconnect mqtt level first */ ret = MQTTDisconnect(&mqtt_demo_client); if (ret != 0) printf("mqtt disconnect fail, ret:%d\n", ret); /* then disconnect tcp level */ mqtt_demo_network.disconnect(&mqtt_demo_network); } return ret; } static void mqtt_demo_deinit(void) { if (mqtt_demo_client.buf) { free(mqtt_demo_client.buf); mqtt_demo_client.buf = NULL; } if (mqtt_demo_client.readbuf) { free(mqtt_demo_client.readbuf); mqtt_demo_client.readbuf = NULL; } } static void mqtt_demo_fun(void *arg) { int ret; int reconnect_times = 0; /* mqtt init */ mqtt_demo_init(); /* mqtt connect */ re: ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT); if (ret != 0) OS_MSleep(500); goto re; /* subscribe topic */ ret = mqtt_demo_subscribe(MQTT_DEMO_TOPIC); if (ret != 0) goto exit; while (1) { /* publish message to topic */ mqtt_demo_publish(MQTT_DEMO_TOPIC, MQTT_DEMO_MSG_TEXT); ret = MQTTYield(&mqtt_demo_client, 300); if (ret != 0) { printf("mqtt yield err, ret:%d\n", ret); reconnect: printf("mqtt reconnect\n"); mqtt_demo_disconnect(); ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT); if (ret != 0) { reconnect_times++; if (reconnect_times > 5) goto exit; OS_MSleep(5000); //5s goto reconnect; } } OS_MSleep(1000); //1s } exit: mqtt_demo_unsubscribe(MQTT_DEMO_TOPIC); mqtt_demo_disconnect(); mqtt_demo_deinit(); OS_ThreadDelete(&mqtt_demo_thread); } static void MainThread(void *arg){ #if WIFI_START == 1 wifi_scan_connect(); #endif } int main(void) { if(OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK){ printf("[ERR] Create MainThread Failed\n"); } if (OS_ThreadCreate(&mqtt_demo_thread, "mqtt_demo_thread", mqtt_demo_fun, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) { printf("[ERR] Create MainThread Failed\n"); } } SYS_RUN(main);
#define WIFI_DEVICE_CONNECT_AP_SSID "Redmi" #define WIFI_DEVICE_CONNECT_AP_PSK "00000000"
- 在这里可以设置XR806连接的wifi SSID和密码
#define MQTT_DEMO_CLIENT_ID "mqt" #define MQTT_DEMO_HOST_NAME "192.168.43.251" #define MQTT_DEMO_PORT "1884" #define MQTT_DEMO_USERNAME "root" #define MQTT_DEMO_PASSWORD "" #define MQTT_DEMO_TOPIC "/vo84Hm3xbUj/xr806_senor_set0/data"
-
这里的HOST_NAME根据你的虚拟机ip进行修改,查看虚拟机ip可以使用ifconfig -a进行查看,另外我的虚拟机网络选择的是直接复制物理网络连接状态
-
MQTT_DEMO_TOPIC为你订阅的主题,可以随便设置,订阅的时候代码做出相应修改即可
-
MQTT_DEMO_USERNAME是刚才在mosquito配置的账号root
wifi_scan_connect()
- 这个函数是连接wifi,连接wifi后mqtt就可以连接上虚拟机的服务端
int main(void) { if(OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK){ printf("[ERR] Create MainThread Failed\n"); } if (OS_ThreadCreate(&mqtt_demo_thread, "mqtt_demo_thread", mqtt_demo_fun, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) { printf("[ERR] Create MainThread Failed\n"); } }
- 这个是main函数,创建两个线程,一个连接wifi一个,连接mqtt
要注意的是使用SYS_RUN的时候要包含这个头文件,否则编译出错
#include "ohos_init.h"
- 可以看到只有一个mqtt文件夹和main.c文件,非常简单
-
这个是mqtt目录下的BUILD.gn
包含wifi头文件和mqtt头文件即可 -
8、编译文件
执行hb build -f//首次编译加-f,之后不用
执行 sudo cp ~/xr806_openharmony/device/xradio/xr806/xr_skylark/out/xr_system.img /home/用户名/ 将编译后的xr_system.img复制到用户目录
最后进行烧录即可运行mqtt,我使用的是安卓手机开wifi给电脑和XR806连接,虚拟机复制物理网络同时运行mosquito,mqtt连接上mosquito即可进行订阅和发布
使用mosquitto订阅XR806的消息 mosquitto_sub -h 192.168.43.251 -p 1884 "你设置的主题名字" -u "root"
使用mosquitto给XR806发布消息 mosquitto_pub -h 192.168.43.251 -p 1884 "你设置的主题名字" -m "想要给XR806发的消息" -u "root"
- 要注意的是-p选项填你在mosquito.conf文件设置的端口,-h选项填你的服务端ip地址,在这里是我的ubuntu的ip地址
成功进行mqtt连接后就可以进行wifi和mqtt的学习了
-
@mocul 太棒啦
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号