物联网云平台数据库选型与搭建全指南(NRF52840, CH585M,ESP32-S3的硬件资源要求选型对比、方案设计、搭建步骤)

物联网云平台数据库选型与搭建全指南(NRF52840, CH585M,ESP32-S3的硬件资源要求选型对比、方案设计、搭建步骤)

物联网云平台数据库选型与搭建全指南(适配LoRaWAN场景)

一、物联网云平台主流数据库对比(含流行度+LoRaWAN适配性)

1. 核心数据库类型对比表

数据库类型 代表产品 流行度 LoRaWAN适配场景 优势 劣势 部署成本(中小规模)
时序数据库 InfluxDB(开源)、TDengine(国产)、TimescaleDB ★★★★★ 核心:传感器时序数据(温湿度/电量/信号强度)高频写入、时间范围查询 1. 高并发写入(10万+ TPS);2. 时间维度查询极快;3. 按时间自动分片压缩 1. 非时序查询能力弱;2. 事务支持差 低(单机部署<500元/月)
关系型数据库 PostgreSQL、MySQL/MariaDB ★★★★☆ 辅助:设备配置、用户信息、网关参数、LoRaWAN网络配置(DevEUI/AppEUI) 1. 事务强一致性;2. SQL生态成熟;3. 复杂关联查询;4. ChirpStack默认配置库 1. 时序数据写入性能差;2. 海量数据存储成本高 低(云托管RDS 300-800元/月)
文档型NoSQL MongoDB ★★★★☆ 扩展:非结构化设备属性、JSON格式上报数据、多协议设备兼容 1. 数据模型灵活(无需预定义表结构);2. 支持嵌套文档;3. 云托管成熟 1. 时序查询效率低;2. 写入性能弱于时序库 中(云托管MongoDB 500-1500元/月)
键值型NoSQL Redis ★★★★★ 缓存:LoRaWAN网关实时状态、设备在线状态、高频查询数据 1. 毫秒级读写;2. 支持过期策略;3. 分布式部署 1. 持久化成本高;2. 不适合海量历史数据 低(单机Redis 200-500元/月)
云原生时序库 AWS Timestream、阿里云TSDB ★★★☆☆ 大规模LoRaWAN网络(10万+设备)、跨地域部署 1. 弹性扩缩容;2. 免运维;3. 与云服务无缝集成 1. 成本高;2. 厂商锁定;3. 小规模部署不划算 高(按用量计费 1000-5000元/月)

2. 核心结论

  • 物联网云平台最流行:时序数据库(InfluxDB/TDengine)+ 关系型数据库(PostgreSQL)+ 缓存(Redis)的组合(90%以上物联网平台采用);

  • LoRaWAN专属选型

    • 中小规模(<1万设备):InfluxDB(时序)+ PostgreSQL(配置)+ Redis(缓存);

    • 大规模(1万+设备):TDengine(分布式时序)+ PostgreSQL(配置)+ Redis Cluster(缓存);

    • 云托管优先:AWS Timestream/阿里云TSDB + 云RDS PostgreSQL。

二、自建物联网云平台数据库选型指导(分场景)

1. 选型核心原则

决策维度 优先级 选型依据
数据类型 最高 90% LoRaWAN数据为时序数据→优先时序库;10%为结构化配置数据→关系库
设备规模 <1万设备:单机时序库;1万-10万:分布式时序库;>10万:云原生时序库
技术栈匹配 熟悉SQL→TimescaleDB;熟悉国产技术→TDengine;轻量化部署→InfluxDB
运维成本 小团队→免运维云托管;有运维团队→开源单机/分布式部署
成本预算 <1000元/月→开源单机;>1000元/月→云托管/分布式开源

2. 分场景选型方案

场景 数据库组合 部署方式 适用场景
入门测试(<100设备) InfluxDB(单机)+ SQLite(替代PostgreSQL) 本地服务器/虚拟机 实验室验证、LoRaWAN原型开发
中小规模商用(<1万设备) InfluxDB + PostgreSQL + Redis(单机) 云服务器(4核8G) 园区/楼宇LoRaWAN物联网
大规模商用(1万-10万设备) TDengine(集群)+ PostgreSQL(主从)+ Redis Cluster 云服务器集群(8核16G×3) 城市级LoRaWAN网络
云原生部署 AWS Timestream + RDS PostgreSQL + ElastiCache Redis 公有云托管 跨地域LoRaWAN部署、免运维

三、自建物联网云平台数据库搭建详细步骤(中小规模:InfluxDB+PostgreSQL+Redis)

前置准备

  • 硬件/云服务器:Linux(Ubuntu 22.04)、4核8G、500G SSD(时序数据占比高);

  • 软件:Docker + Docker Compose(推荐容器化部署,简化运维);

  • LoRaWAN网络服务器:ChirpStack(开源,默认适配PostgreSQL+InfluxDB)。

步骤1:环境初始化(Ubuntu 22.04)

Bash 复制代码

步骤2:容器化部署PostgreSQL(LoRaWAN配置库)

1. 创建配置文件
Bash 复制代码
2. 启动PostgreSQL
Bash 复制代码

步骤3:容器化部署InfluxDB(LoRaWAN时序库)

1. 创建配置文件
Bash 复制代码
2. 启动InfluxDB
Bash 复制代码

步骤4:容器化部署Redis(缓存)

1. 创建配置文件
Bash 复制代码
2. 启动Redis
Bash 复制代码

步骤5:对接LoRaWAN网络服务器(ChirpStack)

1. 部署ChirpStack
Bash 复制代码
2. 验证数据流转
  1. 访问ChirpStack Web界面:http://服务器IP:8080(默认账号:admin,密码:admin);

  2. 添加LoRaWAN设备(DevEUI/AppEUI配置);

  3. 设备上报数据后,验证数据存储:

    Bash 复制代码

步骤6:数据库基础运维(必做)

1. 数据备份
Bash 复制代码
2. 时序数据清理(避免磁盘满)
Bash 复制代码

四、核心例程(数据读写操作)

1. InfluxDB时序数据读写(Python例程)

Python 复制代码

2. PostgreSQL设备配置读写(Python例程)

Python 复制代码

五、选型与搭建关键点总结

1. 选型核心

  1. LoRaWAN场景优先时序数据库(InfluxDB/TDengine)存储传感器数据,关系库存储配置数据;

  2. 中小规模优先容器化开源部署 ,大规模优先分布式时序库+云托管

  3. 必须搭配Redis缓存提升设备状态查询效率。

2. 搭建关键

  1. 容器化部署简化运维,优先采用Docker Compose;

  2. 时序数据库需设置数据保留策略,避免磁盘占满;

  3. 定期备份配置数据(PostgreSQL)和时序数据(InfluxDB);

  4. 对接LoRaWAN网络服务器(如ChirpStack)时,确保数据库连接参数一致。

3. 进阶优化

  1. 设备规模>1万:将InfluxDB替换为TDengine集群,PostgreSQL配置主从复制;

  2. 需可视化:部署Grafana对接InfluxDB/TDengine,实现LoRaWAN数据大屏;

  3. 云原生改造:迁移到K8s部署,配合Prometheus监控数据库状态。

六、one_channel_hub硬件搭建物料清单与核心调试步骤速查表

6.1 硬件搭建物料清单(面包板原型验证)

物料类别 具体物料 规格参数 数量 用途说明
核心芯片 CH585M芯片 QFN28封装,RISC-V架构 1片 网关主控,负责协议解析、数据转发
核心芯片 SX1278 LoRa模块 支持470/868/915MHz,UART接口 1个 LoRa信号调制解调,实现无线通信
供电模块 AMS1117-3.3V 线性稳压芯片,输入5V/输出3.3V 1片 为CH585M、SX1278提供稳定3.3V供电
供电模块 CH340G芯片 USB转串口,支持5V供电 1片 USB转UART,用于程序下载和调试
供电模块 TP4056芯片 锂电池充电管理 1片 适配锂电池供电场景,实现充电管理
被动器件 晶振 12MHz(主时钟)、32.768KHz(RTC) 各1个 为CH585M提供时钟信号,保证系统运行
被动器件 电容 0.1μF(陶瓷电容)、10pF(陶瓷电容) 若干 去耦、滤波,稳定电源和时钟信号
被动器件 电阻 1KΩ、10KΩ(碳膜电阻) 若干 LED限流、GPIO上拉/下拉
辅助器件 LED灯 直插式,任意颜色 2个 电源状态指示、LoRa通信状态指示
辅助器件 按键 轻触按键,4脚 1个 系统唤醒、复位控制
辅助器件 锂电池 3.7V,容量≥1000mAh 1块 备用供电,适配移动场景
辅助器件 USB-TYPE-C接口 母座,支持数据+供电 1个 USB供电和数据传输接口
连接器件 面包板 半尺寸 1个 搭建临时电路,方便调试和修改
连接器件 杜邦线 公对公、公对母,40P套装 1套 面包板与器件、器件之间的电路连接
调试工具 WCH-Link调试器 支持CH58x系列芯片 1个 CH585M程序下载和在线调试
调试工具 万用表 支持电压、通断测量 1台 检测电路通断、电压是否正常

6.2 核心调试步骤速查表

调试阶段 核心步骤 操作要点 验证标准 常见问题与解决办法
1. 硬件供电调试 1. 搭建供电电路;2. 接入电源;3. 测量关键电压 1. 注意电源正负极,避免接反;2. 先接USB供电测试,再测试锂电池供电;3. 测量AMS1117输出端电压 AMS1117输出3.3V±0.1V;电源灯(PB2)正常亮起 问题:电源灯不亮
解决:1. 检查USB线是否接触良好;2. 用万用表测量供电电路通断;3. 更换AMS1117芯片
2. CH585M最小系统调试 1. 完成最小系统搭建;2. 连接WCH-Link调试器;3. 下载测试程序 1. 确保晶振、复位电路连接正确;2. WCH-Link接CH585M的SWDIO、SWCLK引脚;3. 测试程序选择简单GPIO翻转程序 程序下载成功;测试LED可按设定频率闪烁 问题:程序下载失败
解决:1. 检查WCH-Link驱动是否安装;2. 确认SWD引脚连接正确;3. 检查CH585M复位电路是否正常
3. UART通信调试 1. 搭建UART0(调试)电路;2. 初始化UART0;3. 发送调试信息 1. CH340G TX接CH585M PA0,CH340G RX接CH585M PA1;2. 配置UART0波特率115200;3. 打开串口助手接收数据 串口助手能正常接收"sys init ok!"调试信息 问题:无调试信息输出
解决:1. 检查CH340G驱动是否安装;2. 核对UART引脚连接;3. 确认波特率与串口助手一致
4. LoRa模块调试 1. 搭建LoRa模块对接电路;2. 复位SX1278;3. 发送AT指令配置;4. 测试数据收发 1. SX1278 TX接CH585M PA8,SX1278 RX接CH585M PA9;2. 先执行LoRa复位操作;3. AT指令波特率9600;4. 用另一LoRa模块作为终端测试 1. 配置后串口助手接收"lora config ok!";2. 能正常接收终端发送的LoRa数据;3. 发送数据时LoRa状态灯(PB3)闪烁 问题:LoRa配置失败/无法收发数据
解决:1. 检查LoRa模块供电电压;2. 核对UART1波特率;3. 检查SX1278 RST引脚连接;4. 调整LoRa频段与终端一致
5. 低功耗功能调试 1. 配置RTC定时唤醒;2. 编写休眠函数;3. 测试唤醒功能 1. RTC配置10秒唤醒;2. 无数据时进入休眠模式;3. 分别测试定时唤醒和按键唤醒 1. 休眠时电流≤10μA;2. 10秒后能自动唤醒;3. 按下唤醒按键能立即唤醒 问题:无法唤醒/唤醒不及时
解决:1. 检查RTC晶振连接;2. 核对RTC中断配置;3. 检查按键中断引脚配置
6. 整体功能联调 1. 连接LoRa终端设备;2. 启动网关和终端;3. 验证数据流转 1. 终端配置与网关一致(频段、SF、带宽);2. 终端发送传感器数据;3. 查看上位机接收数据 1. 网关能接收终端数据并上传至上位机;2. 上位机下发数据能被终端接收;3. 整个链路无丢包(测试100条数据丢包率<3%) 问题:数据丢包严重
解决:1. 调整LoRa模块发射功率(提升至17dBm);2. 减小扩频因子;3. 确保网关与终端之间无遮挡

6.3 关键参数速记

  • CH585M系统时钟:48MHz;RTC时钟:32.768KHz

  • UART0(调试):波特率115200,引脚PA0(RX)、PA1(TX)

  • UART1(LoRa对接):波特率9600,引脚PA8(RX)、PA9(TX)

  • LoRa模块默认配置:470MHz频段、SF7扩频因子、125KHz带宽、17dBm发射功率

  • 休眠唤醒配置:RTC定时10秒唤醒,按键下降沿中断唤醒

七、one_channel_hub LoRa单通道网关MCU选型补充(新增ESP32-S3)

7.1 新增ESP32-S3后的核心参数对比表

对比维度 NRF52840 CH585M ESP32-S3 one_channel_hub适配性评分(★/5)
核心架构 ARM Cortex-M4F RISC-V RV32IMAC Xtensa LX7(双核) NRF52840:★4.5;CH585M:★4;ESP32-S3:★4.5
主频 64MHz 48MHz 240MHz(双核) ESP32-S3:★5;NRF52840:★4.5;CH585M:★4(均满足需求)
Flash/RAM 1MB Flash + 256KB RAM 64KB Flash + 16KB RAM 8MB Flash + 512KB RAM(最小配置) ESP32-S3:★5;NRF52840:★5;CH585M:★3.5
通信接口 4路UART、3路SPI、2路I2C、BLE 5.0、NFC 2路UART、1路SPI、1路I2C、BLE 5.0 4路UART、4路SPI、2路I2C、BLE 5.0、Wi-Fi 6、USB OTG ESP32-S3:★5;NRF52840:★5;CH585M:★4
低功耗性能 休眠电流≈2.7μA(仅RTC) 休眠电流≈1.2μA(仅RTC) 休眠电流≈5μA(仅RTC) CH585M:★5;NRF52840:★4.5;ESP32-S3:★4
封装与成本 QFN48(7x7mm),单价≈18元 QFN28(4x4mm),单价≈8元 QFN56(7x7mm),单价≈15元 CH585M:★5;ESP32-S3:★4;NRF52840:★3.5
开发支持 Nordic SDK、Zephyr OS,LoRa驱动完善 WCH SDK、RT-Thread,国产支持及时 ESP-IDF、Arduino,Wi-Fi/BLE生态成熟,LoRa驱动丰富 ESP32-S3:★5;NRF52840:★4.5;CH585M:★4
扩展能力 支持多协议融合(LoRa+BLE) 基础单通道需求,扩展受限 支持LoRa+Wi-Fi+BLE三协议融合、本地AI处理、大屏扩展 ESP32-S3:★5;NRF52840:★4.5;CH585M:★3
供电电压 1.7V-3.6V 2.0V-3.6V 2.7V-3.6V 三者均★5(适配锂电池供电)

7.2 补充ESP32-S3后的选型结论

结合one_channel_hub单通道网关的核心需求(轻量化、成本、功能适配)及三款MCU特性,新增细分场景选型:

  • 极致成本/低功耗场景:优先CH585M

    理由:单价最低(8元),休眠电流最小(1.2μA),封装小巧,满足纯单通道数据收发核心需求,无功能冗余,适合批量低成本部署场景(如简易数据采集网关)。

  • 扩展功能场景(无Wi-Fi需求):优选NRF52840

    理由:Flash/RAM充足(1MB+256KB),支持LoRa+BLE融合通信,开发社区成熟,无Wi-Fi模块的冗余功耗,适合需要本地数据存储、多外设扩展的场景(如对接多个传感器的网关)。

  • 多协议融合/云对接场景:优选ESP32-S3

    理由:自带Wi-Fi 6+BLE 5.0,可直接实现LoRa数据通过Wi-Fi上传至云平台,无需额外添加Wi-Fi模块;双核240MHz算力充足,支持后续功能迭代(如本地数据解析、边缘计算),适合需要直接对接物联网云平台的场景。

后续补充基于ESP32-S3的方案设计、搭建步骤及例程,与原有CH585M、NRF52840方案形成互补。

7.3 基于三款MCU的one_channel_hub方案设计(补充NRF52840)

7.3.1 核心功能定位(分MCU)
  • NRF52840方案:实现LoRa单通道数据收发+BLE辅助调试/本地数据交互,支持多外设扩展(如传感器、SD卡本地存储),适配无Wi-Fi环境、需本地数据处理的单通道网关场景。

  • CH585M方案:实现LoRa单通道数据收发核心功能,极简设计,适配低成本、低功耗、无扩展需求的批量部署场景。

  • ESP32-S3方案:实现LoRa单通道数据收发+Wi-Fi云对接+BLE调试,支持多协议融合,适配需直接上云、功能迭代的场景。

实现LoRa单通道数据收发,通过Wi-Fi直接对接物联网云平台(如阿里云、腾讯云),支持BLE调试、本地数据缓存、设备状态监控及低功耗模式,适配需要直接上云的单通道网关场景。

7.3.2 硬件方案设计(核心原理图框架-分MCU)
7.3.2.1 NRF52840硬件方案
  1. 核心供电模块
  • 输入:5V USB供电 或 3.7V锂电池供电;
  • 稳压:采用AMS1117-3.3V稳压芯片,输出3.3V给NRF52840、LoRa模块、BLE天线供电;
  • 电源管理:TP4056充电管理芯片(适配锂电池),电源开关+电源指示灯。
  1. NRF52840核心电路
  • 最小系统:外接64MHz晶振(主时钟)、32.768KHz晶振(RTC时钟);
  • 复位电路:采用RC复位电路,搭配复位按键;
  • 下载接口:SWD调试接口(SWDIO、SWCLK引脚),搭配WCH-Link调试器。
  1. LoRa模块接口电路(对接SX1278)
  • 通信接口:NRF52840的UART1(GPIO24-TX、GPIO25-RX)对接SX1278的UART接口;
  • 控制接口:GPIO26作为SX1278复位引脚,GPIO27作为SX1278状态指示引脚;
  • 电源:3.3V供电,添加0.1μF去耦电容。
  1. BLE与调试接口
  • BLE接口:NRF52840自带BLE 5.0模块,外接2.4G BLE天线;
  • UART调试:UART0(GPIO6-TX、GPIO8-RX)对接CH340G USB转串口芯片,用于程序下载和调试。
  1. 扩展功能电路
  • 状态指示:2个LED灯(GPIO13-电源灯,GPIO14-LoRa通信状态灯);
  • 按键:2个功能按键(GPIO15-复位按键,GPIO16-配置按键);
  • 扩展接口:SPI接口(GPIO19-SCK、GPIO20-MOSI、GPIO21-MISO),可对接SD卡模块实现本地数据存储。
7.3.2.2 CH585M硬件方案(沿用原有)
  1. 核心供电模块
  • 输入:5V USB供电 或 3.7V锂电池供电;
  • 稳压:采用AMS1117-3.3V稳压芯片,输出3.3V给CH585M、SX1278模块供电;
  • 电源管理:TP4056充电管理芯片(适配锂电池),电源开关+电源指示灯。
  1. CH585M核心电路
  • 最小系统:外接12MHz晶振(主时钟)、32.768KHz晶振(RTC时钟);
  • 复位电路:采用RC复位电路,搭配复位按键;
  • 下载接口:SWD调试接口,搭配WCH-Link调试器。
  1. LoRa模块接口电路(对接SX1278)
  • 通信接口:CH585M的UART1(PA8-TX、PA9-RX)对接SX1278的UART接口;
  • 控制接口:GPIO4作为SX1278复位引脚;
  • 电源:3.3V供电,添加0.1μF去耦电容。
  1. 调试接口
  • UART调试:UART0(PA0-RX、PA1-TX)对接CH340G USB转串口芯片,用于程序调试。
  1. 辅助功能电路
  • 状态指示:2个LED灯(PB2-电源灯,PB3-LoRa通信状态灯);
  • 按键:1个复位按键。
7.3.2.3 ESP32-S3硬件方案(沿用原有)
  1. 核心供电模块
  • 输入:5V USB供电 或 3.7V锂电池供电;
  • 稳压:采用AMS1117-3.3V稳压芯片,输出3.3V给ESP32-S3、LoRa模块供电;
  • 电源管理:TP4056充电管理芯片(适配锂电池),电源开关+电源指示灯。
  1. ESP32-S3核心电路
  • 最小系统:外接40MHz晶振(主时钟)、32.768KHz晶振(RTC时钟);
  • 复位电路:采用RC复位电路,搭配复位按键;
  • 下载接口:USB Type-C接口(直接用于程序下载和调试,无需额外USB转串口芯片)。
  1. LoRa模块接口电路(对接SX1278)
  • 通信接口:ESP32-S3的UART2(GPIO17-TX、GPIO16-RX)对接SX1278的UART接口;
  • 控制接口:GPIO4作为SX1278复位引脚,GPIO5作为SX1278状态指示引脚;
  • 电源:3.3V供电,添加0.1μF去耦电容。
  1. 云对接与调试接口
  • Wi-Fi接口:ESP32-S3自带Wi-Fi模块,无需额外电路,通过天线座外接2.4G Wi-Fi天线;
  • BLE调试:利用ESP32-S3自带BLE功能,支持手机APP调试;
  • 备用UART调试:UART0(GPIO1-TX、GPIO3-RX),可外接CH340G用于串口调试。
  1. 辅助功能电路
  • 状态指示:2个LED灯(GPIO2-电源灯,GPIO15-LoRa通信状态灯);
  • 按键:2个功能按键(GPIO0-复位按键,GPIO14-配置按键,用于Wi-Fi配网)。
  1. 核心供电模块
  • 输入:5V USB供电 或 3.7V锂电池供电;
  • 稳压:采用AMS1117-3.3V稳压芯片,输出3.3V给ESP32-S3、LoRa模块供电;
  • 电源管理:TP4056充电管理芯片(适配锂电池),电源开关+电源指示灯。
  1. ESP32-S3核心电路
  • 最小系统:外接40MHz晶振(主时钟)、32.768KHz晶振(RTC时钟);
  • 复位电路:采用RC复位电路,搭配复位按键;
  • 下载接口:USB Type-C接口(直接用于程序下载和调试,无需额外USB转串口芯片)。
  1. LoRa模块接口电路(对接SX1278)
  • 通信接口:ESP32-S3的UART2(GPIO17-TX、GPIO16-RX)对接SX1278的UART接口;
  • 控制接口:GPIO4作为SX1278复位引脚,GPIO5作为SX1278状态指示引脚;
  • 电源:3.3V供电,添加0.1μF去耦电容。
  1. 云对接与调试接口
  • Wi-Fi接口:ESP32-S3自带Wi-Fi模块,无需额外电路,通过天线座外接2.4G Wi-Fi天线;
  • BLE调试:利用ESP32-S3自带BLE功能,支持手机APP调试;
  • 备用UART调试:UART0(GPIO1-TX、GPIO3-RX),可外接CH340G用于串口调试。
  1. 辅助功能电路
  • 状态指示:2个LED灯(GPIO2-电源灯,GPIO15-LoRa通信状态灯);
  • 按键:2个功能按键(GPIO0-复位按键,GPIO14-配置按键,用于Wi-Fi配网)。
7.3.3 软件方案设计(核心流程-分MCU)
7.3.3.1 NRF52840软件方案
  1. 系统初始化流程
  • 上电复位后,初始化NRF52840核心外设:时钟(64MHz)、UART1(LoRa对接)、UART0(调试)、GPIO(LED/按键)、RTC、BLE;
  • 初始化LoRa模块:通过UART1发送AT指令,配置LoRa频段、扩频因子、带宽等参数;
  • BLE初始化:配置BLE广播名称,设置数据收发服务和特征值,支持手机APP连接调试。
  1. 数据收发与本地交互流程
  • 接收流程:NRF52840通过UART1接收SX1278的LoRa数据,解析后通过BLE发送至手机APP,同时可通过SPI接口将数据存储至SD卡(可选);
  • 发送流程:手机APP通过BLE下发指令,NRF52840接收后通过UART1发送至SX1278,由SX1278调制为LoRa信号发送,发送完成后向APP反馈状态。
  1. 低功耗流程
  • 无数据收发时,NRF52840进入低功耗模式(仅保留RTC和BLE广播);
  • 定时唤醒:RTC定时10秒唤醒,检查LoRa数据和BLE连接状态;
  • 按键唤醒:配置按键触发外部中断唤醒系统。
7.3.3.2 CH585M软件方案(沿用原有)
  1. 系统初始化流程
  • 上电复位后,初始化CH585M核心外设:时钟(48MHz)、UART1(LoRa对接)、UART0(调试)、GPIO(LED/按键)、RTC;
  • 初始化LoRa模块:通过UART1发送AT指令,配置LoRa频段、扩频因子、带宽等参数。
  1. 数据收发流程
  • 接收流程:CH585M通过UART1接收SX1278的LoRa数据,解析后通过UART0发送至上位机;
  • 发送流程:上位机通过UART0下发指令,CH585M接收后通过UART1发送至SX1278,由SX1278调制为LoRa信号发送。
  1. 低功耗流程
  • 无数据收发时,CH585M进入休眠模式(仅保留RTC);
  • 定时唤醒:RTC定时10秒唤醒,检查LoRa数据;
  • 按键唤醒:配置按键触发外部中断唤醒系统。
7.3.3.3 ESP32-S3软件方案(沿用原有)
  1. 系统初始化流程
  • 上电复位后,初始化ESP32-S3核心外设:时钟(240MHz)、UART2(LoRa对接)、GPIO(LED/按键)、RTC、Wi-Fi、BLE;
  • 初始化LoRa模块:通过UART2发送AT指令,配置LoRa频段、扩频因子、带宽等参数;
  • Wi-Fi配网:支持AirKiss配网或按键触发配网,连接指定Wi-Fi热点。
  1. 数据收发与云对接流程
  • 接收流程:ESP32-S3通过UART2接收SX1278的LoRa数据,解析后通过Wi-Fi上传至云平台,同时本地缓存数据(防止网络中断);
  • 发送流程:云平台下发指令,ESP32-S3接收后通过UART2发送至SX1278,由SX1278调制为LoRa信号发送,发送完成后向云平台反馈状态。
  1. 低功耗流程
  • 无数据收发时,ESP32-S3进入轻度休眠模式(仅保留RTC和Wi-Fi心跳);
  • 定时唤醒:RTC定时10秒唤醒,检查LoRa数据和Wi-Fi连接状态;
  • 按键唤醒:配置按键触发外部中断唤醒系统。
  1. 系统初始化流程
  • 上电复位后,初始化ESP32-S3核心外设:时钟(240MHz)、UART2(LoRa对接)、GPIO(LED/按键)、RTC、Wi-Fi、BLE;
  • 初始化LoRa模块:通过UART2发送AT指令,配置LoRa频段、扩频因子、带宽等参数;
  • Wi-Fi配网:支持AirKiss配网或按键触发配网,连接指定Wi-Fi热点。
  1. 数据收发与云对接流程
  • 接收流程:ESP32-S3通过UART2接收SX1278的LoRa数据,解析后通过Wi-Fi上传至云平台,同时本地缓存数据(防止网络中断);
  • 发送流程:云平台下发指令,ESP32-S3接收后通过UART2发送至SX1278,由SX1278调制为LoRa信号发送,发送完成后向云平台反馈状态。
  1. 低功耗流程
  • 无数据收发时,ESP32-S3进入轻度休眠模式(仅保留RTC和Wi-Fi心跳);
  • 定时唤醒:RTC定时10秒唤醒,检查LoRa数据和Wi-Fi连接状态;
  • 按键唤醒:配置按键触发外部中断唤醒系统。

7.4 基于三款MCU的one_channel_hub搭建详细步骤

7.4.1 NRF52840搭建步骤(面包板原型验证)
  1. 前置准备物料
  • 核心芯片:NRF52840开发板、SX1278 LoRa模块;
  • 通信器件:2.4G BLE天线(IPEX接口)、64MHz晶振、32.768KHz晶振;
  • 辅助器件:AMS1117-3.3V、TP4056、CH340G、LED、按键、SD卡模块(可选);
  • 连接器件:面包板、杜邦线(公对公、公对母);
  • 调试工具:WCH-Link调试器、万用表。
  1. 分步搭建与测试

  2. 搭建供电电路

  • AMS1117-3.3V输入接5V(USB或锂电池经TP4056),输出3.3V;
  • 3.3V分别给NRF52840开发板、SX1278模块、CH340G供电;
  • 接入电源,测试电源灯(GPIO13)亮,供电稳定。
  1. 搭建调试接口电路
  • CH340G TX接NRF52840 GPIO6(UART0_RX),CH340G RX接NRF52840 GPIO8(UART0_TX);
  • 安装CH340G驱动,打开串口助手,配置波特率115200。
  1. 搭建LoRa模块对接电路
  • SX1278 VCC接3.3V,GND接GND;
  • SX1278 TX接NRF52840 GPIO25(UART1_RX),SX1278 RX接NRF52840 GPIO24(UART1_TX);
  • SX1278 RST接NRF52840 GPIO26,SX1278 DIO0接NRF52840 GPIO27;
  • 连接BLE天线至NRF52840开发板的IPEX接口。
  1. 搭建扩展功能电路(可选)
  • SD卡模块VCC接3.3V,GND接GND;
  • SD卡模块 SCK接NRF52840 GPIO19,MOSI接GPIO20,MISO接GPIO21,CS接GPIO22;
  • 配置按键(GPIO16)串联10K上拉电阻接3.3V,另一端接GND。
  1. 硬件自检
  • 接通电源,电源灯亮;
  • 按下复位按键,NRF52840正常启动,无异常发热;
  • 串口助手接收"sys init ok!"调试信息。
7.4.2 NRF52840软件搭建步骤(基于Nordic SDK)
  1. 开发环境搭建
  1. 核心代码开发与调试
  • 初始化外设:编写uart_init.c、ble_init.c、lora_init.c,分别初始化UART0(调试)、UART1(LoRa)、BLE、LoRa模块;
  • 数据收发逻辑:编写lora_comm.c,实现LoRa数据收发与BLE数据交互;
  • 扩展功能开发(可选):编写sdcard.c,实现SD卡本地数据存储;
  • 下载调试:通过WCH-Link将程序下载到NRF52840,利用SES查看调试信息,通过手机APP连接BLE验证数据交互。
7.4.3 CH585M与ESP32-S3搭建步骤(沿用原有)

CH585M搭建步骤参考原有2. 硬件搭建物料清单与核心调试步骤速查表;ESP32-S3搭建步骤参考原有7.4 基于ESP32-S3的one_channel_hub搭建详细步骤。

7.4.1 硬件搭建步骤(面包板原型验证)
  1. 前置准备物料(新增/调整部分)
  • 核心芯片:ESP32-S3-DevKitC-1开发板(替代裸芯片,简化开发)、SX1278 LoRa模块;
  • 辅助器件:2.4G Wi-Fi天线(IPEX接口)、40MHz晶振、32.768KHz晶振;
  • 其他物料:与CH585M方案通用(AMS1117、TP4056、LED、按键等)。
  1. 分步搭建与测试

  2. 搭建供电电路

  • 同CH585M方案,AMS1117-3.3V输出3.3V,分别给ESP32-S3开发板、SX1278模块供电;
  • 接入锂电池,测试TP4056充电功能,确保供电稳定。
  1. 搭建LoRa模块对接电路
  • SX1278 VCC接3.3V,GND接GND;
  • SX1278 TX接ESP32-S3 GPIO16(UART2_RX),SX1278 RX接ESP32-S3 GPIO17(UART2_TX);
  • SX1278 RST接ESP32-S3 GPIO4,SX1278 DIO0接ESP32-S3 GPIO5;
  • 连接Wi-Fi天线至ESP32-S3开发板的IPEX接口。
  1. 搭建辅助功能电路
  • LED灯:GPIO2接电源灯(串联1K电阻),GPIO15接LoRa状态灯(串联1K电阻);
  • 按键:GPIO14接配置按键(串联10K上拉电阻),复位按键使用开发板自带按键。
  1. 硬件自检
  • 接通电源,电源灯亮;
  • 按下复位按键,ESP32-S3正常启动,无异常发热。
7.4.2 软件搭建步骤(基于ESP-IDF)
  1. 开发环境搭建
  1. 核心代码开发与调试
  • 初始化外设:编写uart_init.c、wifi_init.c、lora_init.c,分别初始化UART2、Wi-Fi、LoRa模块;
  • 云对接开发:编写mqtt_client.c,实现通过MQTT协议对接物联网云平台;
  • 数据收发逻辑:编写lora_comm.c,实现LoRa数据收发与云平台数据交互;
  • 下载调试:通过USB Type-C将程序下载到ESP32-S3,利用ESP-IDF Monitor查看调试信息。

7.5 基于三款MCU的核心例程代码

7.5.1 NRF52840核心例程(UART+LoRa+BLE)
Plain 复制代码
#include "nrf_drv_uart.h"
#include "nrf_drv_gpiote.h"
#include "ble_nus.h"
#include "nrf_delay.h"
#include <string.h>

// 引脚定义
#define LORA_RST_PIN     26
#define LORA_DIO0_PIN    27
#define LED_LORA_PIN     14
#define LED_POWER_PIN    13
#define KEY_CONFIG_PIN   16

// UART1配置(对接SX1278,9600波特率)
#define UART_LORA_INSTANCE 1
#define UART_TX_PIN        24
#define UART_RX_PIN        25
#define UART_BUF_SIZE      128

// BLE相关定义
#define BLE_DEVICE_NAME "LoRa_Gateway_NRF52840"
static ble_nus_t m_nus;
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;

// UART句柄
static const nrf_drv_uart_t uart_lora = NRF_DRV_UART_INSTANCE(UART_LORA_INSTANCE);
static uint8_t uart_rx_buf[UART_BUF_SIZE];
static uint8_t uart_tx_buf[UART_BUF_SIZE];
static uint16_t uart_rx_len = 0;

// GPIO初始化
static void gpio_init(void)
{
    ret_code_t err_code;

    // 初始化GPIOTE驱动
    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    // LED引脚:推挽输出
    nrf_drv_gpiote_out_config_t out_config = NRF_DRV_GPIOTE_OUT_CONFIG_INIT_HIGH(false);
    err_code = nrf_drv_gpiote_out_init(LED_POWER_PIN, &out_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_gpiote_out_init(LED_LORA_PIN, &out_config);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_out_clear(LED_LORA_PIN);  // LoRa灯灭

    // LoRa复位引脚:推挽输出
    err_code = nrf_drv_gpiote_out_init(LORA_RST_PIN, &out_config);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_out_set(LORA_RST_PIN);  // 默认不复位

    // 配置按键:上拉输入,下降沿中断
    nrf_drv_gpiote_in_config_t in_config = NRF_DRV_GPIOTE_IN_CONFIG_INIT(NRF_GPIOTE_POLARITY_HITOLO, NRF_GPIO_PIN_PULLUP);
    err_code = nrf_drv_gpiote_in_init(KEY_CONFIG_PIN, &in_config, NULL);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_enable(KEY_CONFIG_PIN);
}

// UART事件回调函数
static void uart_event_handler(nrf_drv_uart_event_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_UART_EVT_RX_DONE:
            uart_rx_len = p_event->data.rx.length;
            // 接收LoRa数据,通过BLE发送
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {
                ble_nus_data_send(&m_nus, uart_rx_buf, &uart_rx_len, m_conn_handle);
                nrf_drv_gpiote_out_set(LED_LORA_PIN);
                nrf_delay_ms(100);
                nrf_drv_gpiote_out_clear(LED_LORA_PIN);
            }
            // 继续接收
            nrf_drv_uart_rx(&uart_lora, uart_rx_buf, UART_BUF_SIZE);
            break;
        case NRF_DRV_UART_EVT_TX_DONE:
            break;
        default:
            break;
    }
}

// UART初始化
static void uart_init(void)
{
    ret_code_t err_code;
    nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
    uart_config.pseltx = UART_TX_PIN;
    uart_config.pselrx = UART_RX_PIN;
    uart_config.baudrate = NRF_UART_BAUDRATE_9600;

    err_code = nrf_drv_uart_init(&uart_lora, &uart_config, uart_event_handler, NULL);
    APP_ERROR_CHECK(err_code);
    // 启用接收
    nrf_drv_uart_rx(&uart_lora, uart_rx_buf, UART_BUF_SIZE);
}

// LoRa模块复位
static void lora_reset(void)
{
    nrf_drv_gpiote_out_clear(LORA_RST_PIN);
    nrf_delay_ms(100);
    nrf_drv_gpiote_out_set(LORA_RST_PIN);
    nrf_delay_ms(100);
}

// LoRa模块配置(AT指令)
static void lora_config(void)
{
    lora_reset();
    nrf_delay_ms(500);

    // SX1278 AT指令配置(470MHz,SF7,125KHz)
    const char *at_cmds[] = {
        "AT+FREQ=470000000\r\n",
        "AT+SF=7\r\n",
        "AT+BW=125\r\n",
        "AT+CR=4\r\n",
        "AT+POWER=17\r\n",
        "AT+MODE=1\r\n",
        "AT+SAVE\r\n"
    };

    for (int i = 0; i < sizeof(at_cmds)/sizeof(at_cmds[0]); i++)
    {
        strcpy((char*)uart_tx_buf, at_cmds[i]);
        nrf_drv_uart_tx(&uart_lora, uart_tx_buf, strlen(at_cmds[i]));
        nrf_delay_ms(200);
    }
    // 发送初始化完成标识
    const char *init_ok = "LoRa module config ok!\r\n";
    strcpy((char*)uart_tx_buf, init_ok);
    nrf_drv_uart_tx(&uart_lora, uart_tx_buf, strlen(init_ok));
}

// BLE连接事件回调函数
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t err_code;
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            break;
        case BLE_GAP_EVT_DISCONNECTED:
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;
        case BLE_GATTS_EVT_WRITE:
            // 接收BLE下发指令,通过LoRa发送
            nrf_drv_uart_tx(&uart_lora, p_ble_evt->evt.gatts_evt.params.write.data, p_ble_evt->evt.gatts_evt.params.write.len);
            nrf_drv_gpiote_out_set(LED_LORA_PIN);
            nrf_delay_ms(100);
            nrf_drv_gpiote_out_clear(LED_LORA_PIN);
            break;
        default:
            break;
    }
}

// BLE初始化
static void ble_init(void)
{
    ret_code_t err_code;
    ble_stack_init_t init = {0};
    ble_gap_conn_params_t gap_conn_params = {0};
    ble_gap_sec_params_t gap_sec_params = {0};

    // 初始化BLE协议栈
    err_code = ble_stack_init(&init);
    APP_ERROR_CHECK(err_code);
    // 设置BLE事件回调
    NRF_SDH_BLE_OBSERVER(m_ble_observer, NRF_SDH_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    // 初始化NUS服务(Nordic UART Service)
    ble_nus_init_t nus_init = {0};
    nus_init.data_handler = NULL;
    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
    // 配置GAP参数
    memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    gap_conn_params.min_conn_interval = NRF_BLE_GAP_MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = NRF_BLE_GAP_MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = 0;
    gap_conn_params.conn_sup_timeout  = NRF_BLE_GAP_CONN_SUP_TIMEOUT;
    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
    // 设置设备名称
    err_code = sd_ble_gap_device_name_set(&(ble_gap_device_name_t){.name = (uint8_t*)BLE_DEVICE_NAME, .len = strlen(BLE_DEVICE_NAME)});
    APP_ERROR_CHECK(err_code);
    // 启动BLE广播
    err_code = sd_ble_gap_adv_start(&(ble_gap_adv_params_t){.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED, .interval = NRF_BLE_GAP_ADV_INTERVAL});
    APP_ERROR_CHECK(err_code);
}

// 系统初始化入口
void sys_init(void)
{
    // 初始化GPIO
    gpio_init();
    // 初始化UART
    uart_init();
    // 初始化BLE
    ble_init();
    // 初始化LoRa模块
    lora_config();
}

// 主函数入口
int main(void)
{
    // 系统初始化
    sys_init();
    // 进入主循环
    while (1)
    {
        nrf_delay_ms(1000);
    }
}
7.5.1 外设初始化例程(UART+LoRa+Wi-Fi)
Plain 复制代码
#include "esp_err.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "wifi.h"
#include <string.h>

// 引脚定义
#define LORA_RST_PIN     GPIO_NUM_4
#define LORA_DIO0_PIN    GPIO_NUM_5
#define LED_LORA_PIN     GPIO_NUM_15
#define LED_POWER_PIN    GPIO_NUM_2
#define KEY_CONFIG_PIN   GPIO_NUM_14

// UART2配置(对接SX1278,9600波特率)
#define UART_NUM_LORA    UART_NUM_2
#define UART_TX_PIN      GPIO_NUM_17
#define UART_RX_PIN      GPIO_NUM_16
#define BUF_SIZE         1024

static const char *TAG = "lora_gateway";

// GPIO初始化
void gpio_init(void)
{
    // LED引脚:推挽输出
    gpio_reset_pin(LED_POWER_PIN);
    gpio_reset_pin(LED_LORA_PIN);
    gpio_set_direction(LED_POWER_PIN, GPIO_MODE_OUTPUT);
    gpio_set_direction(LED_LORA_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(LED_POWER_PIN, 1);  // 电源灯亮
    gpio_set_level(LED_LORA_PIN, 0);   // LoRa灯灭

    // LoRa复位引脚:推挽输出
    gpio_reset_pin(LORA_RST_PIN);
    gpio_set_direction(LORA_RST_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(LORA_RST_PIN, 1);  // 默认不复位

    // 配置按键:上拉输入
    gpio_reset_pin(KEY_CONFIG_PIN);
    gpio_set_direction(KEY_CONFIG_PIN, GPIO_MODE_INPUT);
    gpio_set_pull_mode(KEY_CONFIG_PIN, GPIO_PULLUP_ONLY);
}

// UART初始化
void uart_init(void)
{
    const uart_config_t uart_config = {
        .baud_rate = 9600,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    // 配置UART参数
    uart_param_config(UART_NUM_LORA, &uart_config);
    // 设置UART引脚
    uart_set_pin(UART_NUM_LORA, UART_TX_PIN, UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    // 安装UART驱动
    uart_driver_install(UART_NUM_LORA, BUF_SIZE * 2, 0, 0, NULL, 0);
}

// LoRa模块复位
void lora_reset(void)
{
    gpio_set_level(LORA_RST_PIN, 0);
    vTaskDelay(pdMS_TO_TICKS(100));
    gpio_set_level(LORA_RST_PIN, 1);
    vTaskDelay(pdMS_TO_TICKS(100));
}

// LoRa模块配置(AT指令)
void lora_config(void)
{
    lora_reset();
    vTaskDelay(pdMS_TO_TICKS(500));

    // SX1278 AT指令配置(470MHz,SF7,125KHz)
    const char *at_cmds[] = {
        "AT+FREQ=470000000\r\n",
        "AT+SF=7\r\n",
        "AT+BW=125\r\n",
        "AT+CR=4\r\n",
        "AT+POWER=17\r\n",
        "AT+MODE=1\r\n",
        "AT+SAVE\r\n"
    };

    for (int i = 0; i < sizeof(at_cmds)/sizeof(at_cmds[0]); i++) {
        uart_write_bytes(UART_NUM_LORA, at_cmds[i], strlen(at_cmds[i]));
        vTaskDelay(pdMS_TO_TICKS(200));
        // 接收模块响应,验证配置结果
        uint8_t buf[64];
        int len = uart_read_bytes(UART_NUM_LORA, buf, sizeof(buf)-1, pdMS_TO_TICKS(100));
        if (len > 0) {
            buf[len] = '\0';
            ESP_LOGI(TAG, "LoRa config response: %s", buf);
        }
    }
    ESP_LOGI(TAG, "LoRa module config ok!");
}

// 系统初始化入口
void sys_init(void)
{
    // 初始化GPIO
    gpio_init();
    // 初始化UART
    uart_init();
    // 初始化Wi-Fi(配网)
    wifi_init_sta();  // 自定义Wi-Fi STA模式初始化函数
    // 初始化LoRa模块
    lora_config();

    ESP_LOGI(TAG, "System init ok!");
}
7.5.2 LoRa数据收发与Wi-Fi云上传例程(MQTT协议)
Plain 复制代码
#include "esp_err.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "mqtt_client.h"
#include "string.h"

static const char *TAG = "lora_cloud";
static esp_mqtt_client_handle_t client;

// MQTT连接配置(对接阿里云示例)
#define MQTT_BROKER_URL "mqtt://xxx.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883"
#define MQTT_CLIENT_ID "xxx|securemode=3,tlsVersion=1,signmethod=hmacsha1|"
#define MQTT_USERNAME "xxx&xxx"
#define MQTT_PASSWORD "xxx"
#define MQTT_PUB_TOPIC "/sys/xxx/xxx/thing/event/property/post"

// MQTT事件回调函数
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    esp_mqtt_event_handle_t event = event_data;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT connected!");
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT disconnected!");
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "Received MQTT data: %.*s", event->data_len, event->data);
            // 接收云平台下发指令,通过LoRa发送
            uart_write_bytes(UART_NUM_LORA, event->data, event->data_len);
            gpio_set_level(LED_LORA_PIN, 1);
            vTaskDelay(pdMS_TO_TICKS(100));
            gpio_set_level(LED_LORA_PIN, 0);
            break;
        default:
            break;
    }
}

// MQTT客户端初始化
void mqtt_client_init(void)
{
    const esp_mqtt_client_config_t mqtt_config = {
        .uri = MQTT_BROKER_URL,
        .client_id = MQTT_CLIENT_ID,
        .username = MQTT_USERNAME,
        .password = MQTT_PASSWORD,
    };

    client = esp_mqtt_client_init(&mqtt_config);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);
}

// LoRa数据接收与云上传任务
void lora_cloud_task(void *pvParameters)
{
    uint8_t lora_buf[128];
    while (1) {
        // 读取LoRa数据
        int len = uart_read_bytes(UART_NUM_LORA, lora_buf, sizeof(lora_buf)-1, pdMS_TO_TICKS(1000));
        if (len > 0) {
            lora_buf[len] = '\0';
            ESP_LOGI(TAG, "Received LoRa data: %s", lora_buf);

            // 构造MQTT上传数据(JSON格式)
            char pub_buf[256];
            snprintf(pub_buf, sizeof(pub_buf), 
                     "{\"method\":\"thing.event.property.post\",\"params\":{\"lora_data\":\"%s\"}}", 
                     lora_buf);

            // 上传至云平台
            int ret = esp_mqtt_client_publish(client, MQTT_PUB_TOPIC, pub_buf, 0, 1, 0);
            if (ret > 0) {
                ESP_LOGI(TAG, "MQTT publish success, msg_id: %d", ret);
                gpio_set_level(LED_LORA_PIN, 1);
                vTaskDelay(pdMS_TO_TICKS(100));
                gpio_set_level(LED_LORA_PIN, 0);
            } else {
                ESP_LOGE(TAG, "MQTT publish failed");
            }
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

// 主函数入口
void app_main(void)
{
    // 系统初始化
    sys_init();
    // MQTT客户端初始化
    mqtt_client_init();
    // 创建LoRa数据收发与云上传任务
    xTaskCreate(lora_cloud_task, "lora_cloud_task", 4096, NULL, 5, NULL);
}
Plain 复制代码
#include "esp_err.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "wifi.h"
#include <string.h>

// 引脚定义
#define LORA_RST_PIN     GPIO_NUM_4
#define LORA_DIO0_PIN    GPIO_NUM_5
#define LED_LORA_PIN     GPIO_NUM_15
#define LED_POWER_PIN    GPIO_NUM_2
#define KEY_CONFIG_PIN   GPIO_NUM_14

// UART2配置(对接SX1278,9600波特率)
#define UART_NUM_LORA    UART_NUM_2
#define UART_TX_PIN      GPIO_NUM_17
#define UART_RX_PIN      GPIO_NUM_16
#define BUF_SIZE         1024

static const char *TAG = "lora_gateway";

// GPIO初始化
void gpio_init(void)
{
    // LED引脚:推挽输出
    gpio_reset_pin(LED_POWER_PIN);
    gpio_reset_pin(LED_LORA_PIN);
    gpio_set_direction(LED_POWER_PIN, GPIO_MODE_OUTPUT);
    gpio_set_direction(LED_LORA_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(LED_POWER_PIN, 1);  // 电源灯亮
    gpio_set_level(LED_LORA_PIN, 0);   // LoRa灯灭

    // LoRa复位引脚:推挽输出
    gpio_reset_pin(LORA_RST_PIN);
    gpio_set_direction(LORA_RST_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(LORA_RST_PIN, 1);  // 默认不复位

    // 配置按键:上拉输入
    gpio_reset_pin(KEY_CONFIG_PIN);
    gpio_set_direction(KEY_CONFIG_PIN, GPIO_MODE_INPUT);
    gpio_set_pull_mode(KEY_CONFIG_PIN, GPIO_PULLUP_ONLY);
}

// UART初始化
void uart_init(void)
{
    const uart_config_t uart_config = {
        .baud_rate = 9600,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    // 配置UART参数
    uart_param_config(UART_NUM_LORA, &uart_config);
    // 设置UART引脚
    uart_set_pin(UART_NUM_LORA, UART_TX_PIN, UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    // 安装UART驱动
    uart_driver_install(UART_NUM_LORA, BUF_SIZE * 2, 0, 0, NULL, 0);
}

// LoRa模块复位
void lora_reset(void)
{
    gpio_set_level(LORA_RST_PIN, 0);
    vTaskDelay(pdMS_TO_TICKS(100));
    gpio_set_level(LORA_RST_PIN, 1);
    vTaskDelay(pdMS_TO_TICKS(100));
}

// LoRa模块配置(AT指令)
void lora_config(void)
{
    lora_reset();
    vTaskDelay(pdMS_TO_TICKS(500));

    // SX1278 AT指令配置(470MHz,SF7,125KHz)
    const char *at_cmds[] = {
        "AT+FREQ=470000000\r\n",
        "AT+SF=7\r\n",
        "AT+BW=125\r\n",
        "AT+CR=4\r\n",
        "AT+POWER=17\r\n",
        "AT+MODE=1\r\n",
        "AT+SAVE\r\n"
    };

    for (int i = 0; i < sizeof(at_cmds)/sizeof(at_cmds[0]); i++) {
        uart_write_bytes(UART_NUM_LORA, at_cmds[i], strlen(at_cmds[i]));
        vTaskDelay(pdMS_TO_TICKS(200));
        // 接收模块响应,验证配置结果
        uint8_t buf[64];
        int len = uart_read_bytes(UART_NUM_LORA, buf, sizeof(buf)-1, pdMS_TO_TICKS(100));
        if (len > 0) {
            buf[len] = '\0';
            ESP_LOGI(TAG, "LoRa config response: %s", buf);
        }
    }
    ESP_LOGI(TAG, "LoRa module config ok!");
}

// 系统初始化入口
void sys_init(void)
{
    // 初始化GPIO
    gpio_init();
    // 初始化UART
    uart_init();
    // 初始化Wi-Fi(配网)
    wifi_init_sta();  // 自定义Wi-Fi STA模式初始化函数
    // 初始化LoRa模块
    lora_config();

    ESP_LOGI(TAG, "System init ok!");
}
7.5.2 ESP32-S3核心例程(UART+LoRa+Wi-Fi)
Plain 复制代码
#include "CH58x_common.h"
#include "CH58x_uart.h"
#include "CH58x_gpio.h"
#include <string.h>

// 引脚定义
#define LORA_RST_PIN     GPIO_Pin_4
#define LED_LORA_PIN     GPIO_Pin_3
#define LED_POWER_PIN    GPIO_Pin_2

// UART1配置(对接SX1278,9600波特率)
#define UART_LORA       UART1
#define UART_TX_PIN     GPIO_Pin_8
#define UART_RX_PIN     GPIO_Pin_9
#define UART_BUF_SIZE   128

uint8_t uart_rx_buf[UART_BUF_SIZE];
uint8_t uart_tx_buf[UART_BUF_SIZE];
uint16_t uart_rx_len = 0;

// GPIO初始化
void gpio_init(void)
{
    // 配置LED引脚为推挽输出
    GPIO_InitTypeDef gpio_init_struct = {0};
    gpio_init_struct.GPIO_Pin = LED_POWER_PIN | LED_LORA_PIN;
    gpio_init_struct.GPIO_Mode = GPIO_ModeOut_PP;
    gpio_init_struct.GPIO_Speed = GPIO_Speed10MHz;
    GPIO_Init(GPIOA, &gpio_init_struct);
    GPIO_SetBits(GPIOA, LED_POWER_PIN);  // 电源灯亮
    GPIO_ResetBits(GPIOA, LED_LORA_PIN); // LoRa灯灭

    // 配置LoRa复位引脚为推挽输出
    gpio_init_struct.GPIO_Pin = LORA_RST_PIN;
    GPIO_Init(GPIOB, &gpio_init_struct);
    GPIO_SetBits(GPIOB, LORA_RST_PIN);  // 默认不复位
}

// UART初始化
void uart_init(void)
{
    UART_InitTypeDef uart_init_struct = {0};
    // 配置UART引脚
    GPIO_InitTypeDef gpio_init_struct = {0};
    gpio_init_struct.GPIO_Pin = UART_TX_PIN;
    gpio_init_struct.GPIO_Mode = GPIO_ModeOut_PP;
    gpio_init_struct.GPIO_Speed = GPIO_Speed10MHz;
    GPIO_Init(GPIOA, &gpio_init_struct);
    gpio_init_struct.GPIO_Pin = UART_RX_PIN;
    gpio_init_struct.GPIO_Mode = GPIO_ModeIN_FLOATING;
    GPIO_Init(GPIOA, &gpio_init_struct);
    // 配置UART参数
    uart_init_struct.UART_BaudRate = 9600;
    uart_init_struct.UART_WordLength = UART_WordLength_8b;
    uart_init_struct.UART_StopBits = UART_StopBits_1;
    uart_init_struct.UART_Parity = UART_Parity_No;
    uart_init_struct.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
    uart_init_struct.UART_Mode = UART_Mode_Tx_Rx;
    UART_Init(UART_LORA, &uart_init_struct);
    // 启用接收中断
    UART_ITConfig(UART_LORA, UART_IT_RXNE, ENABLE);
    NVIC_EnableIRQ(UART1_IRQn);
}

// UART中断服务函数
__INTERRUPT void UART1_IRQHandler(void)
{
    if (UART_GetITStatus(UART_LORA, UART_IT_RXNE) != RESET)
    {
        uart_rx_buf[uart_rx_len++] = UART_ReceiveData(UART_LORA);
        if (uart_rx_len >= UART_BUF_SIZE - 1 || uart_rx_buf[uart_rx_len - 1] == '\n')
        {
            // 接收完成,通过UART0发送至上位机
            UART_SendData(UART0, uart_rx_buf, uart_rx_len);
            GPIO_SetBits(GPIOA, LED_LORA_PIN);
            DelayMs(100);
            GPIO_ResetBits(GPIOA, LED_LORA_PIN);
            uart_rx_len = 0;
        }
        UART_ClearITPendingBit(UART_LORA, UART_IT_RXNE);
    }
}

// LoRa模块复位
void lora_reset(void)
{
    GPIO_ResetBits(GPIOB, LORA_RST_PIN);
    DelayMs(100);
    GPIO_SetBits(GPIOB, LORA_RST_PIN);
    DelayMs(100);
}

// LoRa模块配置(AT指令)
void lora_config(void)
{
    lora_reset();
    DelayMs(500);

    // SX1278 AT指令配置(470MHz,SF7,125KHz)
    const char *at_cmds[] = {
        "AT+FREQ=470000000\r\n",
        "AT+SF=7\r\n",
        "AT+BW=125\r\n",
        "AT+CR=4\r\n",
        "AT+POWER=17\r\n",
        "AT+MODE=1\r\n",
        "AT+SAVE\r\n"
    };

    for (int i = 0; i < sizeof(at_cmds)/sizeof(at_cmds[0]); i++)
    {
        strcpy((char*)uart_tx_buf, at_cmds[i]);
        UART_SendData(UART_LORA, uart_tx_buf, strlen(at_cmds[i]));
        DelayMs(200);
    }
    // 发送初始化完成标识
    const char *init_ok = "LoRa module config ok!\r\n";
    strcpy((char*)uart_tx_buf, init_ok);
    UART_SendData(UART_LORA, uart_tx_buf, strlen(init_ok));
}

// 系统初始化入口
void sys_init(void)
{
    SetSysClock(CLK_SOURCE_PLL_60MHz);
    // 初始化GPIO
    gpio_init();
    // 初始化UART0(调试)
    UART0_Init(115200);
    // 初始化UART1(LoRa)
    uart_init();
    // 初始化LoRa模块
    lora_config();
}

// 主函数入口
int main(void)
{
    sys_init();
    while (1)
    {
        DelayMs(1000);
    }
}
7.5.3 CH585M核心例程(UART+LoRa)

7.6 基于三款MCU的硬件物料与调试步骤补充速查表

7.6.1 ESP32-S3方案硬件物料补充表
物料类别 具体物料 规格参数 数量 用途说明
核心芯片 ESP32-S3-DevKitC-1开发板 Xtensa LX7双核,8MB Flash,512KB RAM 1块 网关主控,负责LoRa数据处理、Wi-Fi云对接
通信器件 2.4G Wi-Fi天线 IPEX接口,增益2dBi 1个 增强Wi-Fi信号,确保稳定连接云平台
核心芯片 SX1278 LoRa模块 支持470/868/915MHz,UART接口 1个 LoRa信号调制解调
其他物料 AMS1117-3.3V、TP4056、电容、电阻等 同CH585M方案规格 若干 供电、辅助功能实现
7.6.2 ESP32-S3方案核心调试步骤补充表
7.6.1 三款MCU方案硬件物料对比表
调试阶段 核心步骤 操作要点 验证标准 常见问题与解决办法
1. Wi-Fi配网调试 1. 初始化Wi-Fi STA模式;2. 触发配网;3. 连接指定Wi-Fi 1. 确保Wi-Fi天线连接良好;2. 通过按键或APP触发AirKiss配网;3. 配置正确的Wi-Fi名称和密码 ESP32-S3成功连接Wi-Fi;串口输出Wi-Fi IP地址 问题:Wi-Fi连接失败
解决:1. 检查Wi-Fi名称和密码是否正确;2. 确认Wi-Fi为2.4G频段(不支持5G);3. 检查Wi-Fi天线连接
2. MQTT云对接调试 1. 配置MQTT参数;2. 初始化MQTT客户端;3. 测试数据上传 1. 正确填写MQTT Broker地址、客户端ID、用户名密码;2. 确保云平台设备已注册;3. 测试前关闭防火墙 MQTT连接成功;LoRa数据可正常上传至云平台;云平台下发指令可接收 问题:MQTT连接失败
解决:1. 核对MQTT参数是否正确;2. 检查网络是否能ping通MQTT Broker;3. 确认云平台设备证书有效
3. LoRa与云协同调试 1. 启动LoRa数据收发;2. 测试数据云上传;3. 测试云指令下发 1. 确保LoRa模块配置与终端一致;2. 观察串口调试信息;3. 查看云平台数据接收状态 LoRa终端发送的数据可在云平台查看;云平台下发的指令可通过LoRa发送至终端 问题:数据上传延迟/丢包
解决:1. 优化Wi-Fi信号强度;2. 增加本地数据缓存机制;3. 调整MQTT重连策略
7.6.2 三款MCU方案核心调试步骤对比表
物料类别 NRF52840方案 CH585M方案 ESP32-S3方案
核心芯片 NRF52840开发板、SX1278 LoRa模块 CH585M芯片、SX1278 LoRa模块 ESP32-S3-DevKitC-1开发板、SX1278 LoRa模块
通信器件 2.4G BLE天线、64MHz晶振、32.768KHz晶振 12MHz晶振、32.768KHz晶振 2.4G Wi-Fi天线、40MHz晶振、32.768KHz晶振
供电与调试 AMS1117-3.3V、TP4056、CH340G、WCH-Link AMS1117-3.3V、TP4056、CH340G、WCH-Link AMS1117-3.3V、TP4056、USB Type-C线
辅助器件 LED、按键、SD卡模块(可选)、电阻电容 LED、按键、电阻电容 LED、按键、电阻电容
核心成本(估算) ≈36元(NRF52840+SX1278+天线) ≈16元(CH585M+SX1278) ≈45元(ESP32-S3+SX1278+天线)
调试阶段
--- ---

7.7 三款MCU方案核心差异总结

对比维度 CH585M方案 NRF52840方案 ESP32-S3方案
核心优势 成本最低、功耗最小、封装小巧 开发成熟、无冗余功耗、扩展灵活 自带Wi-Fi+BLE、算力强、直接上云
核心劣势 Flash/RAM小、扩展受限 无Wi-Fi、上云需额外模块 成本较高、功耗略大
适用场景 批量低成本、纯单通道数据收发 无Wi-Fi需求、多外设扩展 直接上云、多协议融合、功能迭代
硬件成本(核心器件) ≈16元(CH585M+SX1278) ≈36元(NRF52840+SX1278) ≈45元(ESP32-S3+SX1278+天线)
相关推荐
兮动人1 天前
C语言之指针入门
c语言·开发语言·c语言之指针入门
知行学思1 天前
Python配置管理完全指南:从dotenv到pydantic_settings
数据库·python·fastapi·环境变量·配置管理·pydantic·dotenv
leoufung1 天前
LeetCode 97. 交错字符串 - 二维DP经典题解(C语言实现)
c语言·算法·leetcode
计算机网恋1 天前
Ubuntu22.04Server虚拟机网络配置
网络·数据库·postgresql
一路往蓝-Anbo1 天前
STM32单线串口通讯实战(五):RTOS架构 —— 线程安全与零拷贝设计
c语言·开发语言·stm32·单片机·嵌入式硬件·观察者模式·链表
今天也好累1 天前
C语言安全格式化:snprintf核心指南
c语言·笔记·学习·visual studio
一只大黄猫1 天前
【数据库-入门2】基本概念
数据库
智者知已应修善业1 天前
【数组删除重复数据灵活算法可修改保留重复数量】2024-3-4
c语言·c++·经验分享·笔记·算法
你怎么知道我是队长1 天前
C语言---字符串
java·c语言·算法