> 文档中心 > W801通过一机一密的方式连接阿里云物联网平台并实现反向控制

W801通过一机一密的方式连接阿里云物联网平台并实现反向控制


一.项目概述

本项目使用了W801以一机一密的方式连接至阿里云物联网平台,定时发送数据并实现了反向控制。

二.项目前的准备

因为使用阿里云物联网平台,因此需要提前创建好一个设备,这个网上的示例和阿里云自己的文档已经十分完整,因此不多赘述,可以自行查阅。创建完设备的MQTT链接参数是用来进行链接的关键,如下图所示。
在这里插入图片描述

三.MQTT连接的注意点与修改

概述:SDK中提供的MQTT链接示例基本是可用的,但是连接阿里云时需要做如下修改。
【1】修改MQTT链接参数,同时要添加Username以及password的宏定义,订阅和发布的topic根据自己的设备来添加
在这里插入图片描述

【2】修改MQTT的client,username等的数组长度,SDK中的数据范围太小,而阿里云的链接参数由于经过加密因此比较长无法满足要求,需要对以下几个位置进行修改。
在这里插入图片描述

【3】修改原MQTTdemo里面的mqtt_demo_init函数,原函数没有账户密码登录的步骤,但是提供了相应函数,因此需要进行补充。
在这里插入图片描述

四.MQTT连接并实现定时上传

【1】概述:在原demo上修改,添加了一个硬件定时器,定时5s后在中断服务函数,向队列里添加一个MQTT_MSG_PUBLISH_CB标志,主循环读取到这个标志后会进行mqtt消息发送,这边还涉及到一个数据处理成为JSON格式,我这里只发送一个温度信息,格式为{“temperature”:“20”},用的就是cJSON库,这个参考下网上其他文章即可。
【2】代码如下:

//mqtt消息发送函数static int mqtt_msg_pub(void){char *temperature_msg;temperature_msg = datatoJSON(temp_label, temperature);mqtt_publish(&mqtt_demo_mqtt_broker, (const char *)MQTT_DEMO_RX_PUB_TOPIC,  (const char *)temperature_msg, strlen(temperature_msg), 0);tls_os_queue_send(mqtt_demo_task_queue, (void *)MQTT_DEMO_CMD_LOOP, 0);return 0;}//demo中原来的主循环static void mqtt_demo_task(void *p){    int ret;    void *msg;    struct tls_ethif *ether_if = tls_netif_get_ethif();    if (ether_if->status)    { wm_printf("sta ip: %v\n", ether_if->ip_addr.addr); tls_os_queue_send(mqtt_demo_task_queue, (void *)MQTT_DEMO_CMD_START, 0);    }    for ( ; ; )    { ret = tls_os_queue_receive(mqtt_demo_task_queue, (void **)&msg, 0, 0); if (!ret) {     switch((u32)msg)     {     case MQTT_DEMO_CMD_START:  do  {      ret = mqtt_demo_init();      if (ret)   break;      tls_os_queue_send(mqtt_demo_task_queue, (void *)MQTT_DEMO_CMD_LOOP, 0);timer_pub();  }  while (0);  break;     case MQTT_DEMO_CMD_HEART:  //wm_printf("send heart ping\r\n");  mqtt_ping(&mqtt_demo_mqtt_broker);  break;     case MQTT_DEMO_CMD_LOOP:  mqtt_demo_loop();  break;case MQTT_MSG_PUBLISH_CB:   //添加一个新的标志,读取到这个标志时候,进行消息发送mqtt_msg_pub();break;     default:  break;     } }    }}//中断函数中向队列添加标志static void timer_pub_irq(u8 *arg){//printf("timer irq\n");tls_os_queue_send(mqtt_demo_task_queue, (void *)MQTT_MSG_PUBLISH_CB, 0);}//上传数据硬件定时器int timer_pub(void){u8 timer_id;struct tls_timer_cfg timer_cfg;timer_cfg.unit = TLS_TIMER_UNIT_MS;timer_cfg.timeout = 5000;timer_cfg.is_repeat = 1;timer_cfg.callback = (tls_timer_irq_callback)timer_pub_irq;timer_cfg.arg = NULL;timer_id = tls_timer_create(&timer_cfg);tls_timer_start(timer_id);return WM_SUCCESS;}

四.阿里云反向控制

【1】阿里云实际上可以采用物模型进行反向控制,但是那个相对比较麻烦,这里我采用一个比较通用的办法,w801订阅了一个topic接受该topic命令并解析,再进行对应操作。这一部分逻辑与我前一篇文章,蓝牙反向控制相似,这里给出链接可以作为参考。
W801上电自动重连wifi并通过蓝牙更新账号密码
【2】代码:

static int mqtt_demo_loop(void){int packet_length = 0;    int counter = 0;counter++;packet_length = mqtt_demo_read_packet(0, 1);    if(packet_length > 0)    { if (MQTTParseMessageType(mqtt_demo_packet_buffer) == MQTT_MSG_PUBLISH) {     uint8_t topic[100], *msg;     uint16_t len;     len = mqtt_parse_pub_topic(mqtt_demo_packet_buffer, topic);     topic[len] = '\0'; // for printf     len = mqtt_parse_publish_msg(mqtt_demo_packet_buffer, &msg);     msg[len] = '\0'; // for printf     //wm_printf("recvd: %s >>> %s\n", topic, msg);aliyun_cmd_excute(msg); } tls_os_queue_send(mqtt_demo_task_queue, (void *)MQTT_DEMO_CMD_LOOP, 0);    }    else if (packet_length == MQTT_DEMO_READ_TIMEOUT)    { tls_os_queue_send(mqtt_demo_task_queue, (void *)MQTT_DEMO_CMD_LOOP, 0);    }    else if(packet_length == -1)    { wm_printf("mqtt error:(%d), stop mqtt demo!\n", packet_length); tls_os_timer_stop(mqtt_demo_heartbeat_timer); mqtt_demo_close_socket(&mqtt_demo_mqtt_broker);    }    return 0;}int aliyun_cmd_excute(char *cmd){//解析Json字符串cJSON *str_json, *str_cmd;str_json = cJSON_Parse(cmd);if (!str_json){printf("[INFO]: JSON格式错误: %s\r\n", cJSON_GetErrorPtr());}else{str_cmd = cJSON_GetObjectItem(str_json, "cmd");if (str_cmd->type == cJSON_Number){//printf("[INFO]: cmd: %d\r\n", str_cmd->valueint);if (str_cmd->valueint == 1){temperature++;printf("[CMD_ALIYUN]: Temperature rise by aliyun, the current temp is %d\n",temperature);}else if (str_cmd->valueint == 2){temperature--;printf("[CMD_ALIYUN]: Temperature drops by aliyun, the current temp is %d\n",temperature);}}}return WM_SUCCESS;}

五.实验结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述