LiteOS + PahoMQTT 连接华为云

举报
JeckXu666 发表于 2022/02/05 22:03:38 2022/02/05
【摘要】 使用小熊派连接华为云平台,实现数据的上传与下放,软件层使用 LiteOS 做系统支撑,移植 PahoMQTT 做通讯

LiteOS + PahoMQTT 连接华为云

一、前言

使用小熊派连接华为云平台,实现数据的上传与下放,软件层使用 LiteOS 做系统支撑,移植 PahoMQTT 做通讯

二、平台端配置

2.1 创建 IOTDA 云产品

进入华为云控制台,进入 IOTDA 中,创建一个产品:

20220129123750

2.2 定义产品模型

进入到产品,创建产品模型

20220129123858

2.3 创建属性和命令

创建模型的温度接受属性

20220129124207

创建模型的 LED 控制命令

20220129124404

2.4 添加设备

进入设备控制台,添加设备:

20220130132915

添加后会生成设备ID和设备密钥,这两个很重要,我们要保存好,后面要使用到

三、设备端配置

3.1 设备端配置

准备小熊派,建立工程,移植 LiteOS,这里我使用的是我之前移植的一个 MDK LiteOS 项目,同时移植了 LVGL,基于这个项目继续配置 esp8266

项目地址:链接

开启工程 LUART,配置 LUART 参数同时开启 DMA:

20220130112814

移植 Paho MQTT 工程代码:

Paho MQTT 开源地址:Github ,将 MQTTPacket 下面的 SRC 源码移植进去

20220130114934

关于代码移植我们只需要关注 transport.c 和 .h 文件,这两个文件是 MQTT 的物理层接口,这里我移植串口发送进去,使用 信号量+DMA 的方式进行开发,防止串口资源使用冲突,同时进一步提高串口速率,部分代码如下:

具体代码可以参考我后面完整的工程代码:

20220130115318

这里是 MQTT 的底层代码,除此之外我们建立一个 ESP8266 文件用于发送数据到 ESP,配置 WIFI 模块,主要就是设置 WIFI 模块工作模式,连接 WIFI 以及连接华为云服务平台,参考代码如下,具体代码见实际工程:

20220130115640

连接 WIFI 主要就是 WIFI 的账号和密码,连接服务平台的话则需要服务平台的域名和端口,域名获取端口在控制台的 IOTDA 接口下面

20220130120010

接口如下,这里使用明文 MQTT 接口:

20220130120023

放到代码如下位置:

20220130120142

3.2 连接华为云

下面创建 huawei.c 和 .h 文件用于连接华为云进行数据上报和下发:

20220130120813

根据 ID 和用户名以及密码调用 MQTT 接口连接华为云,这三个数据通过生成器生成,生成器下载地址:下载地址

20220130133029

将ID、用户名、密钥都填写到代码里面

20220130135430

然后调用 MQTT 接口连接

uint8_t huawei_connect()
{
		uint32_t len;

		printf("进入连接云服务器函数\r\n");
		memset(buf,0,buflen);
		MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
		data.MQTTVersion = 3;
		data.clientID.cstring = ClientID;
		data.keepAliveInterval = 120;
		data.cleansession = 1;	
		data.username.cstring = Username;	
		data.password.cstring = Password;
		len = MQTTSerialize_connect(buf, buflen, &data); 
		transport_sendPacketBuffer(3,buf, len);				//发送连接请求
		
		unsigned char sessionPresent, connack_rc;
		do
		{
				while(MQTTPacket_read(buf, buflen, transport_getdata) != CONNACK)
				{
						osDelay(10);
				}
		}
		while(MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0);
		
		if(connack_rc != 0)
		{
			printf("connack_rc:%uc\r\n",connack_rc);
		}else			
			printf("Connect Success!\r\n");		
		return 0;
}

3.3 上传数据

使用 Paho MQTT 到华为云的上传数据分为两步,第一步订阅主题,主题格式如下

#define POST_TOPIC "$oc/devices/devices_id/sys/properties/report"

devices_id 填写设备 ID,然后定义一个数据上传格式

#define PAY_LOAD "{\"services\":[{\"service_id\":\"Home\",\"properties\":{\"Temp\":\"%d\"},\"eventTime\":\"NULL\"}]}"

service_id 是产品添加时设置 Home

Temp 是产品的属性,然后调用宏接口填写数据:

void test_post(void)
{
	int len = 0;
	int rc = 0;
	unsigned char topic[]= POST_TOPIC;
	unsigned char payload[100]={0};
	
	sprintf((char*)payload,PAY_LOAD,19);
	
	memset(buf,0,buflen);
	MQTTString topicString = MQTTString_initializer;
	topicString.cstring = (char *)topic;
	
	len=MQTTSerialize_publish(buf,buflen,0,0,0,0,topicString,payload,strlen((char *)payload));
	
	rc = transport_sendPacketBuffer(3, buf, len);
	if(!rc)
		printf("Send OK!\r\n");
	else
		printf("Send WRONG!\r\n");
}

编写完成后,我们在 mian 文件中创建相关任务,调用代码:

20220130213959

编译下载程序,在华为云的实验平台上进入设备调试模式,观察数据上传情况,可以看到数据正常上传:

20220131114047

3.4 接受命令

接受命令主要分为三步

第一步先订阅命令接受主题并读返回数据检验有没有订阅成功

	topicString.cstring = GET_TOPIC;
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);

	rc = transport_sendPacketBuffer(3, buf, len);
	if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) 	/* wait for suback */
	{
		unsigned short submsgid;
		int subcount;
		int granted_qos;

		rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
		if (granted_qos != 0)
		{
			printf("granted qos != 0, %d\n", granted_qos);
		}
	}

订阅主题如下:

#define GET_TOPIC "$oc/devices/61f4c4b0de9933029be530e7_ESP8266/sys/commands/#"

具体格式可以查看华为云手册

订阅后就是一个死循环来循环读取订阅主题发送的命令,然后解析命令,将接受的命令打印出来,这里是 JSON 格式的返回数据,想进一步处理的话可以使用 CJSON

		if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH)
		{
			unsigned char dup;
			int qos;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in;
			unsigned char* payload_in;
			int rc;
			MQTTString receivedTopic;

			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
					&payload_in, &payloadlen_in, buf, buflen);
			
			id = &receivedTopic.lenstring.data[strlen("$oc/devices/61f4c4b0de9933029be530e7_ESP8266/sys/commands/request_id=")];
			
			memcpy(&ropicString.cstring[strlen("$oc/devices/61f4c4b0de9933029be530e7_ESP8266/sys/commands/response/request_id=")],
						id,
						strlen("0b2e0999-55a1-43f9-a432-d46a8d58ae7e")
						);

			printf("message arrived %.*s\r\n", payloadlen_in, payload_in);

		}

接受到数据后,要返回命令下发成功信息,先将接受的 ID 复制到新主题上,这个操作就是上个代码的 ropicString 字符串操作部分,然后我们根据主题发送成功信息

		memset(buf,0,buflen);
		printf("publishing reading\r\n");
		
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, ropicString, (unsigned char*)payload, payloadlen);
		rc = transport_sendPacketBuffer(3, buf, len);

代码编写成功后在任务中调用该函数:

20220205103748

编译下载代码,我们在云端打开设备调试,给设备发送命令:

可以看到命令发送成功,接受返回的命令也成功了

20220205103936

小熊派的串口也打印出接受到的数据:

20220205103927

到此使用 LiteOS 移植 PahoMQTT 对华为云进行数据收发基本完成

四、代码链接

GitHub 工程地址:链接

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。