1. 项目概述:当传统秤遇上单片机
菜市场的电子秤、超市的收银台、实验室的分析天平——这些我们日常接触的称重设备,核心都是将压力信号转化为数字显示。而用单片机实现电子秤,正是嵌入式系统最典型的入门项目之一。这个设计不仅包含了传感器信号处理、模数转换、数据显示等基础环节,还能根据需求扩展蓝牙传输、数据存储等高级功能。
我十年前做的第一个单片机项目就是电子秤,当时用STC89C52配合HX711模块,在四位数码管上显示重量,虽然精度只能到10克,但那种"第一次让硬件按自己想法工作"的兴奋感至今难忘。现在回过头看,这个项目涵盖了嵌入式开发80%的基础技能点,特别适合电子类专业学生或单片机爱好者练手。
2. 核心硬件选型与电路设计
2.1 压力传感器:从应变片到模块化方案
称重核心在于压力传感器,常见的有金属应变片和成品模块两种选择:
- 应变片方案:成本低(5元以内)但需要搭建惠斯通电桥,要自己计算补偿电阻(公式:R_comp=R_nom×(ΔR/R)),对新手挑战较大
- 模块化方案:推荐HX711配套的称重传感器(约30元),已集成放大电路,直接输出差分信号
实测发现,铝合金悬臂梁传感器的线性度优于普通金属应变片。我在某次项目中对比过,同样量程5kg时,前者非线性误差<0.3%,后者可能达到1.5%。不过要注意安装方式——悬臂梁必须一端固定,另一端悬空承重,否则灵敏度会大幅下降。
2.2 单片机选型:资源与成本的平衡
根据功能复杂度可选择不同方案:
c复制// STC89C52 基础方案(成本<15元)
优点:资料丰富,IO口直驱数码管
缺点:无内置ADC,需外接HX711
// STM32F103 进阶方案(成本约25元)
优点:自带12位ADC,可做触摸屏交互
缺点:需要掌握ARM开发环境
去年帮学生调试时发现个细节:STC系列单片机在驱动4位数码管时,如果扫描频率低于100Hz会出现闪烁。解决方法要么提高定时器中断频率,要么改用TM1650这类专用驱动芯片。
2.3 信号调理电路设计要点
HX711模块虽然集成度高,但外围电路仍有讲究:
- 电源滤波:必须在VCC和GND间加104陶瓷电容(位置要靠近模块引脚)
- 基准电压:使用TL431提供2.5V基准比电阻分压更稳定
- 机械结构:传感器与承重板的连接要用弹性胶垫,避免侧向力影响
特别注意:HX711的采样速率选择(10SPS或80SPS)会影响噪声水平。称静态物品选10SPS,动态测量(如流水线)才需要80SPS。
3. 软件实现与算法优化
3.1 HX711驱动开发实战
HX711的通信时序要严格遵循手册要求。下面是经过验证的驱动程序片段:
c复制#define HX711_DOUT P1_0
#define HX711_SCK P1_1
long HX711_Read() {
unsigned long count = 0;
while(HX711_DOUT); // 等待模块准备就绪
for(int i=0; i<24; i++) {
HX711_SCK = 1;
count <<= 1;
HX711_SCK = 0;
if(HX711_DOUT) count++;
}
// 第25个脉冲选择增益和速率
HX711_SCK = 1;
count ^= 0x800000; // 补码转原码
HX711_SCK = 0;
return (long)(count/100); // 实测比例系数
}
调试中发现,SCK时钟线长度超过15cm会导致通信失败。建议用示波器观察时序,确保高低电平时间满足手册要求的0.2μs~50μs。
3.2 数字滤波算法对比
称重值需经过滤波处理,常用方法有:
- 滑动平均滤波:实现简单但响应慢
c复制#define FILTER_LEN 10 int filter_buf[FILTER_LEN]; int moving_avg(int new_val) { static int index = 0; filter_buf[index++] = new_val; if(index >= FILTER_LEN) index = 0; long sum = 0; for(int i=0; i<FILTER_LEN; i++) sum += filter_buf[i]; return sum/FILTER_LEN; } - 一阶滞后滤波:平衡响应速度与稳定性
c复制#define ALPHA 0.3f float last_value = 0; float low_pass(float new_val) { last_value = ALPHA*new_val + (1-ALPHA)*last_value; return last_value; }
实测在5kg量程下,滑动平均需要约2秒稳定,而一阶滞后仅需0.5秒。但后者在快速加载时会出现约20g的过冲,需要根据场景权衡。
3.3 校准流程设计
专业电子秤必须包含校准功能,建议实现三点校准:
- 零点校准:空载时执行,记录AD值作为基准
- 量程校准:加载已知重量(如500g砝码),计算系数K
- 线性校验:中间点验证(如250g位置)
校准数据应存入EEPROM。STC单片机可用IAP方式操作:
c复制void EEPROM_Write(uint addr, uchar dat) {
ISP_CONTR = 0x83; // 使能IAP
ISP_CMD = 0x02; // 写命令
ISP_ADDRH = addr>>8;
ISP_ADDRL = addr&0xFF;
ISP_DATA = dat;
ISP_TRIG = 0x46; // 触发命令
ISP_TRIG = 0xB9;
_nop_();
ISP_CONTR = 0; // 关闭IAP
}
4. 结构设计与误差控制
4.1 机械结构避坑指南
常见安装错误包括:
- 传感器受力不均(导致不同位置称重误差大)
- 外壳刚性不足(按压外壳会影响读数)
- 防过载设计缺失(超量程损坏传感器)
建议采用双层结构设计:下层固定传感器和电路板,上层为可拆卸承重台。两者之间用硅胶柱隔离振动,并在传感器周围加限位柱防止过载。
4.2 温度补偿实践
应变片灵敏度会受温度影响,补偿方法有:
- 硬件补偿:在电桥臂串联热敏电阻
- 软件补偿:建立温度-误差对照表
实验室环境下,未补偿的称重传感器温度漂移可达0.05%/℃。通过DS18B20采集环境温度后,用二次多项式补偿可将漂移控制在0.01%以内:
c复制float temp_compensate(float raw, float temp) {
static const float k2 = 0.00015f;
static const float k1 = -0.012f;
static const float k0 = 0.3f;
float delta = k2*temp*temp + k1*temp + k0;
return raw * (1 + delta/100);
}
5. 功能扩展与升级方向
5.1 无线传输实现方案
给电子秤增加蓝牙功能成本不到10元:
- HC-05模块与单片机通过UART连接
- Android端用MIT App Inventor快速开发配套APP
- 数据协议建议采用JSON格式:
json复制{ "weight": 1250, "unit": "g", "stable": true }
5.2 低功耗设计技巧
电池供电时需优化功耗:
- 动态调整HX711采样率(空闲时降至1SPS)
- 单片机进入掉电模式,用外部中断唤醒
- 关闭LED背光或采用分段点亮策略
实测表明,STC15系列在掉电模式下功耗可降至50μA,配合2000mAh锂电池可实现6个月待机。
6. 常见故障排查手册
根据多年维修经验整理典型问题:
| 故障现象 | 可能原因 | 解决方案 |
|---|---|---|
| 显示值跳动 | 电源干扰/机械振动 | 加强滤波/加固结构 |
| 空载不为零 | 传感器预紧力不足 | 重新调零/检查安装 |
| 称重值线性度差 | 传感器过载损坏 | 更换传感器/增加限位 |
| AD值读取不稳定 | 时序不符合HX711要求 | 用逻辑分析仪调试SCK信号 |
| 按键响应迟钝 | 消抖时间设置过长 | 调整消抖算法至20-50ms |
最近遇到个典型案例:某学生作品在开启手机充电器后称重值漂移,最终发现是开关电源的高频噪声通过地线耦合。在传感器供电端加装π型滤波器(100Ω+0.1μF)后问题解决。
7. 项目进阶建议
完成基础功能后,可以尝试:
- 改用24位ADC芯片(如ADS1232)提升精度
- 增加触摸屏实现菜谱热量计算
- 结合OpenCV实现图像识别自动计价
- 通过PID控制实现自动配料功能
记得第一次尝试触摸屏方案时,发现LCD刷新率会影响称重稳定性。后来改用双缓冲机制——称重线程最高优先级,显示线程低优先级,通过消息队列传递数据,这才实现流畅的交互体验。