OpenHarmony Neptune开发板-MQTT连接华为IoT平台

开发 前端
本次我修改程序,解决了CPU异常(直接不能运行)和平台命令下发错误问题,并测试20~30分钟,确保稳定运行,并将一些遇到问题做相关介绍。

[[428086]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言:

之前有发过Neptune开发板-MQTT连接华为IoT平台文章,但发现写的程序有很大BUG,导致程序运行到开发板经常发生CPU异常(直接不能运行)和平台命令下发错误,在此和之前使用我写的程序发生问题的人说一句抱歉,本次我修改程序,解决了CPU异常(直接不能运行)和平台命令下发错误问题,并测试20~30分钟,确保稳定运行,并将一些遇到问题做相关介绍。

介绍:

本示例将演示如何在Neptune开发板上使用MQTT协议连接华为IoT平台,使用的是ATH20温湿度传感器模块与Neptune开发板

本示例实现AHT20温湿度数据上报华为IoT平台,IoT平台下发命令控制LED灯的开关

使用W800 SDK功能包中libemqtt来实现连接华为IoT平台

程序设计

一、MQTT初始化

void mqtt_init(mqtt_broker_handle_t* broker, const char* clientid); 
  • 1.

初始化要连接到代理的信息

二、写入username与password

void mqtt_init_auth(mqtt_broker_handle_t* broker, const char* username, const charpassword); 
  • 1.

启用身份验证以连接到代理。

三、建立TCP连接

编写TCP连接函数,代码示例如下:

static int init_socket(mqtt_broker_handle_t *broker, const char *hostname, short port, int keepalive) 

    int flag = 1; 
    struct hostent *hp; 
 
    // 创建套接字 
    if((socket_id = socket(PF_INET, SOCK_STREAM, 0)) < 0) 
        return -1; 
 
    // 禁用Nagle算法 
    if (setsockopt(socket_id, IPPROTO_TCP, 0x01, (char *)&flag, sizeof(flag)) < 0) 
    { 
        close_socket(&mqtt_broker); 
        return -2; 
    } 
 
    // 查询主机IP启动 
    hp = gethostbyname(hostname); 
    if (hp == NULL ) 
    { 
        close_socket(&mqtt_broker); 
        return -2; 
    } 
 
    struct sockaddr_in socket_address; 
    memset(&socket_address, 0, sizeof(struct sockaddr_in)); 
    socket_address.sin_family = AF_INET; 
    socket_address.sin_port = htons(port); 
    memcpy(&(socket_address.sin_addr), hp->h_addr, hp->h_length); 
 
    // 连接套接字 
    if((connect(socket_id, (struct sockaddr *)&socket_address, sizeof(socket_address))) < 0) 
    { 
        close_socket(&mqtt_broker); 
        return -1; 
    } 
 
    // MQTT stuffs 
    mqtt_set_alive(broker, mqtt_keepalive); 
    broker->socketid = socket_id; 
    broker->mqttsend = send_packet; 
    return 0; 

  • 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.

四、建立MQTT连接

int mqtt_connect(mqtt_broker_handle_t* broker); 
  • 1.

五、订阅MQTT

编写订阅MQTT主题函数,代码示例如下:

static int subscribe_topic(char *topic)//订阅主题 

    unsigned short msg_id = 0, msg_id_rcv = 0; 
    int packet_lengthgth = 0; 
    int ret = -1; 
  
    if(topic == NULL) { 
        return -1; 
    } 
     
    ret = mqtt_subscribe(&mqtt_broker, topic, &msg_id); 
    if( ret == -1 ) { 
        close_socket(&mqtt_broker); 
        return -1; 
    } 
    packet_lengthgth = read_packet(MQTT_DEMO_READ_TIME_SEC, MQTT_DEMO_READ_TIME_US); 
    if(packet_lengthgth < 0) 
    { 
        printf("Error(%d) on read packet!\n", packet_lengthgth); 
        close_socket(&mqtt_broker); 
        return -1; 
    } 
  
    if(MQTTParseMessageType(pcaket_buffer) != MQTT_MSG_SUBACK) 
    { 
        printf("SUBACK expected!\n"); 
        close_socket(&mqtt_broker); 
        return -2; 
    } 
  
    msg_id_rcv = mqtt_parse_msg_id(pcaket_buffer); 
    if(msg_id != msg_id_rcv) 
    { 
        printf("%d message id was expected, but %d message id was found!\n", msg_id, msg_id_rcv); 
        close_socket(&mqtt_broker); 
        return -3; 
    } 
  
    return 0; 

  • 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.

数据推送与解析

采用cJSON封包与解包(使用W800 SDK功能包中cJSON实现),共有两个封包(一个设备属性上报,一个命令应答上报),一个解包解析IoT平台命令,其他不过多赘述具体详见华为IoTDA 设备接入文档:设备接入 IoTDA 文档

例如设备属性上报,代码示例如下:

/*************************打包发布请求*****************/ 
static int packPublishReq(char *jsonBuffer) 

    cJSON *jsRet = NULL
    cJSON *jsArray = NULL
    int ackLen = 0; 
     
    jsRet = cJSON_CreateObject(); 
    if(jsRet) 
    {    
        jsArray = cJSON_CreateArray(); 
        cJSON_AddItemToObject(jsRet, "services", jsArray); 
        { 
            cJSON *arrayObj_1 = cJSON_CreateObject(); 
            cJSON_AddItemToArray(jsArray, arrayObj_1); 
            cJSON_AddStringToObject(arrayObj_1, "service_id""Temperature"); 
 
            cJSON *arrayObj_2 = cJSON_CreateObject(); 
            cJSON_AddItemToObject(arrayObj_1, "properties", arrayObj_2); 
            cJSON_AddStringToObject(arrayObj_2, "temp", Temperature.temp); 
            cJSON_AddStringToObject(arrayObj_2, "humi", Temperature.humi); 
            cJSON_AddStringToObject(arrayObj_2, "led",  Temperature.ON_OFF); 
             
            cJSON_AddStringToObject(arrayObj_1,"event_time", Temperature.timestamp); 
        } 
        char *databuf = cJSON_PrintUnformatted(jsRet); 
        if(databuf) { 
            if( jsonBuffer ) { 
                ackLen = strlen(databuf); 
                memcpy( jsonBuffer, databuf,ackLen); 
            } 
            tls_mem_free(databuf); 
        } 
        cJSON_Delete(jsRet);  
    } 
    return ackLen; 

  • 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.

数据应答(重点)

按照华为云IoT设备平台命令下发文档需要将

下行中的request_id={request_id} 复制到上行中,只有这样下行与上行request_id相同才能保证平台命令数据下发成功任务

下行 $oc/devices/{device_id}/sys/commands/request_id={request_id} 
  • 1.
上行:$oc/devices/{device_id}/sys/commands/response/request_id={request_id} 
  • 1.

这里展示一小段代码:

len = mqtt_parse_pub_topic(pcaket_buffer, topic);    //接收平台下发的topic 
        topic[len] = '\0'
        len = mqtt_parse_publish_msg(pcaket_buffer, &msg); 
           strncpy(request_id,topic+63,47);                         
           sprintf(ACK_TOPIC,"%s%s",MQTT_DEMO_ACK_TOPIC,request_id);//复制request_id={request_id} 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

 这里我出的问题就在->strncpy(request_id,topic+63,47);在我之前是topic+62 而且再我之前创建demo平台下发成功,就没想了,但在这几天测试时就发现这问题故说明。

CPU中断异常问题

由于定时器使用不当,导致CPU中断异常,致程序崩溃(以更改)

华为IoT平台配置

请参考:BearPi-HM_Nano开发板WiFi编程开发——MQTT连接华为IoT平台(Demo我以导出模型)

添加华为云IoT参数:(这只是示例,无法使用)

#define MQTT_DEMO_CLIENT_ID            "616268529fff74057ddd731b_202110101314_0_0_2021101006"                        //ID 
#define MQTT_DEMO_DEVICE_ID            "616268529fff74057ddd731b_202110101314" 
#define MQTT_DEMO_PASSWORD             "b6fd9631cd69eee9ce565a36564b93d26760a49ace05be96cbe9dfaab91f275d" 
#define MQTT_DEMO_SUB_TOPIC            "$oc/devices/616268529fff74057ddd731b_202110101314/sys/commands/#"             //订阅主题 
#define MQTT_DEMO_PUB_TOPIC            "$oc/devices/616268529fff74057ddd731b_202110101314/sys/properties/report"      //发布主题 
#define MQTT_DEMO_ACK_TOPIC            "$oc/devices/616268529fff74057ddd731b_202110101314/sys/commands/response/" 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 在wifi_connecter.h修改wifi热点信息

示例代码编译烧录代码后,按下开发板的RESET按键:

OpenHarmony Neptune开发板-MQTT连接华为IoT平台-鸿蒙HarmonyOS技术社区

点击设备右侧的“查看”,进入设备详情页面,可看到上报的数据。

OpenHarmony Neptune开发板-MQTT连接华为IoT平台-鸿蒙HarmonyOS技术社区

在华为云平台设备详情页,单击“命令”,选择同步命令下发,选中创建的命令属性,单击“确定”,即可发送下发命令控制设备。

OpenHarmony Neptune开发板-MQTT连接华为IoT平台-鸿蒙HarmonyOS技术社区

总结:

现以解决经常发生CPU异常(直接不能运行)和平台命令下发错误,同时创建使用两个定时器,一个20秒上报AHT20数据,一个1分钟ping一次(用以保活),使之稳定运行,支持1.0版本与1.1版本。

注意:!!!需要将libemqtt.h下!!!

MQTT_CONF_USERNAME_LENGTH 修改为64 
MQTT_CONF_PASSWORD_LENGTH 修改为64+8 
clientid[50]修改为clientid[64] 
  • 1.
  • 2.
  • 3.

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-09-10 10:01:04

鸿蒙HarmonyOS应用

2021-09-13 10:03:35

鸿蒙HarmonyOS应用

2021-09-08 15:44:56

鸿蒙HarmonyOS应用

2022-04-01 15:54:01

DHCP网络协议开发板

2022-01-07 21:11:27

鸿蒙HarmonyOS应用

2020-11-17 12:15:36

MQTT开发

2021-05-10 09:40:29

鸿蒙HarmonyOS应用

2021-09-14 10:09:33

开源MowiSeptentrio

2020-12-16 10:05:48

鸿蒙开发板Onenet平台

2020-10-20 09:32:43

HiSparkWi-FiIoT

2022-10-14 15:55:24

环境搭建鸿蒙

2021-12-16 15:14:54

鸿蒙HarmonyOS应用

2022-03-03 19:21:50

Harmony鸿蒙操作系统

2021-12-15 15:28:18

鸿蒙HarmonyOS应用

2020-12-29 09:59:01

鸿蒙HarmonyOS智能家居

2021-12-28 16:06:15

鸿蒙HarmonyOS应用

2021-06-25 15:32:13

鸿蒙HarmonyOS应用

2022-02-24 16:39:41

OpenHarmonNiobe开发鸿蒙

2020-10-23 09:50:15

HiSpark Wi-开发套件
点赞
收藏

51CTO技术栈公众号