一、MQTT协议简介
MQTT(消息队列遥测传输)是一个基于客户端-服务器的消息发布/订阅传输协议,是ISO标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。MQTT工作在TCP/IP协议栈上,是为硬件性能低下的远程设备以及网络状况不理想的情况下而设计的发布/订阅型消息协议。由于MQTT协议的轻量、简便、开放的特点使它适用范围非常广泛。在很多情况下,包括受限的环境中使用,广泛应用于物联网(IoT)。MQTT协议在卫星链路通信传感器、医疗设备、智能家居、及一些小型化设备中已广泛使用。
阿里云为国内主流的云平台,提供免费试用的物联网平台,之前的文章已经详细介绍了使用小凌派RK2206开发板实现基于OpenHarmony的阿里云IoT服务,并在阿里云上成功上线,本文将在此基础上,继续讲解小凌派RK2206开发板与阿里云平台数据交互的实现。小凌派RK2206开发板采用瑞芯微高性能、高性价比的RK2206芯片。RK2206芯片是一款低功耗、高集成的MCU无线局域网处理器,它可以应用于不同的应用领域,如物联网、可穿戴设备、家庭自动化、云连接等。小凌派RK2206开发板内置WIFI模块,外部接口丰富,使用一个小凌派RK2206开发板就能够轻松实现MQTT物联网多种应用。
二、硬件电路设计
如图1所示,为小凌派RK2206开发板支持的外部接口,本文使用小凌派RK2206开发板内置的WIFI和MQTT服务器通信。
图1 小凌派RK2206开发板
三、软件设计
主程序设计。
在iot_aliyun_example函数中,通过LOS_TaskCreate函数创建iot_aliyun_thread和message_thread线程,并设置线程优先级、线程堆栈大小等参数。
void iot_aliyun_example()
{
unsigned int ret = LOS_OK;
unsigned int thread_id1;
unsigned int thread_id2;
TSK_INIT_PARAM_S task1 = {0};
TSK_INIT_PARAM_S task2 = {0};
ret = LOS_QueueCreate("queue", MSG_QUEUE_LENGTH, &m_msg_queue, 0, BUFFER_LEN);
if (ret != LOS_OK)
{
printf("Falied to create Message Queue ret:0x%x\n", ret);
return;
}
task1.pfnTaskEntry = (TSK_ENTRY_FUNC)iot_aliyun_thread;
task1.uwStackSize = 10240;
task1.pcName = "iot_aliyun_thread";
task1.usTaskPrio = 24;
ret = LOS_TaskCreate(&thread_id1, &task1);
if (ret != LOS_OK)
{
printf("Falied to create iot_aliyun_thread ret:0x%x\n", ret);
return;
}
task2.pfnTaskEntry = (TSK_ENTRY_FUNC)message_thread;
task2.uwStackSize = 2048;
task2.pcName = "message_thread";
task2.usTaskPrio = 25;
ret = LOS_TaskCreate(&thread_id2, &task2);
if (ret != LOS_OK)
{
printf("Falied to create message_thread ret:0x%x\n", ret);
return;
}
}
阿里云服务程序设计
iot_aliyun_thread函数中,开发板先连接WIFI,通过WIFI和阿里云IoT平台通信;WIFI连接成功后,初始化网络,初始化MQTT客户端;初始化完成后,成功连接阿里云IoT平台。程序进入主循环,阻塞等待消息队列的信息,当有信息到来时,取出数据上报到阿里云平台上。
int iot_aliyun_thread()
{
aliyun_msg_t *app_msg = NULL;
unsigned int addr;
int ret;
/*WIFI连接*/
SetWifiModeOn();
device_info_init(CLIENT_ID, USERNAME, PASSWORD);
ret = oc_mqtt_init();
if (ret != LOS_OK)
{
printf("oc_mqtt_init fail ret:%d\n", ret);
}
while (1)
{
ret = LOS_QueueRead(m_msg_queue, (void *)&addr, BUFFER_LEN, LOS_WAIT_FOREVER);
if (ret == LOS_OK)
{
app_msg = addr;
switch (app_msg->msg_type)
{
case en_msg_report:
aliyun_deal_report_msg(&app_msg->report);
break;
default:
break;
}
free(app_msg);
app_msg = NULL;
}
else
{
LOS_Msleep(100);
}
}
}
数据处理程序设计
message_thread函数中,每5秒向消息队列中写入数据,并且数据不断累加处理。
void message_thread()
{
aliyun_msg_t *app_msg = NULL;
int data = 0;
while (1)
{
app_msg = malloc(sizeof(aliyun_msg_t));
if (app_msg != NULL)
{
app_msg->msg_type = en_msg_report;
app_msg->report.data = data++;
if (LOS_QueueWrite(m_msg_queue, (void *)app_msg, sizeof(aliyun_msg_t), LOS_WAIT_FOREVER) != LOS_OK)
{
printf("%s LOS_QueueWrite fail\n", __func__);
free(app_msg);
}
}
LOS_Msleep(5000);
}
}
四、编译测试
之前的文章已经详细介绍了如何登录阿里云、创建产品和添加设备,本文就不在赘述。
添加功能
点击进入公共实例,点击侧边栏的产品页面,点击添加自定义功能,如图2所示。
图2 添加自定义功能
输入自定义功能名称,点击确定,如图3所示。
图3 添加自定义功能详情
成功添加自定义功能后,可以查看到添加的自定义功能信息,点击发布上线,如图4所示。
图4 发布自定义功能
WIFI连接
修改代码中的SSID和PASSWORD为使用WIFI的SSID和密匙,用于连接网络,设备通过WIFI访问阿里云IoT平台。代码如下所示:
#define SSID "lzdz"
#define PASSWORD "12345678"
运行结果
例程代码编译烧写到开发板后,按下开发板的RESET按键,通过串口软件查看日志,串口打印MQTT初始化、连接等日志。
NetworkConnect...
MQTTClientInit...
MQTTConnect...
MQTTSubscribe...
此时登录阿里云IoT平台,点击进入设备详情页面,可以看到设备的当前状态为在线。如图5所示。
图5 设备上线阿里云IoT平台
此时,侧边栏选择设备,点击进入设备详情,选择物模型数据页面,就可以看到小凌派RK2206开发板上报的数据,如图6所示。
图6 阿里云数据显示