1. 项目概述与核心思路手头一堆新旧电池分不清哪个还有电、哪个该扔了用万用表一个个量太麻烦市面上成品电池测试仪功能又比较单一。作为一个常年折腾电子项目的爱好者我决定自己动手做一个。这个基于Arduino Nano的电池测试仪不仅能精确测量AA/AAA和9V电池的电压还能用一个直观的进度条图形来显示电量状态配合3D打印的外壳实用又好看。这个项目的核心其实是嵌入式开发里最基础也最重要的技能之一模拟信号的采集与处理。简单说就是让单片机Arduino Nano去“读懂”电池的电压这个连续变化的物理量。Arduino Nano内置了一个10位精度的模数转换器ADC它就像一把尺子能把0到5V之间的电压“量”出1024个刻度从0到1023。我们通过程序读取这个刻度值再通过一个简单的数学公式就能反推出实际的电压是多少。为了把结果展示出来我选用了一块16x2的I2C液晶屏它只需要两根信号线就能驱动大大简化了布线。整个项目从电路设计、3D建模打印外壳到焊接组装、编写调试代码是一个完整的DIY流程。无论你是想学习Arduino的ADC和I2C应用还是想拥有一个实用的桌面小工具这个项目都能给你带来收获。下面我就把从思路到实现的每一个细节包括我踩过的坑和总结的技巧毫无保留地分享出来。2. 硬件设计与元器件选型解析做一个测量仪器硬件是基础选对元器件事半功倍。我的设计目标是精准、安全、易用、美观。围绕这四点我们来拆解硬件方案。2.1 核心控制器为什么是Arduino Nano主控芯片的选择很多比如功能更强的ESP32或者更基础的STM32。但我最终选择了Arduino Nano原因有三点开发效率极高丰富的库和庞大的社区让I2C液晶屏驱动、ADC读取等操作变得异常简单几行代码就能跑起来可以把精力集中在应用逻辑上。尺寸与功耗平衡Nano板子小巧非常适合嵌入到自制仪器外壳中。同时其功耗在持续测量应用中可以接受可以通过USB供电非常方便。成本与易得性价格低廉货源充足对于DIY项目来说容错成本低。这里有个关键细节ADC参考电压的选择。Arduino Nano的ADC默认以板载的5V稳压输出作为参考电压AREF。这意味着ADC认为5V输入对应读数1023。这个5V的精度直接决定了电压测量的精度。如果USB供电电压波动测量结果就会漂移。因此在要求高的场合可以外接一个精准的基准电压源如TL431提供4.096V接到Nano的AREF引脚并在代码中设置analogReference(EXTERNAL)。本项目对精度要求是相对判断电池电量默认的5V参考已足够但心里要明白这个误差来源。2.2 信号输入与量程切换电路这是设计的核心直接关系到测量的准确性和设备的安全性。对于AA/AAA电池标称1.5V电压通常在0.9V耗尽到1.6V新电池之间。直接接入Nano的模拟输入引脚A0-A7是安全的因为这些引脚可承受0-5V电压。我选择将电池正极通过一个10kΩ的限流电阻连接到模拟引脚A0。这个电阻主要起保护作用防止意外短路或高压冲击损坏单片机ADC端口。负极则直接接GND。对于9V电池标称9V满电电压可达9.5V以上远超Nano引脚5V的耐受极限。绝对不能直接接入必须进行分压。我设计了一个由两个精密电阻组成的分压电路。假设我们使用R110kΩ上拉电阻R210kΩ下拉电阻那么分压比就是 R2/(R1R2) 1/2。一个9V的电池电压经过分压后送到A1引脚的电压约为4.5V落在了ADC的测量范围内。计算公式为V_a1 V_battery * (R2 / (R1R2))。注意分压电阻的精度直接影响测量结果。建议选用1%精度的金属膜电阻。同时为了降低对被测电池的影响分压电路的总阻值不宜过小否则会持续消耗电池电量。这里选择两个10kΩ电阻总阻值20kΩ对于9V电池静态电流约为0.45mA在可接受范围内。量程切换为了用一个设备测两种电池需要一个切换开关。我选用了一个小型的双刀双掷DPDT拨动开关。它的作用有两个物理切换被测电池开关一侧将AA/AAA电池接入A0通路另一侧将9V电池接入由A1检测的分压电路。提供数字信号给MCU开关的一个刀位连接到一个数字引脚我用了D2并启用内部上拉电阻。当拨到AA/AAA档时该引脚通过开关接地读到LOW拨到9V档时引脚被内部上拉至HIGH。这样程序就能自动判断当前正在测量哪种电池并选择对应的计算系数和显示量程。2.3 显示模块I2C LCD 1602为什么不用普通的并行LCD因为省线一个标准的1602液晶屏需要至少6根线4位数据模式来控制而I2C版本的只需要4根线VCC, GND, SDA, SCL。这极大简化了飞线焊接和PCB布局。模块上通常集成了一个PCF8574或类似的I2C转接芯片地址默认为0x27或0x3F。焊接与地址确认拿到I2C LCD模块后第一件事是焊接排针。然后可以通过一个简单的Arduino扫描程序来确认它的I2C地址这是后续驱动成功的关键。有时候地址可能不是标准的务必先确认。2.4 供电与结构设计供电整个系统功耗很低Arduino Nano和LCD都可以通过Micro USB口供电非常方便。这意味着测试仪可以连接电脑、充电宝或手机充电器工作。结构设计为了美观和耐用我设计了3D打印外壳。外壳分为三个部分底座内部有卡槽固定Nano主板和穿孔板底部有防滑脚垫。电池仓专门为AA/AAA电池设计了一个带弹簧触点的卡槽为9V电池设计了一个九宫格插槽。确保电池接触可靠是准确测量的前提。屏幕面板固定LCD屏幕并留有开口。面板与底座通过螺丝或卡扣结合。使用FDM 3D打印机如Creality Ender系列搭配PLA材料打印即可。设计时要注意留出足够的线材空间和散热孔。3. 软件原理与代码深度剖析硬件是骨架软件是灵魂。这段代码不长但每一行都有讲究。我们来逐部分拆解。3.1 库引入与初始化#include Wire.h #include LiquidCrystal_I2C.h LiquidCrystal_I2C lcd(0x27, 16, 2);Wire.h是Arduino的I2C通信库必须包含。LiquidCrystal_I2C.h是驱动I2C LCD的第三方库需要提前通过库管理器安装。初始化LCD对象时传入I2C地址0x27、列数16和行数2。如果你的模块地址不同务必修改此处。3.2 引脚定义与校准系数const int batteryPin A0; // AA/AAA电池测量引脚 const int batteryPin9V A1; // 9V电池分压后测量引脚 const int switchPin 2; // 量程切换开关引脚 const float FATT_CORR_AA_AAA 0.926; const float FATT_CORR_9V 0.924;引脚定义清晰便于管理。重点校准系数。FATT_CORR意大利语意为“校正因子”是本文项目的关键。为什么需要它因为理想公式电压 ADC读数 * (参考电压 / 1023)在实际电路中会有偏差。偏差来源包括Arduino Nano板载5V稳压器的实际输出并非精确的5.00V。分压电阻存在精度误差。ADC本身存在非线性误差和增益误差。如何得到这个系数你需要一个已知精确电压的源例如一个全新的1.5V电池或用万用表标定过的稳压电源接上电路读取ADC值然后用公式反向计算校准系数 真实电压 / (ADC读数 * (5.0 / 1023.0))。对于9V量程计算时还要乘以分压比。本项目作者通过实验得到了0.926和0.924这两个值。你必须对自己的硬件进行校准直接套用这两个值很可能不准。3.3 自定义字符与进度条原理代码中定义了一个5x8的字节数组customChars[5][8]用来创建5个自定义字符。观察这5个字符的二进制表示它们分别是字符0: 最左边一列填充1/5宽度字符1: 左边两列填充2/5宽度字符2: 左边三列填充3/5宽度字符3: 左边四列填充4/5宽度字符4: 全部五列填充5/5宽度即实心方块LCD的每个字符位是5像素宽、8像素高。通过组合这5个不同填充程度的字符我们就可以模拟出一个有80个“小段”16字符位 * 5像素/字符的平滑进度条。这比只用空格和实心方块显示要精细得多。3.4 主循环逻辑与电压计算loop()函数中的逻辑是核心读取开关状态digitalRead(switchPin)判断当前档位。读取ADC并计算电压AA/AAA档voltage analogRead(batteryPin) * (5 / 1023.0) * FATT_CORR_AA_AAA;公式解析analogRead()返回0-1023的值。(5 / 1023.0)是每个ADC数字量对应的电压值即分辨率。乘以校准系数得到最终电压。9V档voltage analogRead(batteryPin9V) * (5.0 / 1023.0) * 2 * FATT_CORR_9V;关键点是* 2。因为分压电路将电压减半所以计算实际电池电压时需要乘回2。公式推导V_actual V_a1 * ( (R1R2) / R2 ) V_a1 * 2。映射进度条长度int barSegments map(voltage * 1000, 0, (switchState LOW) ? 2000 : 10000, 0, 80);map()函数是Arduino的神器用于线性映射。voltage * 1000把以伏特为单位的电压如1.23V转换为毫伏1230方便计算。输入范围对于AA/AAA档switchState LOW输入范围是0-2000毫伏即0-2.0V留有余量。对于9V档是0-10000毫伏0-10.0V。输出范围映射到0-80对应进度条的总像素宽度16字符*5像素。绘制进度条通过循环在每个字符位判断需要填充多少个像素然后选择对应的自定义字符打印出来。算法巧妙地将barSegments0-80分解为若干个“5”和余数。显示电压值在第二行清空后打印计算出的电压值并附带单位和小量程标识“V*[1,5V]” 或 “V*[ 9V]”。4. 组装、焊接与调试全流程有了设计和代码接下来就是动手实现。这个过程最能体现一个项目的完成度。4.1 3D打印件后处理打印好的零件可能会有毛边或支撑残留。用美工刀和小锉刀仔细清理。特别是电池仓的触点孔位和屏幕面板的窗口务必保证光滑平整确保电池和屏幕能严丝合缝地安装进去。如果打印尺寸有微小偏差比如螺丝孔对不上可以用合适尺寸的钻头进行扩孔。4.2 电路焊接要点我建议在一块万孔板Perfboard上焊接所有元件而不是直接用杜邦线连接这样更稳固可靠。先规划布局在纸上或脑子里安排好Arduino Nano、LCD接口、开关、电池座接口在板子上的大致位置尽量使走线简短。先焊接矮元件首先焊接电阻、排针等较低的元件。电源与地线为板子规划好电源VCC和地GND的“主干道”。可以用较粗的导线或者利用万孔板背后的铜箔走线如果使用的是带覆铜的板子。确保所有需要供电的模块都能方便地连接到主干道上。信号线焊接按照原理图焊接信号线。I2C的SDA和SCL线可以并列走线。模拟信号线A0, A1尽量远离数字开关信号线D2和电源线以减少噪声干扰。开关焊接双刀双掷开关有6个引脚仔细对照数据手册或用万用表通断档判断引脚逻辑。确保拨动时能正确切换电池通路和数字信号。电池触点对于AA/AAA电池仓可以使用现成的弹簧触点焊接到板子上。对于9V电池扣直接焊接一个9V电池扣线即可。实操心得焊接时务必先断开所有电源。每焊接完一部分就用万用表检查一下通断和是否有短路特别是VCC和GND之间。养成“焊接-检查”的习惯能避免后续很多令人头疼的故障排查。4.3 系统集成与组装将焊接好的核心板用螺丝或热熔胶固定在底座内。将LCD屏幕安装到前面板并从背后用排线连接到核心板的I2C接口。将电池仓部件安装到底座上并将其触点引线焊接到核心板对应位置。将拨动开关安装到面板开孔处并固定。最后将面板与底座合拢用螺丝紧固。建议在合盖前给Arduino Nano的USB口开一个合适的槽位方便插拔。5. 校准、测试与性能优化组装完成通电但先别急着庆祝校准和测试才是保证仪器好用的关键。5.1 校准流程详解你需要一个可靠的参考基准最好是一台四位半的数字万用表。准备标准电压源对于1.5V量程找一节全新的、质量好的AA电池用万用表精确测量其开路电压记录为V_real例如1.621V。对于9V量程可以使用一个可调稳压电源调到9.00V用万用表监测或者用一个全新的9V电池电压通常在9.5V左右作为参考。获取原始ADC读数将标准源接入对应档位。修改代码在loop()中只读取并打印analogRead的原始值以及未校准的计算电压。通过串口监视器查看。等待读数稳定记录下平均的ADC原始值ADC_raw。计算校准系数对于AA/AAA档无分压FATT_CORR_AA_AAA V_real / (ADC_raw * (5.0 / 1023.0))对于9V档有分压 首先计算A1引脚的理论电压V_a1_theory V_real * (R2 / (R1R2))。假设R1R210k则V_a1_theory V_real / 2。 然后计算系数FATT_CORR_9V V_a1_theory / (ADC_raw * (5.0 / 1023.0))或者将两个步骤合并FATT_CORR_9V V_real / (ADC_raw * (5.0 / 1023.0) * 2)更新代码并验证将计算出的新系数替换代码中的旧值重新上传。再次测量标准源看显示电压是否与万用表读数基本一致误差在±0.01V~0.02V内可接受。5.2 功能测试与精度评估用几节不同状态的电池进行测试新电池AA/AAA应显示接近1.6V9V应显示9.5V以上。进度条应基本满格。旧电池电压会下降。当AA/AAA电池电压低于1.2V9V电池电压低于8.4V对于镍氢/碱性电池或7.2V对于锂离子9V电池时通常认为电量不足。进度条会明显缩短。空电池电压很低进度条可能只有一点点或没有。评估精度将你的测试仪读数与万用表读数在多个电压点上进行对比。记录下最大偏差。影响精度的主要因素有参考电压精度、分压电阻精度、ADC非线性度以及校准的仔细程度。5.3 软件优化与扩展思路基础功能完成后可以考虑以下优化软件滤波ADC读数会有微小波动。可以在代码中采用“滑动平均滤波法”。连续读取10次ADC值去掉最大最小值求剩余8次的平均值再用这个平均值计算电压。这能显著提高显示稳定性。// 示例简单的滑动平均滤波 const int numReadings 10; int readings[numReadings]; int readIndex 0; long total 0; int average 0; // 在loop中 total total - readings[readIndex]; // 减去最旧的读数 readings[readIndex] analogRead(pin); total total readings[readIndex]; // 加上最新的读数 readIndex (readIndex 1) % numReadings; average total / numReadings; // 用average代替analogRead(pin)进行计算低电量报警可以在进度条下方或旁边增加一个LED当电压低于设定阈值时点亮。或者让LCD背光闪烁。增加电池类型通过增加一个旋转编码开关和几组分压电阻可以扩展支持更多电池类型如3.7V锂离子、6V铅酸电池等。程序上需要增加一个档位判断和对应的分压比计算。内阻估算进阶通过测量电池空载电压和带一个已知负载如一个功率电阻时的电压可以粗略估算电池内阻从而更准确地判断电池的健康状态。这需要更复杂的电路和计算。6. 常见问题与故障排查实录做项目不可能一帆风顺以下是我在制作和调试过程中遇到的一些典型问题及解决方法希望能帮你快速排雷。问题现象可能原因排查步骤与解决方案LCD屏幕不亮或乱码1. I2C地址错误。2. 接线错误SDA/SCL接反或接触不良。3. 供电不足或电压不对。4. 对比度电位器未调节。1. 运行I2C扫描程序确认地址。2. 检查接线确保SDA接A4SCL接A5Arduino Nano。3. 用万用表测量VCC引脚电压是否为5V。4. 找到LCD模块背面的蓝色电位器用小螺丝刀微调直到显示清晰。电压读数始终为0或接近01. 电池未接通或触点氧化。2. 模拟输入引脚损坏或配置错误。3. 开关档位错误或开关损坏。4. 对于9V档分压电阻开路或虚焊。1. 检查电池安装是否到位用万用表测电池仓触点电压。2. 检查代码中引脚定义是否正确用analogRead读取其他已知电压如3.3V引脚测试ADC是否正常。3. 拨动开关用万用表通断档检查其逻辑是否正确切换。4. 检查分压电阻的焊接。电压读数偏差很大1.未校准或校准系数错误最常见。2. Arduino的5V参考电压不准USB供电波动。3. 分压电阻值误差大。1.严格按照第5.1节的流程重新校准这是解决问题的根本。2. 尝试使用外部稳压电源如手机充电器给Arduino供电避免使用电脑USB口电压可能不稳。3. 用万用表测量分压电阻的实际阻值计算分压比是否准确。进度条显示异常如缺块、闪烁1. 自定义字符未成功加载或加载顺序错误。2. 映射函数map的参数范围设置不当。3. 屏幕刷新逻辑有误未清空旧内容。1. 检查createChar的循环是否正确0-4。确保在setup()中执行。2. 打印barSegments的值到串口检查其是否在0-80的合理范围内。3. 检查绘制进度条前是否用空格清空了该行。切换档位时读数无变化1. 开关的数字信号引脚D2未正确配置INPUT_PULLUP。2. 开关接线错误导致电平无法变化。3. 程序逻辑判断有误。1. 确认代码中pinMode(switchPin, INPUT_PULLUP)已设置。2. 用万用表测量开关引脚电压拨动时看是否在HIGH(5V)和LOW(0V)间变化。3. 在代码中添加串口打印输出switchState的值确认判断逻辑。测量时电池发热或电量消耗快1. 分压电路总阻值过小导致静态电流过大。2. 输入端口意外短路。1. 检查9V分压电路。使用更大的电阻如两个47kΩ将静态电流降到0.1mA以下。2. 断电后仔细检查电路板排除任何可能的短路点。最后一点心得电子DIY的乐趣在于动手和思考。这个电池测试仪项目麻雀虽小五脏俱全涵盖了电源管理、信号调理、AD转换、人机交互和机械结构。当你亲手做出一个能精确测量、稳定显示的工具时那种成就感是无可替代的。最重要的是通过这个过程你真正理解了ADC读数、分压计算、校准这些概念不再是纸上谈兵。希望这个详细的分享能帮你顺利完成自己的作品。如果在制作中遇到新的问题不妨回到原理图和分析代码一步步排查这个过程本身也是极好的学习。