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

—————————

5.12更新:
需要注意调用cJSON_Print函数将JSON体转化为字符串时,会开辟内存,转化后使用完毕后需要调用cJSON_free函数将内存释放掉,否则会导致内存泄漏。一旦内存泄漏会导致系统宕机。

—————————

一.项目概述

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

二.项目前的准备

因为使用阿里云物联网平台,因此需要提前创建好一个设备,这个网上的示例和阿里云自己的文档已经十分完整,因此不多赘述,可以自行查阅。创建完设备的MQTT链接参数是用来进行链接的关键,如下图所示。
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第1张图片

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

概述:SDK中提供的MQTT链接示例基本是可用的,但是连接阿里云时需要做如下修改。
【1】修改MQTT链接参数,同时要添加Username以及password的宏定义,订阅和发布的topic根据自己的设备来添加
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第2张图片

【2】修改MQTT的client,username等的数组长度,SDK中的数据范围太小,而阿里云的链接参数由于经过加密因此比较长无法满足要求,需要对以下几个位置进行修改。
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第3张图片

【3】修改原MQTTdemo里面的mqtt_demo_init函数,原函数没有账户密码登录的步骤,但是提供了相应函数,因此需要进行补充。
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第4张图片

四.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);
	cJSON_free(temperature_msg );
	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);
			}
		}
	}
	cJSON_delet(str_json );
	return WM_SUCCESS;
}

五.实验结果

W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第5张图片
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第6张图片
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第7张图片
W801通过一机一密的方式连接阿里云物联网平台并实现反向控制_第8张图片

你可能感兴趣的:(W801,c++)