Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ESP8266
RT-Thread一般讨论
【RTTxIFX大赛】基于 Infineon 开发板的物联网demo
发布于 2023-07-15 20:30:07 浏览:336
订阅该版
[tocm] # 1 开发板介绍 官方活动链接为 [https://club.rt-thread.org/ask/article/d4aa78c6fb75dda7.html](https://club.rt-thread.org/ask/article/d4aa78c6fb75dda7.html "https://club.rt-thread.org/ask/article/d4aa78c6fb75dda7.html"), 该开发板的主控芯片型号为CY8C624A,是一个具有 Cortex-M4F 和 Cortex-M0+ 的 双核CPU,该主控芯片的功能框图如下所示: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/5fb2c868dd651c7eb0736f1507f088dd.png.webp) 开发板两侧留有供调试和外接其他模块的排针接口,如下图所示。从图中可以看出预留出了串口、IIC、SPI、ADC和PWM等常见的外设和总线接口。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/083ca6b33e26d9b3e197d7740728a7d7.png.webp) # 2 设计简介 ## 2.1 功能简介 本次设计基于 RT-Thread 物联网操作系统和 Infineon 开发板,使用 RT-Studio 作为开发工具,使用 ESP8266-WIFI 模块作为物联网的通讯介质,使用腾讯云服务器作为MQTT服务器,使用腾讯连连作为人机交互端,整体的功能框图如下所示: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/53152df95014e05bead37a58e86955b3.png) ## 2.2 ESP8266 简介 本次使用的 ESP8266 模块如下图所示,ESP8266 是一款强大的 WIFI 模块,支持 AT 指令开发,SDK 开发、Lua 开发、Arduino 开发、Lua 开发等开发方式,本次为了方便和主控板通讯采用 AT 指令的方式进行开发。 ![screenshot_1689425439893.png](https://oss-club.rt-thread.org/uploads/20230715/5ed59ff7a5989b8266b166d1d1d1b9ae.png.webp) # 3 开发步骤 本次开发使用 AT 组件和 MQTT 通讯协议进行设备和服务器之间的通讯,所以需要在配置中配置相应的组件。 ## 3.1 AT 组件 RT-Thread 官方支持了丰富的 AT 设备,本次所用的 ESP8266 模块的配置如下所示,需要开启相应的组件并配置路由的信息和AT设备的串口。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/bfe052ee8bcfb83216a672f4d8c2d1e7.png.webp) ## 3.2 MQTT 组件 RT-Thread 官方支持了多种 MQTT 组件,本次使用 PahoMQTT 组件进行开发,配置如下所示: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/7596dfa943133abdc518ee0e34c2df12.png) ## 3.3 CJson 组件 为了方便和腾讯云服务器进行通讯,在设计通讯格式时采用物模型的方式进行通讯,需要用到 Json 数据格式,在嵌入式设备中通常使用 CJSOn 库对 Json 数据进行解析,CJson 的配置如下: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/bbe72e39196b808b5638b7210c4aa27f.png) 配制好的组件如下图所示: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/bbe72e39196b808b5638b7210c4aa27f.png) ## 3.4 腾讯云服务器的配置 腾讯云物联网开发平台作为本项目的云平台进行数据的转发。MQTT 三元组信息以及服务器的IP参数的构建参考腾讯云文章 [MQTT.fx 快速接入指引](https://cloud.tencent.com/document/product/1081/46507 "MQTT.fx 快速接入指引") 和 [智能灯接入指引](https://cloud.tencent.com/document/product/1081/41155)。订阅和发布消息的数据帧格式参考腾讯云文章 [物模型协议](https://cloud.tencent.com/document/product/1081/34916)。创建好的设备和物模型页面如下图所示。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230715/de530bbe860be1e78596e6cdc11cbe34.png) # 4 关键代码编写 代码的仓库地址为 [https://gitee.com/crystal266/infineon_demo](https://gitee.com/crystal266/infineon_demo "https://gitee.com/crystal266/infineon_demo") MQTT任务的代码如下,主要写了登录,退出,发布消息的代码,订阅回调函数。 ```c #include
#include
#include
#include
#include "rtdevice.h" #define DBG_TAG "mqtt_task.c" #define DBG_LVL DBG_LOG #include
#include "paho_mqtt.h" #include "infineon_esp8266.h" #include "json_parse.h" #include "led.h" #include "cJSON.h" //#include "cJSON_util.h" /** * MQTT URI farmat: * domain mode * tcp://iot.eclipse.org:1883 * * ipv4 mode * tcp://192.168.10.1:1883 * ssl://192.168.10.1:1884 * * ipv6 mode * tcp://[fe80::20c:29ff:fe9a:a07e]:1883 * ssl://[fe80::20c:29ff:fe9a:a07e]:1884 */ #define MQTT_URI "tcp://T0FR66L94D.iotcloud.tencentdevices.com:1883" #define MQTT_CLIENT_ID "T0FR66L94Dinfineon_esp8266" #define MQTT_USERNAME "T0FR66L94Dinfineon_esp8266;12010126;AVBVT;1647450202" #define MQTT_PASSWORD "68dab4c81b227f841ef86b6223711975106a4a4cfe6556f77504b606430eeae0;hmacsha256" #define MQTT_SUBTOPIC "$thing/down/property/T0FR66L94D/infineon_esp8266" #define MQTT_PUBTOPIC "$thing/up/property/T0FR66L94D/infineon_esp8266" #define MQTT_WILLMSG "Goodbye!" /* define MQTT client context */ static MQTTClient client; static int is_started = 0; /** * @brief MQTT 订阅回调函数 * @param c 客户端标识 * @param msg_data 收到的数据 * @return 无 */ static void infineon_mqtt_sub_callback(MQTTClient *c, MessageData *msg_data) { *((char *) msg_data->message->payload + msg_data->message->payloadlen) = '\0'; LOG_D("mqtt sub callback: %.*s", //msg_data->topicName->lenstring.len, //msg_data->topicName->lenstring.data, msg_data->message->payloadlen, (char * )msg_data->message->payload); parse_msg(msg_data->message->payloadlen, (char *) msg_data->message->payload); // 解析收到的数据 } /** * @brief MQTT 默认的订阅回调函数 * @param c 客户端标识 * @param msg_data 收到的数据 * @return 无 */ static void infineon_mqtt_sub_default_callback(MQTTClient *c, MessageData *msg_data) { *((char *) msg_data->message->payload + msg_data->message->payloadlen) = '\0'; LOG_D("mqtt sub default callback: %.*s %.*s", msg_data->topicName->lenstring.len, msg_data->topicName->lenstring.data, msg_data->message->payloadlen, (char * )msg_data->message->payload); } /** * @brief MQTT 连接的回调函数 * @param c 客户端标识 * @return 无 */ static void infineon_mqtt_connect_callback(MQTTClient *c) { LOG_D("enter mqtt_connect_callback!"); } /** * @brief MQTT 上线的回调函数 * @param c 客户端标识 * @return 无 */ static void infineon_mqtt_online_callback(MQTTClient *c) { LOG_D("enter mqtt_online_callback!"); } /** * @brief MQTT 掉线的回调函数 * @param c 客户端标识 * @return 无 */ static void infineon_mqtt_offline_callback(MQTTClient *c) { LOG_D("enter mqtt_offline_callback!"); } /** * @brief MQTT 启动 * @param 无 * @return 成功返回0,失败返回-1 */ int infineon_mqtt_start(void) { /* init condata param by using MQTTPacket_connectData_initializer */ MQTTPacket_connectData condata = MQTTPacket_connectData_initializer; static char cid[20] = { 0 }; if (is_started) { LOG_E("mqtt client is already connected."); return -1; } /* config MQTT context param */ { client.isconnected = 0; client.uri = MQTT_URI; /* generate the random client ID */ rt_snprintf(cid, sizeof(cid), "rtthread%d", rt_tick_get()); /* config connect param */ memcpy(&client.condata, &condata, sizeof(condata)); client.condata.clientID.cstring = MQTT_CLIENT_ID; client.condata.keepAliveInterval = 30; client.condata.cleansession = 1; client.condata.username.cstring = MQTT_USERNAME; client.condata.password.cstring = MQTT_PASSWORD; /* config MQTT will param. */ client.condata.willFlag = 1; client.condata.will.qos = 1; client.condata.will.retained = 0; client.condata.will.topicName.cstring = MQTT_PUBTOPIC; client.condata.will.message.cstring = MQTT_WILLMSG; /* malloc buffer. */ client.buf_size = client.readbuf_size = 1024; client.buf = rt_calloc(1, client.buf_size); client.readbuf = rt_calloc(1, client.readbuf_size); if (!(client.buf && client.readbuf)) { LOG_E("no memory for MQTT client buffer!"); return -1; } /* set event callback function */ client.connect_callback = infineon_mqtt_connect_callback; client.online_callback = infineon_mqtt_online_callback; client.offline_callback = infineon_mqtt_offline_callback; /* set subscribe table and event callback */ client.messageHandlers[0].topicFilter = rt_strdup(MQTT_SUBTOPIC); client.messageHandlers[0].callback = infineon_mqtt_sub_callback; client.messageHandlers[0].qos = QOS1; /* set default subscribe event callback */ client.defaultMessageHandler = infineon_mqtt_sub_default_callback; } /* run mqtt client */ paho_mqtt_start(&client); is_started = 1; return 0; } /** * @brief MQTT 停止 * @param 无 * @return 成功返回0,失败返回-1 */ int infineon_mqtt_stop(void) { if (is_started == 1) { is_started = 0; return paho_mqtt_stop(&client); } } /** * @brief MQTT 发布消息 * @param send_buff 要发布的消息的内容 * @return 成功返回0,失败返回-1 */ int infineon_mqtt_publish(char *send_buff) { if (is_started == 0) { LOG_E("mqtt client is not connected."); return -1; } paho_mqtt_publish(&client, QOS1, MQTT_PUBTOPIC, send_buff); return 0; } /** * @brief MQTT 新订阅的回调函数 * @param client 客户端标识 * @param msg_data 收到的数据 * @return 无 */ void infineon_mqtt_new_sub_callback(MQTTClient *client, MessageData *msg_data) { *((char *) msg_data->message->payload + msg_data->message->payloadlen) = '\0'; LOG_D("mqtt new subscribe callback: %.*s %.*s", msg_data->topicName->lenstring.len, msg_data->topicName->lenstring.data, msg_data->message->payloadlen, (char * )msg_data->message->payload); } /** * @brief MQTT 订阅 * @param topic 要订阅的主题的名字 * @return 成功返回0,失败返回-1 */ int infineon_mqtt_subscribe(char *topic) { if (is_started == 0) { LOG_E("mqtt client is not connected."); return -1; } return paho_mqtt_subscribe(&client, QOS1, topic, infineon_mqtt_new_sub_callback); } /** * @brief MQTT 取消订阅 * @param topic 要取消订阅的主题的名字 * @return 成功返回0,失败返回-1 */ int infineon_mqtt_unsubscribe(char *topic) { if (is_started == 0) { LOG_E("mqtt client is not connected."); return -1; } return paho_mqtt_unsubscribe(&client, topic); } /* * json数据格式 * { * "method":"report", // report 表示设备属性上报 * "clientToken":"123", // 用于上下行消息配对标识 * "timestamp":1628646783, // 属性上报的时间,格式为 UNIX 系统时间戳,不填写该字段表示默认为当前系统时间。单位为毫秒 * "params":{ // JSON 结构内为设备上报的属性值 * "led":1, * "fan":1 * } * } */ /** * @brief MQTT 处理线程 * @param parameter 线程的入参 * @return 无 */ void mqtt_thread_entry(void *parameter) { while (1) { if (get_esp8266_link_status() == 0) // 等到 ESP8266 连接成功后才能连接腾讯云 { break; } else { rt_thread_mdelay(1000); } } infineon_mqtt_start(); // 启动mqtt,连接服务器 cJSON *root = NULL; cJSON *params = NULL; char *send_str = NULL; while (1) { rt_thread_mdelay(5000); // publish 间隔 root = cJSON_CreateObject(); /* 创建一个cJSON对象,要用 cJSON_Delete 释放内存 */ if (root != NULL) { cJSON_AddStringToObject(root, "method", "report"); cJSON_AddStringToObject(root, "clientToken", "123"); params = cJSON_CreateObject(); /* 创建子对象 */ if (params != NULL) { cJSON_AddItemToObject(root, "params", params); cJSON_AddNumberToObject(params, "led", get_led_status()); // 添加 LED 状态 cJSON_AddNumberToObject(params, "fan", get_fan_status()); // 风扇状态 send_str = cJSON_Print(root); if (send_str != NULL) { LOG_D("send msg: %s\n", send_str); infineon_mqtt_publish(send_str); } } } if (send_str != NULL) // 释放空间 { cJSON_free(send_str); send_str = NULL; } if (root != NULL) { cJSON_Delete(root); // 防止内存泄露,会把下面所有的子节点都释放 } } } /** * @brief 启动 MQTT 处理线程 * @param 无 * @return 无 */ int start_mqtt_thread(void) { /* 创建 MTQTT 处理线程 */ rt_thread_t thread = rt_thread_create("mqtt_thread", mqtt_thread_entry, RT_NULL, 2048, 10, 20); if (thread != RT_NULL) { rt_thread_startup(thread); // 创建成功则启动线程 } else { LOG_E("create mqtt thread failed"); return (-RT_ERROR); } return RT_EOK; } ``` # 5 其他 看板子外设资源原本更想做一个LVGL的项目移植这一套内容 [https://github.com/FASTSHIFT/X-TRACK](https://github.com/FASTSHIFT/X-TRACK "https://github.com/FASTSHIFT/X-TRACK") 或者做一个ADC示波器的,由于个人时间原因只做了一个简单的物联网demo,后续将补上 ADC + SPI 屏幕的单独测试和使用。 另外期待 7月22日 南京线下场的 RT-Thread 官方培训活动🤞 🤞 🤞
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
crystal266
嵌入式
文章
14
回答
547
被采纳
161
关注TA
发私信
相关文章
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部