从HX711到精准电子秤:DIY高精度称重系统全攻略
1. 项目缘起从“差不多”到“称得准”的执念不知道你有没有过这样的经历想给咖啡豆称重厨房秤的精度不够想给电子元件分装手头的电子秤最小量程又太大。市面上的成品秤要么是精度和量程难以兼得要么是功能单一无法满足一些DIY场景下的定制化需求。几年前我因为一个开源硬件项目需要一台能精确到0.1克、量程在500克以内的小台秤用来称量一些小批量的粉末材料。找了一圈要么太贵要么不准于是萌生了自己动手做一个的念头。这个念头最终落在了HX711这个芯片上。HX711是一款专为电子秤设计的24位模数转换器ADC它几乎成了DIY电子秤领域的“标配”。但“标配”并不意味着简单。从传感器选型、电路连接、代码校准到最后的稳定性和精度优化每一步都有不少门道。网上能找到的教程很多但要么过于简略只给个接线图和代码要么过于理论让人看得云里雾里。我花了相当一段时间踩了不少坑才让我的小台秤从“能显示数字”进化到“稳定可靠、值得信赖”。今天我就把自己从零开始制作一只基于HX711的小台秤的全过程包括那些教程里不会写的细节、容易翻车的点以及如何让读数更稳定的技巧完整地分享出来。无论你是刚接触Arduino的新手还是想深入了解传感器应用的老玩家这篇文章都能给你提供一个从原理到实践、可直接“抄作业”的完整方案。我们的目标是做一台成本可控、精度满意、并且真正理解其工作原理的称重工具。2. 核心部件深潜HX711与应变片称重传感器制作电子秤核心在于如何将“重量”这个物理量转化为单片机可以读取的“数字信号”。这个过程的主角有两个应变片称重传感器和HX711模数转换芯片。只有吃透它们后面的校准和调试才能有的放矢。2.1 应变片称重传感器力的“翻译官”我们常用的称重传感器内部核心是一个“金属弹性体”和贴在它上面的“电阻应变片”。你可以把它想象成一根微型的、非常坚硬的弹簧。当有重物压上去时弹性体会发生极其微小的形变可能是弯曲或拉伸。贴在上面的应变片是一种特殊的电阻其阻值会随着自身的形变被拉长或压缩而改变。通常我们会把四个这样的应变片连接成一个惠斯通电桥。电桥的巧妙之处在于当传感器不受力时电桥处于平衡状态输出电压为零。一旦受力应变片的阻值变化会打破这种平衡产生一个与所受压力成正比的、非常微弱的差分电压信号通常是毫伏级别。这里有一个关键点传感器的量程和灵敏度。常见的DIY传感器有1kg、5kg、10kg等。量程越小通常灵敏度越高单位重量引起的电压变化越大在小重量测量时相对精度可能更好。但量程小的传感器也更容易因过载而损坏。所以选择传感器时你的最大称重需求应该略小于传感器的额定量程留出一些余量。2.2 HX711芯片微弱信号的“放大镜”与“数字化仪”传感器输出的信号太微弱了而且伴随着各种噪声Arduino自带的ADC通常10位或12位根本无法有效分辨。这时就需要HX711登场。它的核心功能有两个可编程增益放大器PGAHX711内部集成了一个PGA增益可以设置为128或64。这意味着它能把传感器输出的毫伏级信号放大到伏特级别供后续电路处理。对于最常见的5V供电、1mV/V灵敏度的传感器通常选择128倍增益。高精度24位Σ-Δ ADC这是HX711的杀手锏。我们常见的Arduino ADC是10位2^101024个刻度而24位ADC的理论刻度数是2^2416,777,216个超高的分辨率意味着它能捕捉到信号极其细微的变化这是实现高精度称重的基础。Σ-ΔSigma-Delta架构则擅长通过过采样和数字滤波来抑制噪声提高信噪比。HX711与MCU如Arduino的通信方式非常简单是类似SPI的两线制串行通信DATA和SCK这大大简化了连线。它负责完成最困难的信号放大和模数转换然后以固定的速率默认10Hz或80Hz可选将转换好的24位数据准备好等待MCU来读取。一个重要的实操细节HX711芯片本身和其外围电路特别是基准电压的稳定性直接决定了测量的绝对精度。如果给HX711的供电VCC波动或者基准电压不干净那么即使传感器信号被完美放大转换最终结果也会漂移。因此在电路设计时给HX711的电源最好经过滤波并且尽量让传感器和HX711使用同一个稳定的电源以减少共模干扰。3. 硬件搭建全攻略从原理图到实体连接理解了核心部件我们就可以动手搭建硬件了。这部分我会给出清晰的接线图并解释每一根线的作用以及布线时需要注意的“玄学”问题。3.1 物料清单与选型建议主控板Arduino Uno。最通用资料最多引脚够用。当然Nano、Pro Mini等同样可以核心是具备数字IO口。称重模块HX711模块已焊接好芯片和必要外围电路。这是最省事的选择。模块通常已经将HX711的AVDD模拟电源和DVDD数字电源在内部连接并引出了VCC、GND、DT数据、SCK时钟、E、E-、A、A-这些引脚。称重传感器推荐使用“悬臂梁式”传感器通常是长方形金属块带固定孔和受力孔。量程根据需求选如500g或1kg。务必确认传感器是“四线制”还是“六线制”。四线制只有红E、黑E-、白A、绿A-六线制则多了两根 Sense 和 Sense-用于远端补偿DIY中通常短接到A和A-即可。我们的模块按四线制连接。显示设备I2C接口的LCD1602液晶屏。这是另一个极大简化连线的选择。传统的1602需要接一大堆线7根数据线3根控制线而I2C版本只需要4根线VCC、GND、SDA、SCL通过一个转接板驱动节省了宝贵的IO口。其他杜邦线公对公、母对母、一个稳定的5V电源如手机充电器USB线、用于放置称重平台的轻质坚固材料如亚克力板、螺丝螺母、一个面包板用于调试。3.2 电路连接详解与避坑指南连接遵循“电源-信号-显示”的顺序。下图是连接的逻辑示意图[5V电源]--------------------- | ----------------------------------------------- | | | V V V [HX711模块] [Arduino Uno] [I2C LCD] VCC --(红)-- 5V 5V --- 5V VCC -- 5V GND --(黑)-- GND GND --- GND GND -- GND DT --(绿)-- D2 A4 --- SDA SCK --(蓝)-- D3 A5 --- SCL E --(红)-- 传感器红 E- --(黑)-- 传感器黑 A- --(白)-- 传感器白 A --(绿)-- 传感器绿接线步骤与关键解释供电统一将5V电源的正极同时连接到Arduino的5V引脚、HX711模块的VCC、LCD的VCC。负极GND也同样全部共地。“共地”是保证所有设备参考电位一致的关键否则通信会混乱或失败。建议使用面包板的总线排来统一管理电源和地线。HX711与Arduino连接DT - D2 (Arduino的数字引脚2用于读取数据)SCK - D3 (Arduino的数字引脚3用于发送时钟脉冲)为什么是D2和D3其实很多库示例用这两个引脚它们可以是任何数字IO。但有些库的中断例程可能对引脚有要求跟随主流选择可以避免不必要的麻烦。HX711与传感器连接这是最容易接错的地方。模块和传感器通常都用红黑代表电源E, E-用绿白代表信号A, A-。但不同厂家的传感器颜色定义可能不同最稳妥的方法是查看传感器说明书或者用万用表测量通常红黑之间的电阻桥臂激励电阻约为400欧姆绿白之间的电阻信号输出电阻也约为350欧姆。如果接反了测量值会随重量增加而减小出现负数调换A和A-即可。I2C LCD与Arduino连接SDA - A4 (Arduino Uno的I2C数据线)SCL - A5 (Arduino Uno的I2C时钟线)注意I2C设备有地址通常默认是0x27或0x3F。如果屏幕不亮可能需要扫描地址并修改代码。可以使用专门的I2C扫描示例程序来查找地址。布线经验谈电源要干净如果使用电脑USB供电当电脑负载大时USB电压可能波动导致读数跳动。强烈建议使用独立的5V适配器供电。信号线要短HX711的DT和SCK线不宜过长最好在20厘米以内并避免与电源线平行走线以减少干扰。传感器固定是灵魂传感器必须被牢固地安装在底座上固定孔只有受力端另一个孔可以自由上下移动。任何微小的晃动或扭曲都会导致读数严重不准且不稳定。我常用L型角铝和螺丝来固定确保受力方向严格垂直于传感器平面。4. 软件核心库的选用、校准算法与稳定显示硬件搭好只是成功了一半软件的配置和校准才是赋予它“灵魂”的过程。这里涉及到库函数的使用、关键的校准流程以及如何让显示值变得稳定可靠。4.1 必备库安装与初始化我们需要两个库HX711_ADC和LiquidCrystal_I2C。前者是专门为HX711优化的库功能强大且稳定后者用于驱动I2C LCD。在Arduino IDE中通过“项目” - “加载库” - “管理库”搜索并安装它们。安装完成后在代码开头引入#include HX711_ADC.h #include Wire.h #include LiquidCrystal_I2C.h接下来是初始化对象。注意这里需要根据你的实际接线和LCD地址进行修改// HX711初始化 (DT pin, SCK pin) HX711_ADC LoadCell(2, 3); // I2C LCD初始化 (地址, 列数, 行数)。如果0x27不行请尝试0x3F。 LiquidCrystal_I2C lcd(0x27, 16, 2);在setup()函数中我们需要启动这些设备void setup() { Serial.begin(57600); // 用于调试输出 lcd.init(); // 初始化LCD lcd.backlight(); // 打开背光 LoadCell.begin(); // 启动HX711 // 重要启动后等待传感器稳定。放置500ms是个好习惯。 delay(500); // tare()函数用于去皮/归零。这里先执行一次清除启动时的偏移。 LoadCell.tare(); // 启动ADC转换使用128倍增益默认速率。 LoadCell.start(2000); // 参数2000表示等待稳定化的超时时间(ms) }4.2 校准流程获取那个关键的“比例因子”这是整个项目最核心的一步。HX711读取的是原始值raw value我们需要将它转换为重量值克或千克。转换公式很简单重量 (原始值 - 零点偏移) / 比例因子。零点偏移就是空载时的原始值通过tare()函数可以轻松设置。难就难在比例因子。它没有标准值每个传感器、每次安装都不同必须通过实验校准。标准校准步骤准备已知重量的砝码最好是标准砝码。如果没有可以用未开封的硬币如1元硬币约6g、标准包装的食盐如500g等作为参考。精度越高校准结果越好。编写并上传校准程序你可以使用HX711_ADC库自带的示例程序Calibration或者自己写一个简单的。核心逻辑是清空秤盘执行tare()归零。在串口监视器中提示用户放上已知重量的砝码。放上砝码后程序读取稳定的原始值然后根据公式比例因子 (稳定原始值 - 零点偏移) / 已知重量计算出比例因子。将这个比例因子保存下来比如存入EEPROM或直接硬编码到主程序中。一个更实用的“交互式校准”代码片段void calibration() { Serial.println(*** 校准流程开始 ***); Serial.println(请确保秤盘空载然后发送 t 进行去皮归零。); while (Serial.available() 0) {} if (Serial.read() t) { LoadCell.tare(); Serial.println(去皮完成。); } Serial.println(现在请放上已知重量的砝码单位克输入重量值后按回车。); while (Serial.available() 0) {} float knownWeight Serial.parseFloat(); // 读取用户输入的重量 Serial.println(正在读取数据...请保持稳定。); delay(4000); // 等待读数稳定 float rawValue LoadCell.getData(); // 获取当前原始值 float scaleFactor (rawValue - LoadCell.getTareOffset()) / knownWeight; Serial.print(计算出的比例因子为: ); Serial.println(scaleFactor, 6); // 打印6位小数 Serial.println(请将这个值更新到主程序的 LoadCell.setCalFactor() 函数中。); // 也可以在这里直接保存: LoadCell.setCalFactor(scaleFactor); }校准经验与陷阱多点校准如果追求更高线性度可以进行两点校准例如用100g和500g砝码取两个比例因子的平均值或者在量程范围内分段校准。环境温度传感器的输出会受温度影响。如果称重环境温度变化大可能需要考虑温度补偿但这对于大多数室内DIY应用可以忽略。砝码放置位置砝码应放在秤盘中心。偏载会导致传感器受力不均影响校准准确性。理想的秤盘应该通过一个“承压头”将力均匀传递到传感器的受力点。4.3 主循环与滤波让读数“沉稳”下来未经处理的原始数据往往是跳动的。我们需要在主循环loop()中做两件事更新数据和显示数据。void loop() { // 1. 更新HX711数据。update()函数会检查是否有新数据就绪并读取它。 LoadCell.update(); // 2. 每隔一定时间读取一次处理后的数据。getData()返回的是经过库内部平滑处理后的重量值。 if (millis() t 200) { // 每200ms更新一次显示避免刷新太快导致闪烁 t millis(); float weight LoadCell.getData(); // 单位取决于你校准用的单位 // 3. 可选附加自己的数字滤波。例如移动平均滤波。 // sum sum - readings[readIndex]; // 减去最旧的读数 // readings[readIndex] weight; // 存入新读数 // sum sum weight; // readIndex (readIndex 1) % numReadings; // weight sum / numReadings; // 计算平均值 // 4. 显示到LCD和串口 lcd.clear(); lcd.setCursor(0, 0); lcd.print(Weight: ); lcd.print(weight, 1); // 显示1位小数 lcd.print( g); Serial.print(重量: ); Serial.println(weight); } }关于滤波的深度建议HX711_ADC库内部已经做了不错的平滑处理。但如果你发现读数依然有轻微抖动可以额外添加软件滤波。移动平均滤波简单有效创建一个数组持续存储最近的N个读数每次显示时取平均值。N越大曲线越平滑但响应也越迟钝。对于台秤N5或10通常是个不错的起点。一个常见的“漂移”问题排查如果读数在空载时缓慢单向漂移持续变大或变小首先检查硬件电源是否稳定传感器是否受热安装结构是否有应力缓慢释放排除了硬件问题可以在软件中设置一个“零点跟踪”功能长时间空载且读数在极小范围内波动时自动执行一次tare()。但此功能要慎用避免在称重过程中误触发。5. 结构设计与精度提升从“能用”到“好用”一个精准的电子秤30%靠电路和代码70%靠机械结构。不合理的结构设计会引入误差、摩擦和晃动毁掉所有的软件努力。5.1 秤体结构设计思路我们的目标是让被称重物体的重力沿着设计路径毫无损耗且垂直地传递到传感器的受力点上。底座需要足够重、足够稳。可以用厚实的木板、金属板。目的是抑制整个秤体在称重时的微小晃动。传感器安装必须使用螺丝将传感器的固定端牢牢锁死在底座上。传感器本身不能有任何晃动或翘曲。承压与传力机构直接接触式简单在传感器的受力端螺丝孔上拧上一根垂直的螺丝杆。秤盘一块轻质平板如亚克力中心打孔套在螺丝杆上用螺母从上方轻轻锁住允许秤盘有微小活动空间但不会脱落。这种结构简单但可能因侧向力导致误差。浮动式连接推荐在传感器受力端和秤盘之间增加一个“球头连接件”或“自由关节”。例如在受力端螺丝上安装一个小钢珠秤盘底部对应位置做一个凹面。这样能保证力始终垂直传递即使秤盘放置物品时有点歪斜。这是专业秤的常见做法能极大改善偏载误差。秤盘要轻、要平、要刚性。重量轻可以增加有效称量范围。亚克力板、碳纤维板、轻质铝合金板都是好选择。外壳与保护为电路部分制作一个简单的外壳防止灰尘和触碰。在传感器和活动部件周围留出足够空间避免任何摩擦。5.2 精度影响因素与优化技巧温度补偿如果项目用于环境温度变化较大的场合如厨房传感器的输出会漂移。一个简单的方案是加入一个温度传感器如DS18B20记录下不同温度下的零点偏移和比例因子在代码中做插值补偿。但这属于进阶内容。电源噪声抑制在HX711模块的VCC和GND之间靠近芯片引脚处焊接一个10uF的钽电容和一个0.1uF的陶瓷电容可以很好地滤除电源噪声。软件去抖与阈值在显示逻辑中加入一个“死区”阈值。例如只有当重量变化超过0.05克时才更新显示这样可以消除最后一位数字的无意义跳动。多次测量取平均对于静态称重可以在物体放稳后连续采样10次数据去掉最大最小值后取平均作为最终结果输出。长期稳定性测试校准后放上一个标准砝码静置数小时甚至一天观察读数变化。如果漂移超出可接受范围回头检查机械结构的应力是否完全释放电源是否绝对稳定。6. 功能扩展与创意玩法基础功能实现后这个小台秤就成为了一个可编程的“力测量平台”可以玩出很多花样。6.1 添加按键与菜单通过连接几个按钮到Arduino可以实现去皮、单位切换克/盎司、校准模式进入、累计称重等功能。配合LCD可以制作简单的菜单系统。例如长按某个键进入校准模式短按去皮。6.2 数据记录与上传将Arduino换成NodeMCUESP8266或ESP32就可以接入Wi-Fi。称重数据可以实时上传到物联网平台如Blynk、ThingsBoard或者记录到SD卡中。你可以用它来做咖啡冲煮记录记录每次的咖啡粉重量和注水时间或者实验室的简易数据采集。6.3 超限报警与自动分拣结合一个蜂鸣器或LED可以设置重量上下限。当称重物品超重或不足时发出声光报警。更进一步配合一个舵机或电磁铁可以做成简单的自动分拣装置将不同重量区间的物品推入不同的容器。6.4 作为其他项目的输入设备这个称重单元可以集成到更大的项目中。比如一个自动调配营养土的机器根据配方称量不同土壤和肥料一个智能猫粮碗记录猫咪每次的进食量或者一个实验用的简易材料测试仪测量微小力的大小。7. 疑难杂症排查清单在制作过程中你几乎一定会遇到一些问题。下面是一个快速排查指南问题LCD屏幕不亮或乱码。检查I2C地址是否正确用扫描程序确认。接线是否牢固VCC GND SDA SCL。对比度电位器如果模块有是否调节合适。问题串口读数始终为0或固定值。检查HX711的DT和SCK线是否接反。传感器线序是否正确尝试调换A和A-。代码中begin()和start()函数是否被正确调用。用万用表测量传感器E和E-之间是否有5V左右电压。问题读数跳动非常剧烈几十上百克地跳。检查电源极大概率是电源功率不足或干扰太大。换用独立的5V适配器供电。检查所有GND是否可靠连接。HX711模块靠近电源处是否加了滤波电容。问题读数有规律地缓慢漂移例如每分钟变几克。检查机械结构传感器固定端是否真的紧固了秤盘或传力机构是否接触到了其他东西产生摩擦环境温度是否在剧烈变化传感器本身是否预热不充分通电后等待几分钟再校准和使用。问题放上重物后读数变小出现负数。检查传感器信号线A和A-接反了。调换它们即可。问题校准后重量显示值约为实际值的一半或两倍。检查校准用的砝码重量值在代码中是否输入正确。检查setCalFactor()和getData()的计算逻辑单位是否一致。制作一只自己的小台秤远不止是连接几根线、上传一段代码那么简单。它是一次对传感器技术、模拟电路、数字信号处理、机械结构乃至误差分析的微型综合实践。当你第一次放上砝码屏幕上稳定地显示出正确的数字时那种对物理世界进行精确量化的成就感是购买任何成品都无法替代的。希望这份详尽的指南能帮你绕开我当年走过的弯路顺利做出属于你自己的、既精准又可靠的称重工具。如果在制作中遇到新的问题不妨从电源、接地和机械结构这三个最基础的方面重新审视往往能发现问题的根源。