手把手教你用STM32F103C8T6和BC20模块,把温湿度+GPS数据搬到OneNet地图上(附完整代码)

张开发
2026/4/21 3:13:20 15 分钟阅读

分享文章

手把手教你用STM32F103C8T6和BC20模块,把温湿度+GPS数据搬到OneNet地图上(附完整代码)
基于STM32F103C8T6与BC20模块的物联网地理信息可视化实战在物联网应用开发中地理位置数据的采集与可视化呈现是一个极具实用价值的技术方向。本文将详细介绍如何利用STM32F103C8T6微控制器与BC20通信模块构建一个完整的物联网终端实现温湿度数据与GPS信息的采集并通过OneNet平台实现数据的云端可视化展示。1. 硬件系统架构设计1.1 核心硬件选型与特性本系统的硬件架构围绕STM32F103C8T6微控制器展开这是一款基于ARM Cortex-M3内核的32位微控制器具有以下关键特性72MHz主频提供足够的处理能力处理传感器数据和通信协议64KB Flash/20KB SRAM满足中等复杂度应用的程序存储需求丰富的外设接口包括USART、SPI、I2C等便于连接各类传感器和通信模块BC20模块是一款集成了NB-IoT通信和GPS定位功能的复合模块其技术参数如下表所示特性参数说明通信制式NB-IoT支持Band3/Band5/Band8GPS性能灵敏度-147dBm冷启动时间35秒工作电压3.3V-4.2V典型值3.8V工作电流通信时约120mA低功耗模式下1mA1.2 系统硬件连接方案硬件连接需要特别注意信号完整性和电源稳定性以下是关键连接点STM32与BC20的串口连接USART2_TX(PA2) → BC20_RXUSART2_RX(PA3) ← BC20_TX波特率设置为9600bpsDHT11温湿度传感器连接数据线连接至PC13需外接4.7K上拉电阻OLED显示接口采用SPI接口连接分辨率128x64用于本地数据显示提示BC20模块的GPS天线应尽量放置在开放空间避免金属遮挡影响定位性能。2. 软件开发环境搭建2.1 工具链配置开发环境建议采用以下组合# 安装ARM工具链 sudo apt-get install gcc-arm-none-eabi # 安装OpenOCD用于调试 sudo apt-get install openocd # 安装STM32CubeMX用于外设配置2.2 关键驱动实现2.2.1 BC20模块AT指令处理BC20模块通过AT指令进行控制以下是核心指令处理函数BC20_ErrorCode BC20_SendAT(const char *cmd, const char *expected_resp, uint32_t timeout_ms) { uint32_t count 0; uint32_t max_count timeout_ms / 10; BC20_ClearRecvBuf(); USART2_SendStr((char*)cmd); while (count max_count) { if (buf_uart2.rx_flag) { strncpy(s_recv_buf, buf_uart2.buf, BC20_BUF_LEN-1); if (strstr(s_recv_buf, expected_resp) ! NULL) { return BC20_OK; } buf_uart2.rx_flag 0; } delay_ms(10); count; } return BC20_ERR_TIMEOUT; }2.2.2 GPS数据解析BC20模块输出的GPS数据采用NMEA-0183协议以下是GPRMC语句解析实现static BC20_ErrorCode BC20_ParseGPRMC(const char *rmc_str, GPS_Data *gps) { char *token; char rmc_copy[BC20_BUF_LEN]; strncpy(rmc_copy, rmc_str, BC20_BUF_LEN-1); token strtok(rmc_copy, ,); // $GNRMC token strtok(NULL, ,); // 时间 token strtok(NULL, ,); // 状态 if (token NULL || strcmp(token, A) ! 0) { gps-is_valid 0; return BC20_OK; } // 解析纬度 token strtok(NULL, ,); float lat_deg atof(token) / 100; int deg (int)lat_deg; gps-latitude deg (lat_deg - deg) * 100 / 60; // 解析经度 token strtok(NULL, ,); float lon_deg atof(token) / 100; deg (int)lon_deg; gps-longitude deg (lon_deg - deg) * 100 / 60; gps-is_valid 1; return BC20_OK; }3. OneNet平台集成3.1 平台配置流程OneNet平台配置分为以下几个关键步骤创建产品登录OneNet开发者中心选择产品开发→创建产品设置产品名称、选择设备接入方式定义物模型添加三个数据点温度、湿度、位置信息位置信息数据类型设置为JSON格式创建设备记录设备ID、产品ID和鉴权信息这些参数将用于设备连接认证3.2 数据上传实现设备通过MQTT协议与OneNet平台通信数据上传函数实现如下BC20_ErrorCode BC20_SendToOneNet(float temp, float humi, const GPS_Data *gps) { char cmd[BC20_BUF_LEN]; snprintf(cmd, BC20_BUF_LEN, ATQMTPUB0,0,0,0,\$sys/%s/%s/thing/property/post\, {\id\:\123\,\version\:\1.0\,\params\:{ \temp\:{\value\:%.1f}, \humi\:{\value\:%.1f}, \map\:{\value\:{\Lon\:\%.6f\,\Lat\:\%.6f\}} }}\r\n, OneNet_PRODUCT_ID, OneNet_DEVICE_ID, temp, humi, gps-longitude, gps-latitude); return BC20_SendAT_NOOLED(cmd, OK, 5000); }4. 数据可视化实现4.1 OneNet地图组件配置在OneNet平台上实现地理信息可视化需要以下步骤创建数据流进入设备详情页添加location数据流设置数据类型为地理位置配置地图组件在应用可视化编辑器中添加地图组件绑定设备数据流到地图设置轨迹显示样式和刷新频率4.2 数据呈现优化技巧数据平滑处理在设备端对GPS坐标进行移动平均滤波减少定位跳动轨迹压缩只上传坐标变化超过阈值的数据点节省流量多设备显示通过不同颜色标识不同设备便于区分// GPS数据平滑处理示例 #define FILTER_WINDOW 5 typedef struct { float latitude[FILTER_WINDOW]; float longitude[FILTER_WINDOW]; uint8_t index; } GPS_Filter; void GPS_Filter_Update(GPS_Filter *filter, float lat, float lon) { filter-latitude[filter-index] lat; filter-longitude[filter-index] lon; filter-index (filter-index 1) % FILTER_WINDOW; } void GPS_Filter_GetAverage(GPS_Filter *filter, float *lat, float *lon) { float sum_lat 0, sum_lon 0; for(int i0; iFILTER_WINDOW; i) { sum_lat filter-latitude[i]; sum_lon filter-longitude[i]; } *lat sum_lat / FILTER_WINDOW; *lon sum_lon / FILTER_WINDOW; }5. 系统优化与问题排查5.1 常见问题解决方案在实际部署中可能会遇到以下典型问题GPS定位失败检查天线连接和放置位置增加定位超时时间和重试机制在开阔场地进行首次定位数据上传失败检查SIM卡状态和网络信号强度验证OneNet平台鉴权信息增加数据发送重试逻辑电源不稳定为BC20模块提供独立电源滤波在电源输入端增加大容量电容5.2 低功耗优化策略对于电池供电的应用场景可采取以下措施降低功耗间歇工作模式设备大部分时间处于休眠状态定时唤醒采集数据网络连接管理完成数据上传后主动断开网络连接传感器电源控制通过MOS管控制传感器电源非采集时段断电// 低功耗模式实现示例 void Enter_LowPower_Mode(void) { // 关闭外设时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE); // 配置唤醒源 EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line EXTI_Line0; EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd ENABLE; EXTI_Init(EXTI_InitStructure); // 进入停止模式 PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); // 唤醒后重新初始化系统时钟 SystemInit(); }通过上述完整的实现方案开发者可以构建一个稳定可靠的物联网地理信息采集与可视化系统。该系统不仅适用于资产追踪、环境监测等工业场景也可扩展应用于智能农业、物流运输等多个领域。

更多文章