ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于STM32与OneNet的货车重量检测系统保姆级设计笔记

基于STM32与OneNet的货车重量检测系统保姆级设计笔记 简介面向嵌入式与物联网课程设计、毕业设计及实际项目开发的货车重量检测系统完整源码包围绕STM32单片机、HX711称重传感器与ESP8266 WiFi模块构建通过采集称重数据并上传至OneNet云平台实现货车载重的实时监测与远程管理解决传统称重方式效率低、数据不易查看的问题。资源包共335个文件压缩后约108.58MB包含STM32的C源码与H头文件、HX711驱动、ESP8266透传通信代码、可烧录hex文件、Keil工程配置以及PDF设计文档、原理图、实物图和配套软件工具目录结构完整清晰。目前已有830人学习下载。无论是想完整复现这套物联网称重系统还是仅学习传感器采集、WiFi数据传输与云平台对接都能依托源码注释、设计文档、使用说明和接线指引快速上手直观理解从称重传感器到OneNet显示的完整链路并可将方案迁移到其他智能称重或物联网监测场景。 这篇博文会有点长因为我打算把它当成一份完整的“保姆级”设计笔记来写而不是一个简单的项目简介。基于这个“基于STM32物联网设计的货车重量检测系统(OneNet)-源码包”标题和相关的热词我将它拆解成一位工程师从拿到源码包到完全跑通再到二次开发的全过程。这不是一个简单的“我发个源码包”的帖子它需要回答的是这个系统到底怎么用原理是什么我拿到代码后能不能烧录跑通遇到问题怎么办我把整个内容重新整理成了下面这篇可复现的技术长文。1. 拿到源码包后先看清这个系统的高层设计很多同学下载完源码包第一反应就是打开工程文件然后开始找main函数。我的习惯相反第一步是先看系统架构因为只有把数据流摸清楚了后面遇到问题才知道是卡在传感器、主控、WiFi模块还是云平台。1.1 为什么选用“STM32ESP8266OneNet”这个黄金组合这个项目实际上解决了货车称重场景里的一个非常实际的需求车辆在装载货物时需要快速知道是否超载但传统地磅需要车辆开到固定地点而且数据无法实时汇聚。而这套系统的核心思路是让重量数据直接上网。主控芯片选择的是STM32系列从源码包命名和热词看很可能是STM32F103C8T6或同系列。它的优势是资源够用、资料多、库函数稳定对付HX711和ESP8266这种外设绰绰有余。更重要的是如果是做毕业设计STM32在答辩时能讲的观点也更多。WiFi模块用ESP8266-01S或ESP-12F它的工作就是把串口数据转成TCP/IP报文按照HTTP协议发给OneNet平台。平台用中国移动的OneNet不用自建服务器用免费版就够。它提供了完善的数据流、APIKey和设备管理省掉了最麻烦的后端开发。从整体数据链路看这套系统的信息流是这样的货车重量 → 电阻应变式称重传感器 → HX711模数转换器 → STM32微控制器数据处理与逻辑判断 → ESP8266模块串口转WiFi → OneNet云平台 → 手机或电脑监控1.2 源码包里的文件哪些是需要重点关注的核心文件源码包解压后典型的目录结构应该包含以下几类你拿到手之后一定要优先看这几个文件文件路径与文件名文件作用重要程度User/main.c主逻辑初始化外设、主循环调用称重和上传函数核心Hardware/HX711/hx711.c读传感器ADC值、去皮、计算重量核心Hardware/ESP8266/esp8266.c串口配置、发AT指令、组建HTTP报文核心Hardware/OLED/oled.c本地显示重量和状态如果加了屏幕辅助Cloud/OneNet/onenet.c封装数据点上传和数据流映射核心拿到代码不要急着改功能先用串口助手确认你的开发板上电后HX711能不能正常读数ESP8266能不能用串口收到AT指令的OK回复。先把代码KEEP跑起来再谈二次开发。2. HX711称重传感器链路从毫伏级电压到直观数字这套系统的前端是称重这个环节如果搞不清楚后面的云端数据都是“垃圾进垃圾出”。很多人调不通不是云平台的问题而是重量传感器压根就没标定对。2.1 电阻应变式传感器与HX711芯片的配合原理先补一个底层认知。货车称重传感器内部是电阻应变片组成的惠斯通电桥当重物压在传感器上时应变片电阻发生变化电桥输出电压差。这个电压差有多小往往是毫伏级别的。所以需要HX711这款24位高精度AD芯片来做两级放大和模数转换。HX711与STM32之间只需要两根线SCK时钟和DOUT数据。它是典型的时序驱动型芯片。下面是HX711驱动中最重要的读数函数源码包里一定有类似的代码uint32_t HX711_Read(void) { uint32_t count 0; uint8_t i; // 等待DOUT变低表示转换完成 while(HAL_GPIO_ReadPin(HX711_DOUT_GPIO_Port, HX711_DOUT_Pin) GPIO_PIN_SET); // 读取24位数据 for(i 0; i 24; i) { HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); count count 1; HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); if(HAL_GPIO_ReadPin(HX711_DOUT_GPIO_Port, HX711_DOUT_Pin) GPIO_PIN_SET) { count; } } // 给第25个脉冲选择增益128A通道 HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); return count; }这段代码的关键点在于数据是补码形式最高位是符号位24位数据是左对齐的。所以我强烈建议你在读取后进行一次符号扩展否则满量程读数和零点读数在计算差值时可能出现负数溢出。2.2 标定流程没有这一步骤屏幕上的数字没有任何意义如果用标准的100kg砝码标定通常在代码里会看到这样的逻辑// 在main函数初始化后先让传感器空载稳定10秒 HX711_Tare(20); // 采样20次取平均作为去皮基准 // 放上标准砝码读取ADC值变化量 int32_t adc_span HX711_Read_Average(10) - tare_value; // 得出每个ADC码对应的重量单位kg/码 float calibration_factor 100.0f / (float)adc_span;但在实际货车称重场景里有三点容易被忽略传感器的量程要远大于实际载荷上限。比如要称10吨的货车传感器量程不能选10吨的至少要选15吨到20吨。保证传感器工作在线性区ADC值变化才不会怪。效率高不等于精度高。HX711有10SPS和80SPS两种输出速率。我实测下来货车动态称重必须用10SPS模式虽然慢一点但稳定。80SPS挡位上数据抖动能达到几十个码在秤台上晃动时基本没法看。电源纹波会吃掉精度。HX711的AVDD直接决定了ADC的满量程电压如果供电纹波大测出来的重量会自己漂移。板子尽量用线性稳压别直接拿开关电源怼上去。2.3 为什么推荐加一个OLED屏幕做本地显示有人会问数据都上传OneNet了为什么还要本地屏幕我的个人经验是重量上传会有网络延迟货车司机在秤台上等不了1秒。本地OLED显示的是实时反馈云端数据是事后追溯。两者分工不同缺一不可。常用的就是0.96寸I2C接口的OLEDSSD1306驱动STM32软模拟I2C就能搞定占两个GPIO就够了。3. ESP8266接OneNetHTTP上报方式的细节拆解这个是整个项目里最容易出bug、也最考察通信逻辑的部分。常见的热词里也有“esp8266连接onenet失败”、“onenet生成apikey”说明大家卡在这里的不少。3.1 在OneNet平台上创建产品、设备和APIKey这个步骤在源码包的README或者博文里通常是一笔带过的但没有操作过的新手容易漏掉关键信息。我把每个细节都写清楚注册登录OneNet平台进入控制台选择一个项目或新建一个项目。在“多协议接入”页面选择“HTTP协议”点击添加产品。产品名称“货车重量检测系统”行业选“智慧交通”或者“智慧物流”技术方案选“HTTP/HTTPS”。产品创建成功后在设备管理页面添加设备。设备名称建议直接用ASCII字符不要用中文。因为有些HTTP库处理中文URL编码会出乱码导致鉴权失败。你可以用truck001这样的名字。APIKey在“设备详情”里有单独的一栏。这个Key是整个设备访问接口的身份标识相当于你设备的“密码”。点击复制的时候注意APIKey很容易在复制时少一位建议复制到记事本里先确认长度常见APIKey长度是32位左右。记住设备ID这个ID在URL拼接和上传数据点时会用到。3.2 HTTP POST请求的报文格式该用什么函数去编码OneNet的HTTP协议接入上报数据点常用的接口是POST /devices/{device_id}/datapoints Host: api.heclouds.com api-key: {你的apikey} Content-Type: application/json请求体示例{datastreams:[{id:weight,datapoints:[{value:12500}]}]}这个JSON看起来很简单但问题往往出在如何用STM32生成这个JSON字符串上。因为STM32的资源有限你不可能引入复杂的JSON库常用的做法是用sprintf拼字符串。源码包里应该有类似这样的代码char buf[128]; sprintf(buf, {\datastreams\:[{\id\:\weight\,\datapoints\:[{\value\:%.2f}]}]}, weight_kg);这里有两个大坑%.2f在C标准库里占空间巨大如果你用的是微型版printf浮点数格式化可能会输出空字符串。备选方案是先把重量拆成整数部分和小数部分分别用%d格式化。转义引号容易错。上面这行代码里所有的双引号前必须加反斜杠漏一个就完蛋。3.3 AT指令流程ESP8266真正的干活顺序ESP8266在源码包里可能有两种模式一种是直接用AT指令控制一种是用官方SDK透传。从源码包的属性推断大概率是AT指令方式。于是我们需要保证下面这一串AT指令是稳定且按顺序初始化的AT ATE0 ATCWMODE1 ATCWJAP你的WiFi名,你的密码 ATTCPSTART ATTCPCONNECTapi.heclouds.com,80有经验的开发者会发现问题ATTCPCONNECT这条指令在很多ESP8266固件里不存在应该用ATCIPSTART指令。例如ATCIPSTARTTCP,api.heclouds.com,80连接成功后再用ATCIPSEND发送HTTP报文最后发送这个十六进制字符表示报文结束ATCIPSENDlen再补充一点源码包中的代码如果用的是ESP8266官方固件建议先通过串口助手发一个ATGMR确认固件版本。AT指令的返回结果因固件版本不同差别很大我在调试中就遇到过新固件的连接返回是CONNECT\r\nOK老固件是CONNECT\r\n你的程序如果只等一个OK字符串就可能进入假死状态。处理方式就是状态机判断不要只盯着OK见到CONNECT也要当作成功。4. STM32端程序设计架构与常见宿命要说这个系统最核心的软件架构也就是为什么这套代码能稳定跑在货车称重场景而不会跑着跑着就死掉是因为它遵循了一个比较巧妙的主循环构建方式。4.1 状态机从“开机联网”到“稳定采集”再到“上传成功”很多初级代码会写成顺序执行看起来每一步都到了但如果哪一步卡住后续就全乱了。而一套设计得好的称重系统应该是一个完整的状态迁移过程。举一个典型的状态划分状态编号状态名称状态行为转移条件S0POWER_ON初始化时钟、GPIO、串口、I2C初始化完成即进入S1S1NET_INIT向ESP8266发AT配置WiFi连接收到WIFI GOT IP进入S2S2SENSOR_READY读取HX711零点完成去皮去皮完成进入S3S3RUNNING周期读取重量并更新OLED每次上传周期到达进入S4完成后回S3S4UPLOADING拼接JSONCIPSEND发数据到OneNet收到正常响应回S3如果代码是这么写的那么它天然具备异常恢复能力。比如S1如果有一段时间没有收到任何有效AT回复程序不应一直在原地死等而应当有超时计数超时后复位ESP8266重新初始化S4的HTTP请求发出去之后如果云端迟迟没有回应在主循环里应当有一个重试次数的限制超过3次就丢弃本次数据等待下一个周期再上传而不能因为一次网络抖动就打乱后续所有称重流程。4.2 时基管理为什么主循环里不能用HAL_Delay(1000)在源码包里可能不会明说但我强烈建议你在主循环里不要依赖HAL_Delay做长时间延时。原因很现实一旦调用了HAL_DelayHX711的读数和ESP8266的串口接收都会被阻塞如果此时恰好云端返回数据串口接收缓冲区可能溢出丢一个字节整个HTTP响应解析就会错乱。我采用的方案是SysTick时基加上一个简单的tick计数。main函数的主循环长这样while (1) { // 每10ms执行一次传感器滤波读取 if ((uwTick - last_tick_sensor) 10) { last_tick_sensor uwTick; weight_raw HX711_Read_Average(3); weight_kg (weight_raw - tare_value) * calibration_factor; OLED_ShowWeight(weight_kg); } // 每5秒上传一次重量到OneNet if ((uwTick - last_tick_upload) 5000) { last_tick_upload uwTick; if (ESP8266_SendDataToCloud(weight_kg) ESP8266_STATUS_OK) { OLED_ShowUploadOK(); } else { OLED_ShowUploadFail(); } } }这样程序永不阻塞所有模块调度都靠时间片轮转。实测下来这套逻辑在7x24小时的长时间运行测试中非常稳不会因为某一次网络失败而“卡死”在某个函数里。4.3 如果用的是4G模块合宙Air724调试注意什么热词里出现了“4g模块合宙air724”和“A7670C-4G模块MQTT通信避坑指南”这应该也会是很多人想扩展的方向。如果项目要脱离WiFi环境比如在货物堆场没有WiFi需要切换到4G模块那需要注意供电。4G模块在数据收发瞬间电流可达2ASTM32开发板上的3.3V无法直接驱动需要外部5V/2A电源给模块供电且地线必须共地。第一条AT指令建议是ATCREG?确认模块入网。如果返回CREG:0,1或0,5代表已注册否则可能是SIM卡接触不良。4G模块走MQTT协议上OneNet比HTTP更省流量OneNet支持MQTT旧版协议设备ID和APIKey能直接用于用户名和密码字段。源码包里如果是HTTP版本改造成MQTT版本需要同时调整消息topic和payload格式。这部分如果展开又是一篇文章了但大方向就是先用串口调试助手模拟模块发包确认服务器地址和topic没问题再让STM32接管。5. 整机联调时必踩的坑与完整排查链路很多时候项目跑不起来不是某一个代码文件的问题而是几个模块之间配合的问题。我这里专门列一列整个联调过程中比较高频的“坑”并且给出完整的排查链路供你拿着源码包对照。5.1 坑一ESP8266上电后AT指令无响应现象程序执行到初始化ESP8266时一直处于等待状态串口助手也发不出任何AT命令的OK回包。排查链路检查ESP8266模块VCC是否正常部分模块是3.3V供电但有些板载稳压需要5V供电。看模块丝印认准了再接。检查CH_PDEN引脚是否被拉高大多数模块必须把EN引脚接到3.3V才能工作如果悬空模块相当于关闭状态。检查RXD和TXD是否交叉连接。此时串口调试助手应当能看到模块上电后的乱码或ready字样如果完全没有大概率是接线问题。将串口波特率降低到9600试试某些固件默认波特率是115200但也有的是9600。5.2 坑二OneNet平台一直显示设备离线这是最让人抓狂的一个坑明明ESP8266已经连接上WiFi了平台还是显示离线。要理解一个关键点OneNet的设备在线状态与TCP长连接有关。设备端如果只是偶尔发起一次HTTP请求平台显示设备在线的时间窗口很短请求结束后TCP连接断开设备立刻变为离线。这是正常的不代表功能失败。如果要让设备保持在线需要做到两点之一定时保持TCP连接不要在每次请求结束后关闭socket。使用MQTT协议连接因为MQTT本质上是一个长连接协议心跳包会自动维持设备在线状态。如果源码包走的是HTTP方式那么你判断联调成功的指标应该是“平台收到数据点并且能画出折线图”而不是“设备永久在线”。5.3 坑三重量值突变或者乱跳这个问题要把锅分成两半一半是硬件问题一半是软件平滑不够。硬件方面称重传感器的屏蔽线必须单端接地传感器和HX711之间的连线尽量短。如果线缆过长且经过强电区采集到的ADC值会周期性跳动。软件方面不要直接使用单次读取值要采用滑动平均滤波或中位值平均滤波。我实测过连续采5次去掉最大值最小值取平均能滤掉绝大多数随机脉冲干扰但要注意保证滤波后数据的响应速度货车称重场景5-10Hz的输出频率足够。5.4 坑四晶振不起振程序根本跑不起来热词里有一条“stm32 晶振电容计算”看起来很专业实际上就是一块新手拦路石。如果代码烧录后开发板无反应首先怀疑外部8MHz晶振是否起振用示波器量X1引脚应该有正弦波。如果没示波器有更简单的排查路径把代码里的时钟源切到HSI内部时钟如果切换后程序能跑那基本是外部晶振电路问题检查晶振两个脚的负载电容是否匹配常见值是20pF到22pF。在调试阶段直接用内部HSI时钟也能跑只是串口波特率可能会稍微偏移不影响功能验证。6. 联调完成后的部署细节以及一些有价值的进阶方向联调完成只是第一步如果要把它真正部署到货场实地使用还需要做好几个缓一缓就能出大问题的细节。6.1 供电设计与系统级看门狗称重系统在货场使用电压波动和电磁干扰是常态因此供电最好做一个隔离。主控板和传感器建议采用独立DC-DC模块。另外如果系统一旦死机必须在几秒钟内自动恢复这就要在代码里启用IWDG独立看门狗。喂狗操作不要放在主循环的顶部应该放在关键任务完成之后例如某次上传逻辑执行完之后喂狗这样如果任务卡住看门狗就知道出问题了。6.2 本地数据缓存网络断了不能什么都丢在货场这种环境WiFi偶尔断一下太正常了。如果每次断网就丢数据等网络恢复后云端就会缺一段记录。进阶的方案是在SD卡或STM32片内Flash上建一个简易环形缓冲存储最近几百条重量记录每次上传失败时把数据写入缓冲连上网络后再补传。这样做不仅更专业巅峰时期的货物重量记录也不会缺失。6.3 把源码包跑通之后可以怎么扩展热词里还出现了“k210与stm32通讯”和“stm32鱼缸”这些相对较远的关键词。其实它们提示了一个方向这套代码框架不只是货车称重能用它几乎就是个“传感器采集MCU云平台”的万能模板。如果你愿意把HX711换成DHT11温湿度传感器把货车称重场景换成粮仓温湿度监测换了JSON里的数据流ID和界面展示逻辑完全复用。对于正在做毕业设计的朋友这是一个很大的加分项不用重新造轮子。6.4 源码包的版权与引用建议在文档里写清楚最后多说一句非技术的事情。如果你是参考网上公开源码包来做的项目建议在自己的文档里注明原始出处和基于哪一版代码修改因为很多源码包使用的开源协议要求保留版权声明。特别是如果后续要参加比赛或者公开发表引用不规范是一个潜在风险。做工程和做研究一样尊重来源会让自己少走很多弯路。这个项目算是“麻雀虽小五脏俱全”从传感器到云平台一整条链路下来硬件、软件、通讯、数据可视化全练到了。拿到源码包以后按上面的顺序一步一步来先本地显示再云端上传最后再调精度和稳定性基本不会跑偏。本文还有配套的精品资源点击获取
返回列表