• 【X806开发板试用】串口数据透传阿里云IOT


    上成果

    在这里插入图片描述

    阿里云对接需要用的是PRODUCTKEY,DEVICENAME和DEVICESECRET,开始直接用MQTT的例子硬怼,没成功,后面看了文档,发现阿里云对接的client_id,username和password是通过三要素生成的。
    在这里插入图片描述

    找了一下代码,发现再device/xradio/xr806/xr_skylark/src/net/cloud/aliyun下面有阿里云的东西,遂打开看了一下,刚好有加密过程。就直接拿过来用了,不过这里出现了一点小插曲,一直引用不到里面的接口。折腾了半天不行,一怒之下,给复制出来了。

    代码

    创建app站内有很多文章就不再赘述,创建好以后代码结构如下:
    在这里插入图片描述

    其中,inc是把device/xradio/xr806/xr_skylark/include/net/cloud/aliyun下面的inc复制出来的;
    src下面的aliyun,是直接把
    device/xradio/xr806/xr_skylark/src/net/cloud/aliyun
    复制出来的;

    wifi,mqtt,uart的都有例子,就拿过来,改一改。大体流程是
    先初始化wifi,连接wifi成功获取到网络权限以后,初始化mqtt的task,待mqtt的task连接到阿里云iot以后,初始化uart task,初始化OK以后开始轮询接收uart1数据,并透传给阿里云。

    不BB了,直接上代码:
    ohosdemo下的BUILD.gn

    group("ohosdemo") {
        deps = [
            #"hello_demo:app_hello",
            "mqtt2uart_demo:app_uart2mqtt",
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    mqtt2uart_demo下的BUILD.gn

    
    import("//device/xradio/xr806/liteos_m/config.gni")
    
    static_library("app_uart2mqtt") {
       configs = []
    
       sources = [
          "src/main.c",
          "src/aliyun/alink_auth.c",
          "src/aliyun/alink_ca.c",
          "src/aliyun/alink_cjson_get.c",
          "src/aliyun/alink_mqtt_client.c",
          "src/aliyun/alink_utils.c",
       ]
    
       cflags = board_cflags
    
       include_dirs = board_include_dirs
       include_dirs += [
          "inc",
          "//kernel/liteos_m/kernel/arch/include",
          "//base/iot_hardware/peripheral/interfaces/kits",
          
          ".",
          "//utils/native/lite/include",
          "//foundation/communication/wifi_lite/interfaces/wifiservice",
          "//device/xradio/xr806/xr_skylark/project"
       ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    main.c

    #include 
    #include "ohos_init.h"
    #include "kernel/os/os.h"
    
    #include "iot_gpio.h"
    #include "wifi_device.h"
    #include "common/framework/net_ctrl.h"
    #include "mqtt_client.h"
    #include "driver/chip/hal_uart.h"
    
    #include "iot_uart.h"
    static OS_Thread_t g_main_thread;
    static OS_Thread_t g_mqtt_thread;
    static OS_Thread_t g_uart_thread;
    
    
    #define WIFI_DEVICE_CONNECT_AP_SSID "XXXXX"//这里填你家路由器的SSID
    #define WIFI_DEVICE_CONNECT_AP_PSK "XXXXX"//这里填你家路由器的PWD
    
    #define MQTT_CLIENT_ID "2022666"
    #define MQTT_HOST_NAME "iot-as-mqtt.cn-shanghai.aliyuncs.com"
    #define MQTT_PORT      "1883"
    #define MQTT_PRODUCTKEY  "a1oz5VdCSZk"
    #define MQTT_DEVICENAME  "DHTER000S"
    #define MQTT_DEVICESECRET  "8368b89e723216bccb471434969391e5"
    #define MQTT_SECUREMODE "2"
    
    #define MQTT_RECV_TOPIC MQTT_PRODUCTKEY"/"MQTT_DEVICENAME"/user/get" //下发TOPIC
    #define MQTT_UPDATE_TOPIC MQTT_PRODUCTKEY"/"MQTT_DEVICENAME"/user/update"//上报TOPIC
    
    #define MQTT_BUF_SIZE (2*1024)
    
    static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer;
    static Client mqtt_demo_client;
    static Network mqtt_demo_network;
    
    #define UART_BUFFER_MAXSIZE 100
    
    static int mqtt_demo_publish(char *topic, char *msg) ;
    
    static int mqtt_demo_init(void) {
        char *send_buf;
        char *recv_buf;
    
        mqtt_para_init();
        aliot_device_info(MQTT_PRODUCTKEY,
    					    MQTT_DEVICENAME,
    					    MQTT_DEVICESECRET,
    					    MQTT_CLIENT_ID,
    					    MQTT_SECUREMODE);
    	
        printf("str_clientID = %s\n", xr_devc_info.client_id);
    	printf("str_user_name = %s\n", xr_devc_info.user_name);
    	printf("sha1_pwd = %s\n", xr_devc_info.password);
    	
    	mqtt_demo_connectData.clientID.cstring = xr_devc_info.client_id;
        mqtt_demo_connectData.keepAliveInterval = 30; // 30s
        mqtt_demo_connectData.cleansession = 0;
        mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1
        
        send_buf = malloc(MQTT_BUF_SIZE);
        if (send_buf == NULL) {
            printf("no memory\n");
            return -1;
        }
        recv_buf = malloc(MQTT_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_BUF_SIZE,
                   (unsigned char *)recv_buf, MQTT_BUF_SIZE);
    
        /* set username and password */
        mqtt_demo_connectData.username.cstring = xr_devc_info.user_name;
        mqtt_demo_connectData.password.cstring = xr_devc_info.password;
        return 0;
    }
    
    static int mqtt_demo_connect(char *host_name, char *host_port) {
        int ret = -1;
    
        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;
        }
    
        ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData);
        if (ret != 0) {
            printf("mqtt connect faild, ret:%d\n", ret);
            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) {
            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) {
            ret = MQTTDisconnect(&mqtt_demo_client);
            if (ret != 0)
                printf("mqtt disconnect fail, ret:%d\n", ret);
            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 uart_task(void *arg)
    {
    	int ret;
    	unsigned int uart_id = 1;
    	unsigned int uart_len;
    	unsigned char uart_rx_buffer[UART_BUFFER_MAXSIZE];
    	unsigned char uart_tx_buffer[UART_BUFFER_MAXSIZE];
    
    	static IotUartAttribute uart_param = { 115200,
    						   IOT_UART_DATA_BIT_8,
    						   IOT_UART_STOP_BIT_1,
    						   IOT_UART_PARITY_NONE,
    						   0,
    						   0,
    						   0 };
    
    	printf("uart%d test start\r\n", uart_id);
    	IoTUartInit(uart_id, &uart_param);
    	
    	IoTUartWrite(uart_id, "uart1 init OK\r\n", 15);
    
    	while (1) {
    		memset((char *)uart_rx_buffer, 0, UART_BUFFER_MAXSIZE);
    		ret = IoTUartRead(uart_id, uart_rx_buffer, UART_BUFFER_MAXSIZE);
    		if (ret > 0) {
    			printf("recv len=%d, data:%s\r\n", ret, uart_rx_buffer);
    			if(0 == mqtt_demo_publish(MQTT_UPDATE_TOPIC, uart_rx_buffer))
    			{
    			    memset(uart_tx_buffer, 0, UART_BUFFER_MAXSIZE);
    			    uart_len = snprintf((char *)uart_tx_buffer,
    								    UART_BUFFER_MAXSIZE,
    								    "uart%d send data:[%s] OK\r\n", 
    								    uart_id, 
    								    uart_rx_buffer);
    			    IoTUartWrite(uart_id, uart_tx_buffer, uart_len);
    			}
    			else
    			{
    				printf("Publish data failed!!\n");
    			}
    		}
    		OS_MSleep(100); //100ms
    	}
    
    exit:
    	IoTUartDeinit(uart_id);
    	OS_ThreadDelete(&g_uart_thread);
    	printf("uart%d test end\r\n", uart_id);
    }
    
    static void mqtt_task(void *arg)   {
        int ret;
        int reconnect_times = 0;
    
        mqtt_demo_init();
    
        ret = mqtt_demo_connect(MQTT_HOST_NAME, MQTT_PORT);
        if (ret != 0)
            goto exit;
    
        ret = mqtt_demo_subscribe(MQTT_RECV_TOPIC);
        if (ret != 0)
            goto exit;
    
    	mqtt_demo_publish(MQTT_UPDATE_TOPIC, "mqtt init OK");
    	if (!OS_ThreadIsValid(&g_uart_thread)) {
    		OS_ThreadCreate(&g_uart_thread, "uart_task",
    							uart_task, (void *)NULL,  OS_THREAD_PRIO_APP, (8 * 1024));
    	}
    
        while (1) {
            ret = MQTTYield(&mqtt_demo_client, 500);
            if (ret != 0) {
                printf("mqtt yield err, ret:%d\n", ret);
    reconnect:
                printf("mqtt reconnect\n");
                mqtt_demo_disconnect();
                ret = mqtt_demo_connect(MQTT_HOST_NAME, MQTT_PORT);
                if (ret != 0) {
                    reconnect_times++;
                    if (reconnect_times > 5)
                        goto exit;
                    OS_MSleep(5000); //5s
                    goto reconnect;
                }
            }
        }
    
    exit:
        printf("mqtt disconnect\n");
        mqtt_demo_unsubscribe(MQTT_RECV_TOPIC);
        mqtt_demo_disconnect();
        mqtt_demo_deinit();
        OS_ThreadDelete(&g_mqtt_thread);
    }
    
    static void net_cb(uint32_t event, uint32_t data, void *arg) {
        uint16_t type = EVENT_SUBTYPE(event);
        switch (type) {
        case NET_CTRL_MSG_NETWORK_UP:
            printf("NET_CTRL_MSG_NETWORK_UP\n");
            if (!OS_ThreadIsValid(&g_mqtt_thread)) {
                OS_ThreadCreate(&g_mqtt_thread, "connect_to_server_task",
                                    mqtt_task, (void *)NULL,  OS_THREAD_PRIO_APP, (8 * 1024));
            }
            break;
        case NET_CTRL_MSG_NETWORK_DOWN:
            break;
        default:
            break;
        }
    }
    
    static void MainThread(void *arg)   {
        printf("MainThread start\r\n");
    	
        if (WIFI_SUCCESS != EnableWifi()) {
            printf("Error: EnableWifi fail\n");
            return;
        }
    
        OS_Sleep(1);
    
        if (WIFI_SUCCESS != Scan()) {
            printf("Error: Scan fail.\n");
            return;
        }
    
        OS_Sleep(3);//这里为了方便用延时,实际用回调更好,否则3秒可能不够
    
        const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID;
        const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK;
        WifiScanInfo scan_results[30];
        unsigned int scan_num = 30;
    
        if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) {
            printf("Error: GetScanInfoList fail.\n");
            return;
        }
    
        WifiDeviceConfig config = { 0 };
        int netId = 0;
    
        int i;
        for (i = 0; i < scan_num; i++) {
            printf("ssid: %s    ", scan_results[i].ssid);
            printf("securityType: %d\n", scan_results[i].securityType);
            if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) {
                memcpy(config.ssid, scan_results[i].ssid,
                       WIFI_MAX_SSID_LEN);
                memcpy(config.bssid, scan_results[i].bssid,
                       WIFI_MAC_LEN);
                strcpy(config.preSharedKey, psk);
                config.securityType = scan_results[i].securityType;
                config.wapiPskType = WIFI_PSK_TYPE_ASCII;
                config.freq = scan_results[i].frequency;
                break;
            }
        }
    
        if (i >= scan_num) {
            printf("Error: No found ssid in scan_results\n");
            return;
        }
    
        if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {
            printf("Error: AddDeviceConfig Fail\n");
            return;
        }
        printf("Config Success\n");
    
        if (WIFI_SUCCESS != ConnectTo(netId)) {
            printf("Error: ConnectTo Fail\n");
            return;
        }
        
        observer_base *net_ob;
        net_ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK, NET_CTRL_MSG_ALL, net_cb, NULL);
        if (net_ob == NULL)
            return;
    
        if (sys_ctrl_attach(net_ob) != 0)
            return;
    
        while (1) {
            OS_MSleep(500);
        }
    }
    
    void UART2MQTTMain(void) {
        if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
            printf("[ERR] Create MainThread Failed\n");
        }
    }
    SYS_RUN(UART2MQTTMain);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365

    遇到的问题

    1.aliyun的lib引用不到
    偷懒,直接复制出来的;
    2.mqtt yield err, ret:-1
    抓包发现,有时候发的keepalive包没有得到响应,怀疑是本地网络不好,后来连上家里的wifi就没问题了。
    做了一个简单的修改,发包一次不响应过会再发一次。三次收不到才认为是短线,才发起reconnect。
    文件:MQTTClient.c
    函数:int keepalive(Client* c)

    修改如下:

    if (expired(&c->last_sent) || expired(&c->last_received))
        {
            if (c->ping_outstanding)
            {
            	MQTT_WARN("PINGRESP not received in keepalive interval %d.\n",c->ping_outstanding);
    		if(c->ping_outstanding <= 3){
    		    Timer timer;
    	            InitTimer(&timer);
    	            countdown_ms(&timer, 1000);
    	            int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
    	            if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet
    					c->ping_outstanding++;
    		    }
    		    else
    		    {
                	rc = FAILURE; /* PINGRESP not received in keepalive interval */
    		    }
               }
    		else
    		{
                    Timer timer;
                    InitTimer(&timer);
                    countdown_ms(&timer, 1000);
                    int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
                    if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet
                        c->ping_outstanding = 1;
               }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    待优化

    1. 串口透传部分目前是接过来数据就上传,没有加缓冲,数据量大时候,可能会丢数据可以加一下队列;
    2. aliyun部分代码引用最好不要复制,引用原位置代码最好;
  • 相关阅读:
    xatlas源码解析(七)
    cento常用命令
    mqtt综合实战(中国移动OneNET+ESP8266 AT指令)
    跑步耳机哪种好,推荐五款在运动中值得佩戴的耳机推荐
    rancher部署nginx服务
    Streamlit学习笔记
    从“专家”视角看:2024年软件测试行业的八大发展趋势!
    【FISCO-BCOS】十八、使用docker部署区块链
    ESP8266-Arduino编程实例-APDS-9930环境光和趋近感器驱动
    FileUpload控件上传文件时出现 不支持给定路径的格式.的解决方法
  • 原文地址:https://blog.csdn.net/weixin_47569031/article/details/136253325