☰
基于STM32的智能计价电子秤:从HX711称重到ESP8266联网全解析
2026/10/7 7:55:31 网站建设 项目流程

1. 从零到一:为什么我选择STM32而不是51来做这台计价秤

很多人第一次接触电子秤项目,脑子里蹦出来的方案就是51单片机加一个HX711模块,淘宝上几十块钱的散件包一抓一大把。我最早也是这么干的,用STC89C52搭了一版,能跑,但问题很快就暴露出来了:称重数据跳得厉害,按键响应迟钝,想加个蓝牙或者WiFi上传功能,资源直接捉襟见肘。后来我下定决心换成STM32平台重做,整个项目的体验才真正上了一个台阶。

这篇文章要聊的,就是基于STM32的智能计价电子秤从方案选型、硬件设计、驱动开发到功能联调的完整过程。核心关键词包括STM32、嵌入式、电子秤、HX711、ESP8266,适合有C语言基础、玩过一点单片机、想做一个能拿得出手的嵌入式项目的朋友。不管你是做毕业设计、课程设计,还是想给自己店里搞一台定制化的计价秤,这套方案都能直接参考。

先说清楚这台秤要干什么:放上物品,称出重量,输入单价,自动算出总价,显示在屏幕上;同时支持去皮、清零、单价修改;进阶一点,通过ESP8266把每笔称重记录传到云端或者手机端,方便做数据统计。听起来不复杂,但真正做起来,从ADC采样到滤波算法,从按键消抖到多任务调度,每一个环节都有坑。

为什么是STM32?我总结下来有三个硬理由。第一是ADC和定时器资源丰富,HX711虽然是外部24位ADC,但STM32的定时器可以用来做精确的采样节拍控制,这点比51强太多。第二是RAM和Flash够用,跑一个带菜单界面的UI、加上滤波算法和通信协议栈,51那点内存根本不够塞。第三是生态成熟,HAL库、标准库、各种开源驱动一搜一大把,开发效率高。当然,如果你只是做一个最基础的称重显示,51确实够用,但只要涉及到多任务、通信、复杂UI,STM32就是更合理的选择。

提示:选型不是越贵越好,而是要看你的功能边界。如果只是称重加数码管显示,51完全能胜任;一旦要加屏幕、要联网、要做数据记录,直接上STM32,别犹豫。

2. 硬件架构拆解:称重、主控、显示、通信四条线怎么走

2.1 称重模块:HX711与应变片的配合逻辑

电子秤的核心是称重传感器,也就是电阻应变式称重传感器。它的原理很简单:金属弹性体受力变形,贴在表面的应变片电阻值随之变化,四个应变片组成惠斯通电桥,输出一个微弱的差分电压信号。这个信号有多微弱?满量程输出通常只有1mV到2mV左右,直接拿STM32的ADC去采,根本分辨不出来。所以需要HX711这样的专用24位ADC来做前端放大和数字化。

HX711内部集成了低噪声可编程增益放大器,可选增益32、64、128。称重传感器一般用128增益,对应满量程差分输入±20mV。HX711的输出是24位二进制补码,通过两根线(SCK和DOUT)与主控通信,时序类似SPI但又不是标准SPI,需要自己写驱动。

这里有个关键参数需要算清楚:HX711的采样率。它有两个可选模式,10Hz和80Hz。10Hz模式下噪声更低,适合高精度静态称重;80Hz模式响应更快,但噪声会大一些。对于计价秤这种场景,我建议用10Hz,因为称重是一个相对静态的过程,精度比速度重要。如果你要做动态称重,比如传送带上快速过磅,那就得用80Hz甚至更高。

实际接线的时候,称重传感器的四根线要对应接好:激励正(E+)、激励负(E-)、信号正(S+)、信号负(S-)。不同厂家的传感器线色可能不一样,一定要看说明书,接反了不仅读不出数,还可能损坏传感器。HX711的AVDD和DVDD要分开供电,AVDD用干净的模拟电源,DVDD可以跟STM32的3.3V共用,但最好加磁珠隔离。

2.2 主控最小系统:STM32F103C8T6够不够用

我选的是STM32F103C8T6,也就是常说的“蓝板”核心芯片。72MHz主频,64KB Flash,20KB RAM,对于这个项目来说绰绰有余。最小系统包括晶振电路(8MHz外部晶振加两个22pF电容)、复位电路(10K上拉加100nF电容)、启动模式选择(BOOT0和BOOT1接地)、SWD调试接口。

电源部分要注意,STM32是3.3V供电,如果你用5V的USB供电,需要加一个LDO稳压芯片,比如AMS1117-3.3。HX711的DVDD也是3.3V,可以共用。但称重传感器的激励电压一般是5V,所以HX711的AVDD要用5V供电,这样传感器的输出信号范围才够大。

2.3 显示方案:OLED、LCD还是数码管

显示部分我试过三种方案。数码管最便宜,但只能显示数字,做计价秤的话要好几段才能显示重量、单价、总价,接线复杂,视觉效果也一般。LCD1602能显示字符,但分辨率太低,做不了好看的界面。最后我选了0.96寸OLED或者2.4寸TFT彩屏。

OLED用I2C接口,两根线搞定,显示效果清晰,功耗低,适合做小型便携秤。TFT彩屏用SPI接口,可以显示更丰富的信息,比如商品名称、单位、甚至简单的图标,适合做台式计价秤。如果你要做带触摸的,那就上带触摸控制器的TFT,但驱动复杂度会上升不少。

我个人的建议是:如果只是做基础版,0.96寸OLED足够;如果想做得好看一点、功能丰富一点,直接上2.4寸SPI TFT,驱动芯片一般是ILI9341或者ST7789,网上驱动代码很多,移植起来不费劲。

2.4 通信模块:ESP8266怎么接、怎么用

ESP8266是这个项目的联网核心。它本身是一个带WiFi功能的SoC,可以通过AT指令或者直接烧录固件来使用。我采用的是AT指令方案,STM32通过UART发送AT指令控制ESP8266连接路由器、连接服务器、发送数据。这样做的好处是STM32端的代码简单,不需要处理复杂的TCP/IP协议栈。

接线方面,ESP8266的TX接STM32的RX,RX接STM32的TX,注意电平匹配。ESP8266是3.3V电平,STM32也是3.3V,可以直接连。但ESP8266的供电一定要足,峰值电流能到300mA以上,如果用STM32板子上的3.3V LDO供电,很可能带不动,导致模块反复重启。我踩过这个坑,后来单独用一个AMS1117-3.3给它供电才稳定。

注意:ESP8266的CH_PD引脚要拉高才能正常工作,GPIO0悬空或者拉高进入运行模式。如果你要用AT固件,确保模块里烧录的是AT固件版本,不同版本的AT指令集有差异。

3. HX711驱动与称重滤波:从原始ADC值到稳定重量

3.1 HX711的时序驱动怎么写

HX711的通信时序不复杂,但时序要求比较严格。DOUT是数据输出脚,SCK是时钟输入脚。当DOUT为高电平时,表示数据还没准备好,需要等待;当DOUT变低,表示数据可以读取了。然后给SCK发送25到27个时钟脉冲,前24个脉冲读出24位数据,第25个脉冲选择下一次的增益和通道。

具体操作流程是这样的:先判断DOUT是否为低,如果是低,说明数据就绪;然后循环24次,每次把SCK拉高再拉低,读取DOUT的电平,组合成24位数据;最后再发一个脉冲,设置增益。读出来的24位数据是二进制补码形式,需要转换成有符号的32位整数。

这里有个细节:HX711的数据速率是10Hz或80Hz,意味着每100ms或12.5ms才更新一次数据。如果你在主循环里不停地读,大部分时间都在等待DOUT变低,效率很低。更好的做法是用定时器中断来触发读取,或者用外部中断检测DOUT下降沿。我一般用定时器,每100ms读一次,跟10Hz的采样率匹配。

// HX711读取一个24位数据的简化代码 int32_t HX711_Read(void) { int32_t value = 0; uint8_t i; while(HAL_GPIO_ReadPin(HX711_DOUT_GPIO_Port, HX711_DOUT_Pin) == GPIO_PIN_SET); for(i = 0; i < 24; i++) { HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); value = value << 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) value++; } 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); if(value & 0x800000) value |= 0xFF000000; return value; }

3.2 去皮、校准与线性度处理

拿到原始ADC值之后,第一步是去皮。所谓去皮,就是记录空秤时的ADC值作为零点,后续所有读数都减去这个零点值。但零点会漂移,尤其是温度变化的时候。所以我在程序里做了一个自动跟踪:当连续一段时间内重量读数都在零点附近波动时,缓慢更新零点值。

校准是称重精度的关键。我用的是两点校准法:先放一个已知重量的砝码,比如500g,记录ADC差值;再放另一个砝码,比如1000g,记录ADC差值。然后计算比例系数。公式很简单:重量 = (ADC值 - 零点值) / 比例系数。比例系数 = (ADC值2 - ADC值1) / (重量2 - 重量1)。

但实际做下来,线性度并不是完美的。传感器本身有非线性误差,HX711的增益也有温漂。如果要求高精度,可以做多点校准,用分段线性插值。对于一般的计价秤,两点校准加软件滤波已经够用了。

3.3 滤波算法:滑动平均、中值滤波还是卡尔曼

原始ADC值跳得厉害,必须滤波。我试过几种方案:

  • 滑动平均滤波:最简单,取最近N个采样值的平均。N越大越平滑,但响应越慢。我一般取10到20个点。
  • 中值滤波:取最近N个值的中位数,能有效去除脉冲噪声。但计算量比平均滤波大,需要排序。
  • 卡尔曼滤波:效果最好,但参数调起来麻烦,对于这个项目有点杀鸡用牛刀。

我最后用的是“中值滤波加滑动平均”的组合:先取5个点做中值滤波,去掉突变值;再取10个点做滑动平均,进一步平滑。实测下来,重量读数能稳定在±1g以内,对于计价秤来说完全够用。

还有一个技巧:在重量变化超过一定阈值时,重置滤波器,让系统快速响应。比如从空秤放上物品,重量从0跳到500g,如果还用旧的滤波数据,响应会很慢。我的做法是检测到重量突变超过50g时,清空滤波缓冲区,直接用当前值作为初始值。

提示:滤波窗口大小要根据你的采样率和响应要求来定。10Hz采样率下,20点滑动平均意味着2秒的响应延迟,对于计价秤来说有点慢。我一般用10点,1秒延迟,可以接受。

4. 计价逻辑与交互设计:按键、菜单、单价计算

4.1 按键扫描:非阻塞式设计

计价秤需要几个按键:去皮、清零、单价加、单价减、确认。如果用传统的延时消抖,主循环会被阻塞,影响称重采样。所以我用的是非阻塞式按键扫描,基于定时器中断,每10ms扫描一次按键状态,用状态机判断按下、释放、长按等事件。

具体实现是:每个按键维护一个计数器,检测到低电平时计数器加一,高电平时清零。当计数器达到一定值(比如3次,即30ms)时,确认按下。释放检测类似。长按检测则是按下后持续计数,超过一定时间(比如1秒)触发长按事件。

这种设计的好处是主循环不会被阻塞,称重采样和按键扫描可以并行。如果你用FreeRTOS,也可以把按键扫描放在一个独立任务里,优先级设低一点。

4.2 单价输入与总价计算

单价输入我用的是“位选加调整”的方式:按单价加/减键切换当前编辑的位数,按确认键进入下一位。比如单价是12.5元/公斤,先编辑十位,再编辑个位,再编辑小数位。这样只需要两个按键就能完成单价输入,节省IO口。

总价计算就是重量乘以单价。但要注意单位换算:称重传感器输出的是克,单价通常是元/公斤,所以要先除以1000。另外,金额显示一般保留两位小数,需要做四舍五入处理。

// 总价计算示例 float weight_kg = weight_g / 1000.0f; float total_price = weight_kg * unit_price; // 四舍五入到分 total_price = (int)(total_price * 100 + 0.5f) / 100.0f;

4.3 显示界面布局

显示界面我分了三行:第一行显示重量,第二行显示单价,第三行显示总价。如果是TFT彩屏,可以用不同颜色区分,重量用白色大字,单价用黄色,总价用绿色大字。OLED的话就用不同字体大小来区分。

刷新策略上,不需要每次循环都刷新屏幕,那样太浪费资源。我的做法是:重量变化超过1g、单价变化、总价变化时才刷新对应区域。这样屏幕刷新频率大大降低,视觉效果也更稳定。

5. ESP8266联网上传:从AT指令到数据上云

5.1 AT指令配置流程

ESP8266的AT指令配置有一套标准流程:先发AT测试通信,然后AT+CWMODE设置工作模式(Station模式),AT+CWJAP连接路由器,AT+CIPSTART建立TCP连接,AT+CIPSEND发送数据。每一步都要等待模块返回OK或者预期响应,超时要重试。

我踩过的一个坑是:AT指令的响应时间不固定,有时候几十毫秒,有时候几秒。如果用固定的延时等待,要么等太久影响效率,要么等太短导致失败。正确的做法是循环读取串口数据,检测到预期字符串就继续,超时才报错。

// 等待ESP8266响应 uint8_t ESP8266_WaitResponse(char *expected, uint32_t timeout) { uint32_t start = HAL_GetTick(); while(HAL_GetTick() - start < timeout) { if(ESP8266_CheckResponse(expected)) return 1; } return 0; }

5.2 数据格式设计与上传策略

上传的数据我用的JSON格式,包含时间戳、重量、单价、总价。时间戳可以用STM32的RTC,如果没有RTC就用开机后的毫秒数。JSON格式的好处是通用性强,服务端解析方便。

上传策略上,我采用的是“每笔称重完成后上传一次”。也就是说,当重量稳定并且用户确认后,触发一次上传。这样不会频繁发送数据,节省流量和功耗。如果网络断开,数据先存到本地Flash,等网络恢复后再补传。

5.3 网络异常处理与重连机制

网络异常是常态,必须处理好。我的做法是:每次上传前检查ESP8266的连接状态,如果TCP连接断了,先重连;如果WiFi断了,先重连WiFi。重连失败超过一定次数,就进入低功耗模式,每隔一段时间再试。

还有一个细节:ESP8266在发送数据时,如果数据量较大,需要分多次发送,每次等待模块返回“>”提示符后再发送下一段。这个流程要封装好,不然很容易丢数据。

注意:ESP8266的AT固件版本不同,指令集可能有差异。建议先用USB转TTL模块单独调试ESP8266,确认AT指令都能正常工作,再接到STM32上联调。

6. 调试过程中踩过的坑与排查思路

6.1 称重数据跳变:从电源到接地的完整排查

最开始调试的时候,重量读数跳得厉害,空秤时能在±50g范围内波动。我按以下顺序排查:

  1. 电源问题:先用示波器看HX711的AVDD和DVDD,发现AVDD上有明显的纹波。换了一个低噪声LDO,加了100uF和100nF的滤波电容,纹波明显减小。
  2. 接地问题:称重传感器的屏蔽线没有接地,导致引入干扰。把屏蔽线接到模拟地之后,跳变减小到±10g。
  3. 采样时序问题:HX711的SCK时钟太快,导致数据读取错误。降低SCK频率,确保每个脉冲宽度大于1us。
  4. 滤波参数问题:滤波窗口太小,平滑效果不够。增大到10点滑动平均后,读数稳定在±2g。

最后发现,最大的干扰源是ESP8266。ESP8266发射WiFi信号时会产生强烈的电磁干扰,影响HX711的模拟部分。解决办法是把ESP8266的天线远离HX711和传感器,并且在电源上做好隔离。

6.2 ESP8266连接超时:AT指令调试实录

ESP8266连接路由器时经常超时,报“AT+CWJAP”失败。排查过程:

  1. 确认路由器是2.4GHz频段,ESP8266不支持5GHz。
  2. 确认WiFi密码正确,注意大小写和特殊字符。
  3. 检查供电,发现用STM32板载LDO供电时,ESP8266启动瞬间电压跌落,导致重启。换成独立LDO后解决。
  4. 调整AT指令的超时时间,从5秒增加到15秒,给模块足够的连接时间。

还有一个隐藏问题:ESP8266的AT固件版本太老,不支持某些指令。用AT+GMR查看版本号,升级到较新的AT固件后,连接稳定性明显提升。

6.3 屏幕显示闪烁:刷新策略优化

TFT屏幕刷新时闪烁,原因是每次刷新都重绘整个屏幕。优化方法是只刷新变化的区域,并且用双缓冲机制。如果RAM不够,至少要做到局部刷新,不要全屏重绘。

另外,SPI时钟频率也会影响刷新效果。STM32F103的SPI最高到18MHz,但ILI9341的SPI时钟上限是10MHz左右,超频会导致显示异常。我一般设到9MHz,稳定可靠。

7. 项目扩展方向:从单机秤到智能称重终端

这台秤做完之后,我陆续加了一些扩展功能,让它从一个简单的计价秤变成了一个智能称重终端。

第一个扩展是数据记录与导出。在STM32上挂一个SD卡模块,用FatFS文件系统,把每笔称重记录写到CSV文件里。这样即使没有网络,数据也不会丢。SD卡用SPI接口,跟TFT屏幕共用SPI总线,通过片选信号区分。

第二个扩展是蓝牙打印。加一个HC-05蓝牙模块,连接热敏打印机,称重完成后直接打印小票。这个功能在生鲜店、熟食店特别实用。

第三个扩展是多传感器融合。比如同时接两个称重传感器,一个大量程用于粗称,一个小量程用于精称,通过软件切换。或者接一个超声波测距模块,测量物品体积,结合重量计算密度。

第四个扩展是云端数据看板。ESP8266上传的数据存到服务器,用简单的Web页面展示每日称重统计、销售额趋势等。这个需要一点后端开发,但用Python Flask或者Node.js很快就能搭起来。

如果你想把项目做得更“嵌入式”,可以尝试用FreeRTOS重构,把称重、显示、按键、通信分成独立任务,通过队列和信号量通信。这样代码结构更清晰,也更容易扩展。我后来用FreeRTOS重写了一版,称重任务优先级最高,通信任务优先级最低,系统运行非常稳定。

提示:扩展功能不要一次全加上,一个一个来,每加一个都充分测试。嵌入式项目最怕的就是功能堆太多,出了问题不知道是哪里的锅。

8. 关于元器件选型与成本控制的一些经验

做项目绕不开成本。我这台秤的物料清单大致是这样的:STM32F103C8T6核心板约10元,HX711模块约3元,5kg称重传感器约15元,0.96寸OLED约8元,ESP8266模块约10元,再加上按键、电阻电容、PCB板,总成本控制在60元以内。如果换成TFT彩屏,成本增加15元左右。

选型的时候有几个原则:第一,不要迷信进口芯片,国产替代方案现在很成熟,比如HX711就有很多国产兼容型号,性能差不多,价格便宜不少。第二,传感器是核心,不要在这上面省钱,劣质传感器的线性度和温漂会让你调试到崩溃。第三,电源芯片要选低噪声的,尤其是给模拟部分供电的LDO,纹波大了称重精度直接受影响。

PCB布局也有讲究。模拟部分和数字部分要分开布局,HX711尽量靠近称重传感器接口,走线要短且粗。晶振远离模拟区域,WiFi天线远离传感器。如果做双面板,底层尽量铺地,减少干扰。

最后说一句关于焊接的:HX711模块和传感器之间的连线,最好用屏蔽线,并且长度不要超过30cm。线太长会引入噪声,影响称重精度。如果必须长距离连接,考虑用差分信号传输或者加屏蔽驱动。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询