1. 项目概述与设计思路几年前我为了长途骑行时能随时知道水袋里还剩多少水用一堆分立元件主要是4060振荡器捣鼓出了一个水袋水位指示器。那玩意儿虽然能用但功能单一换个水袋就得重新调教实在不够灵活。去年计划去内蒙古来一趟山地车穿越我寻思着得升级一下装备于是第一版基于微控制器uC的水位计诞生了。它用单片机替代了大部分分立逻辑实现了水位分段显示和简单的校准功能算是迈出了一大步。今年趁着有空我又做了第二版。这次升级的核心目标是“极致精简”和“更低功耗”。最直观的改动就是干掉了那个独立的电源开关把我另一个项目里做的、基于PIC10F322的智能电源管理模块给整合了进来。现在整个设备就靠一个按钮来搞定所有操作开机、关机、功能选择、校准。PCB也重新布局了更紧凑。显示部分还是那三个高亮、低功耗的LED红、橙、绿但通过不同的闪烁组合能指示出多达6种水位状态从“水满”到“快没水了”的提醒更加细腻。这个项目的原理其实挺有意思的它没有用传统的浮子或压力传感器而是利用了水作为电介质的特性。在水袋外侧贴上两条平行的铜箔作为探测电极它们和水袋的塑料壁、内部的水共同构成了一个电容。这个电容的容量会随着水位升降而变化。我用一颗4060振荡器它的振荡频率与这个“水电容”相关。水位不同频率就不同。单片机PIC12F1572负责测量这个频率再换算成水位高度。这种非接触式测量最大的好处就是不污染饮用水也无需在水袋内部安装任何东西完全无损。为什么执着于用单片机重构分立元件方案就像搭积木每增加一个功能就要堆一堆电阻电容电路板大功耗也难以精细控制。而单片机是一个可编程的“大脑”所有逻辑水位判断、LED显示模式、按钮响应、电池检测、校准算法都通过软件实现。这样一来要修改功能、适配不同容量的水袋比如我跑步用的1升水袋和骑行用的2.5升水袋只需要改几行代码或者通过校准功能现场学习一下硬件完全不用动。这种灵活性对于DIY项目和产品迭代来说价值巨大。2. 硬件系统深度解析2.1 核心传感原理从“水电容”到频率信号整个系统的基石是如何把水位这个物理量变成单片机可以读取的电信号。我选择的是RC振荡测容法。2.1.1 “水电容”的构成与特性在水袋外壁粘贴两条铜箔带一条覆盖水袋下半部分约一半高度另一条从底部延伸到顶部。这两条铜箔就是电容的两个极板中间隔着水袋的绝缘塑料壁和内部的水。当水袋有水时水导电介质的存在会极大地改变两极板间的电场分布和等效介电常数从而显著增加电容量。水位越高被水“耦合”的极板有效面积越大电容值也就越大。这个方法的巧妙之处在于完全非接触传感器在外部绝不接触饮用水安全卫生。结构简单只需铜箔和胶带成本极低易于安装。线性度尚可对于柱状水袋电容变化与水位高度在一定范围内近似线性关系简化了标定。注意铜箔的粘贴工艺至关重要。必须确保铜箔与水袋外壁紧密贴合无气泡并且两条铜箔之间必须保持平行和恒定的间距。间距不均匀会导致电容基线值漂移影响测量一致性。我通常使用高粘性的电工胶带或专用的双面导电胶带先固定铜箔再在外面缠绕几圈绝缘胶带进行保护和加固。2.1.2 CD4060振荡电路设计CD4060是一个14级二进制串行计数器/分频器内部自带振荡器。我将其配置为一个RC振荡器其中“水电容”就是这个RC网络中的C。电路原理是4060的振荡频率f ≈ 1 / (2.2 * R * C)。这里R是一个固定的高精度电阻C就是我们的“水电容”与一个固定小电容的并联值。因此水位变化 → 水电容C变化 → 振荡频率f变化。单片机要做的就是测量这个频率。我选择让4060振荡后经过若干级分频输出一个较低频率的方波信号给单片机的输入捕捉或定时器引脚。这样做的好处是降低了单片机需要测量的频率减轻了计算负担也提高了在低功耗模式下测量的可行性。2.2 微控制器与电源管理架构第二版硬件上最核心的进化是采用了“双MCU”架构分工明确各司其职。2.2.1 主控MCUPIC12F1572这是系统的大脑负责所有核心业务逻辑频率测量通过定时器模块精确测量来自4060的方波信号周期。水位计算与映射将测得的周期值或频率值通过预存或校准得到的参数转换为具体的水位百分比或等级。LED显示驱动根据水位等级控制红、橙、绿三个LED呈现出“常亮”、“慢闪”、“快闪”等不同状态形成6级视觉指示。按钮扫描与功能处理管理唯一按钮的短按、长按等事件切换显示模式、进入校准菜单等。校准算法执行执行“满水校准”和“空满水校准”流程将当前传感器读数存储到单片机的非易失性存储器如EEPROM中。选择PIC12F1572的原因是其性价比高8引脚封装节省空间具备足够的定时器、中断资源和EEPROM且其在MikroC环境下的开发工具链我很熟悉。2.2.2 电源管理MCUPIC10F322这个来自我另一个独立项目的小芯片在本系统中扮演了“智能电源管家”的角色彻底取代了机械开关。软开关机长按按钮5秒PIC10F322检测到后会控制一个MOSFET开关接通或断开主电路PIC12F1572、4060、LED等的电源。电池电压监测它通过内部ADC定期测量电池电压。当主系统开机后如果收到查询指令它会将电池电量状态如“充足”、“中等”、“低电”反馈给主MCU由主MCU通过LED闪烁模式来提示用户。极致待机功耗在系统完全关机状态下只有PIC10F322的极小部分电路以极低功耗运行监听按钮长按事件。其自身功耗可控制在1微安以下使得电池放置数月也不会耗尽。这种设计将功耗最高的主系统与需要始终待命的开关/电量检测功能物理隔离实现了最优的能耗比。2.2.3 供电与LED选型电池选用一枚小型可充电的100mAh锂聚合物电池。对于这个主要工作在间歇唤醒模式每10秒测量一次的系统来说足以提供数十小时的连续显示时间。在待机关机状态下功耗几乎可忽略不计。LED特意选用了高发光效率、低工作电流的型号。在驱动时单片机引脚输出高电平通过一个限流电阻通常几百欧姆点亮LED。通过PWM或控制亮灭时间可以进一步降低平均电流。实测每个LED在点亮时电流控制在2-3mA在闪烁模式下平均电流更低。3. 软件逻辑与实操流程3.1 主程序状态机与低功耗策略整个软件的核心是一个清晰的状态机围绕低功耗设计。3.1.1 主循环与睡眠模式程序上电初始化后进入主循环。其基本节奏由看门狗定时器WDT设定我将其调整为大约10秒。流程如下唤醒与测量单片机从睡眠模式被WDT超时唤醒。传感器读数立即对4060输出的频率信号进行测量。为了抗干扰通常会连续采样多次取平均。水位计算与显示根据校准参数将平均频率值转换为水位等级0-5级。然后更新LED的显示状态。例如水位80%为“绿灯常亮”50%-80%为“绿灯闪烁”30%-50%为“橙灯常亮”等等。按钮检测快速扫描一次按钮状态。如果没有按下单片机清理现场再次进入睡眠模式等待下一个10秒周期。按钮处理如果检测到按钮按下单片机则保持唤醒状态执行更复杂的按钮事件处理程序防抖、识别短按/长按并可能进入功能菜单模式。这种“工作-睡眠-工作”的间歇模式是电池供电设备长寿的关键。99%的时间系统都在深度睡眠中只有定时器、看门狗和维持SRAM的电路在运行电流可能只有几十微安。3.1.2 按钮多功能复用逻辑只有一个按钮要实现开关机、模式切换、校准确认等多种功能全靠“时间长短”和“上下文”来区分。在关机状态下长按 5秒电源管理MCU动作开启主系统电源。此功能由PIC10F322固件实现在开机显示状态下短按 (1秒)切换显示模式。例如第一次短按显示电池电量LED以特定颜色闪烁表示电量第二次短按返回水位显示。长按 (3-5秒)进入校准菜单。此时LED可能会以某种组合闪烁提示进入菜单模式。在校准菜单状态下短按在不同校准选项间切换如“空水袋校准”、“满水袋校准”、“恢复出厂设置”。长按确认并执行当前选中的校准选项完成后保存数据并退出菜单。所有按钮处理都需加入软件防抖通常延时20-50毫秒再判断状态并且长按计时要准确。3.2 校准功能实现详解校准功能是这个设计灵活性的体现使得同一个硬件可以适配不同形状、容量、甚至不同材质水袋。3.2.1 单点满水校准这是最简单的校准方式适用于对“空”状态精度要求不高但需要准确知道“满”的状态。将水袋完全灌满确保探测区域被水覆盖。长按按钮进入菜单选择“Full Calibration”。系统会提示如绿灯快闪此时再次长按确认。单片机读取当前的频率值F_full并将其存入EEPROM。此后系统将认为频率值 F_full或在一个很小的误差范围内时即为100%满水。3.2.2 空满两点校准这是更精确的方法能建立水位与频率的线性映射关系。空水袋校准将水袋完全排空、晾干内部无水滴。进入“Empty Calibration”模式并确认。单片机记录频率值F_empty。这个值对应0%水位或一个很小的基底值。满水袋校准完成空校准后灌满水袋进行“Full Calibration”。记录频率值F_full。线性插值单片机将F_empty和F_full存入EEPROM。在实际测量中测得当前频率F_current通过以下公式计算水位百分比水位百分比 (F_current - F_empty) / (F_full - F_empty) * 100%然后根据百分比映射到0-5的显示等级。实操心得两点校准时务必保证“空”状态是真正干燥的。残留的水珠会导致F_empty偏大从而在低水位段产生较大误差。我通常会在空校准前向水袋吹气并静置几分钟确保内部干燥。另外校准最好在水袋处于使用时的典型姿态如直立挂在背包里下进行因为水袋形状不规则姿态不同可能导致水位分布略有差异。3.2.3 参数重置这个功能用于恢复出厂预设的校准参数或者当用户觉得当前校准数据有误时使用。执行后单片机将EEPROM中的F_empty和F_full替换为程序编译时预设的默认值。3.3 开发环境与代码要点我使用MikroC for PIC进行开发。这是一款针对PIC单片机的C语言集成开发环境编译效率高库函数丰富对于快速原型开发非常友好。代码结构关键点中断服务程序尽可能简洁只做标志位设置。例如定时器溢出中断用于频率测量计时外部中断用于唤醒或按钮边沿检测。模块化将功能分解为独立模块如sensor.c/h频率测量、led.c/h显示驱动、button.c/h按键处理、eeprom.c/h参数存储。功耗管理在进入睡眠前确保所有未用的外设模块ADC、比较器等都已关闭IO口设置为输出低电平或输入带上拉避免悬空耗电。EEPROM操作对校准参数的读写要小心。写入前先检查数据是否已改变避免不必要的擦写EEPROM有写入次数限制。重要参数可以存储两份并加校验和防止数据损坏。4. 制作、调试与问题排查4.1 PCB设计与外壳制作第二版我重新设计了PCB主要改进是整合电源管理将PIC10F322及其周边电路与主电路集成在同一块板上减少了连接器和飞线。优化布局将4060振荡电路部分靠近板边接口减少传感信号走线长度降低干扰。电源滤波电容靠近两个MCU的VDD引脚放置。增加编程接口为两个PIC分别预留了ICSP在线串行编程接口。这样在焊接完成后可以分别对它们烧录和调试固件。小型化使用更小封装的阻容元件将板子尺寸控制在比一枚硬币略大的范围。外壳我用3D打印制作。设计了一个简单的上下盖结构用螺丝固定。外壳正面为三个LED开了透光孔侧面为按钮开了孔背面留有槽位用于穿过连接铜箔的导线。文件我已经开源大家可以根据自己的打印机和喜好进行优化比如做成卡扣式免螺丝或者增加防水胶圈槽位。4.2 系统调试与实测调试分步骤进行4.2.1 电源管理部分调试先单独给PIC10F322部分供电测试长按按钮是否能可靠控制MOSFET开关。用万用表测量输出端电压。测试其ADC电池检测功能通过调试器读取ADC值验证其在不同输入电压下的读数是否准确。4.2.2 传感与主控部分调试给主系统上电不接水袋探头。用示波器观察4060的振荡输出引脚应该能看到一个固定频率的方波此时C仅为板上的固定小电容。编写一个简单的测试程序让PIC12F1572测量这个固定频率并每秒通过LED闪烁次数发送出来或用调试口打印验证频率测量功能正常。连接水袋探头这是最关键的一步。将两条铜箔导线连接到板子对应接口。准备一个透明水杯将贴有铜箔的水袋片或直接用铜箔贴在杯外浸入水中。观察频率变化缓慢向杯中注水同时用示波器观察4060输出频率或用调试程序读取单片机计算出的频率值。应该能看到频率随着水位上升而单调变化通常是降低因为电容增大频率减小。记录下空杯和满杯时的频率值这就是你后续校准的参考。4.2.3 系统联调与功能验证烧录完整固件组装好设备。测试基本显示给水袋加满水看是否显示“绿灯常亮”。慢慢放水观察LED状态是否按预设顺序平滑变化绿闪 - 橙常 - 橙闪 - 红常 - 红闪。测试按钮功能逐一测试短按切换显示模式如水切换到电量长按进入和退出校准菜单。执行校准严格按照“空满两点校准”流程操作一次然后再次测试水位显示准确性。功耗测试使用万用表电流档串联在电池回路中分别测量设备在“显示瞬间”、“睡眠期间”和“完全关机”状态下的电流。确保睡眠电流在几十微安级别关机电流在几微安以下。4.3 常见问题与排查技巧在实际制作和测试中你可能会遇到以下问题问题现象可能原因排查步骤与解决方案LED完全不亮1. 电池没电或接反。2. 电源管理MCU未开机或损坏。3. 主MCU未正常工作。1. 检查电池电压确认极性。2. 测量电源管理MCU输出端是否有电压。检查其编程和焊接。3. 检查主MCU电源、复位电路尝试用编程器连接看能否识别。LED显示状态混乱不随水位变化1. 探头铜箔接触不良或短路。2. 4060振荡电路不起振或频率异常。3. 单片机频率测量程序有bug。4. 校准数据错误或丢失。1. 用万用表测量探头两线间电阻无水时应为无穷大检查焊接。2. 用示波器直接观察4060振荡输出引脚看是否有波形波形频率是否随水位变化。3. 用调试器单步执行或打印中间变量检查定时器捕获值是否正确。4. 进入校准菜单重新执行两点校准。检查EEPROM读写函数。水位显示跳变不稳定1. 电源噪声干扰。2. 探头信号受干扰如靠近电源线。3. 软件滤波算法不够强。4. 水袋内有气泡或水流晃动。1. 在MCU的VDD和GND之间靠近引脚处增加一个0.1uF的陶瓷去耦电容。2. 将探头导线绞合在一起或使用屏蔽线远离电源部分。3. 增加软件采样次数或采用中位值平均滤波等算法。4. 这是物理限制可在软件中增加“变化率限制”或“迟滞”处理避免因短暂晃动导致显示频繁跳变。静置后读数应稳定。电池电量显示不准1. PIC10F322的ADC参考电压不准。2. 电池电压检测分压电阻精度不够或温漂大。3. 电量百分比映射关系不合理。1. 检查MCU的VREF配置或使用外部基准。2. 使用1%精度的金属膜电阻。测量实际分压电压与计算值是否一致。3. 针对使用的锂电池实测其放电曲线建立电压-电量的对应表而非简单线性计算。按钮操作不灵敏或误触发1. 按钮硬件消抖不足。2. 软件防抖延时设置不当。3. 长按/短按判断阈值不合理。1. 在按钮两端并联一个0.1uF电容进行硬件消抖。2. 调整软件防抖延时时间通常20-50ms为宜。3. 根据实际手感调整长按判定时间如从3秒调到2秒或4秒。最后一点个人体会这种基于电容感应的项目其稳定性和准确性非常依赖于外部环境的一致性。水袋的材质、厚度、铜箔的粘贴牢固度、甚至环境湿度都会对基线电容值产生微小影响。因此定期校准是一个好习惯尤其是在更换水袋或经历剧烈环境变化如从干燥室内到潮湿户外后。这个项目的乐趣不在于追求实验室级别的精度而在于用简单的原理和巧妙的设计可靠地解决一个实际户外需求。当你骑行在荒野中不用取下背包回头瞥一眼肩带上闪烁的LED颜色就能对剩余水量心中有数时那种感觉正是DIY最大的成就感所在。
基于电容传感与MCU的低功耗水位计DIY:从原理到户外实践
发布时间:2026/5/26 4:59:32
1. 项目概述与设计思路几年前我为了长途骑行时能随时知道水袋里还剩多少水用一堆分立元件主要是4060振荡器捣鼓出了一个水袋水位指示器。那玩意儿虽然能用但功能单一换个水袋就得重新调教实在不够灵活。去年计划去内蒙古来一趟山地车穿越我寻思着得升级一下装备于是第一版基于微控制器uC的水位计诞生了。它用单片机替代了大部分分立逻辑实现了水位分段显示和简单的校准功能算是迈出了一大步。今年趁着有空我又做了第二版。这次升级的核心目标是“极致精简”和“更低功耗”。最直观的改动就是干掉了那个独立的电源开关把我另一个项目里做的、基于PIC10F322的智能电源管理模块给整合了进来。现在整个设备就靠一个按钮来搞定所有操作开机、关机、功能选择、校准。PCB也重新布局了更紧凑。显示部分还是那三个高亮、低功耗的LED红、橙、绿但通过不同的闪烁组合能指示出多达6种水位状态从“水满”到“快没水了”的提醒更加细腻。这个项目的原理其实挺有意思的它没有用传统的浮子或压力传感器而是利用了水作为电介质的特性。在水袋外侧贴上两条平行的铜箔作为探测电极它们和水袋的塑料壁、内部的水共同构成了一个电容。这个电容的容量会随着水位升降而变化。我用一颗4060振荡器它的振荡频率与这个“水电容”相关。水位不同频率就不同。单片机PIC12F1572负责测量这个频率再换算成水位高度。这种非接触式测量最大的好处就是不污染饮用水也无需在水袋内部安装任何东西完全无损。为什么执着于用单片机重构分立元件方案就像搭积木每增加一个功能就要堆一堆电阻电容电路板大功耗也难以精细控制。而单片机是一个可编程的“大脑”所有逻辑水位判断、LED显示模式、按钮响应、电池检测、校准算法都通过软件实现。这样一来要修改功能、适配不同容量的水袋比如我跑步用的1升水袋和骑行用的2.5升水袋只需要改几行代码或者通过校准功能现场学习一下硬件完全不用动。这种灵活性对于DIY项目和产品迭代来说价值巨大。2. 硬件系统深度解析2.1 核心传感原理从“水电容”到频率信号整个系统的基石是如何把水位这个物理量变成单片机可以读取的电信号。我选择的是RC振荡测容法。2.1.1 “水电容”的构成与特性在水袋外壁粘贴两条铜箔带一条覆盖水袋下半部分约一半高度另一条从底部延伸到顶部。这两条铜箔就是电容的两个极板中间隔着水袋的绝缘塑料壁和内部的水。当水袋有水时水导电介质的存在会极大地改变两极板间的电场分布和等效介电常数从而显著增加电容量。水位越高被水“耦合”的极板有效面积越大电容值也就越大。这个方法的巧妙之处在于完全非接触传感器在外部绝不接触饮用水安全卫生。结构简单只需铜箔和胶带成本极低易于安装。线性度尚可对于柱状水袋电容变化与水位高度在一定范围内近似线性关系简化了标定。注意铜箔的粘贴工艺至关重要。必须确保铜箔与水袋外壁紧密贴合无气泡并且两条铜箔之间必须保持平行和恒定的间距。间距不均匀会导致电容基线值漂移影响测量一致性。我通常使用高粘性的电工胶带或专用的双面导电胶带先固定铜箔再在外面缠绕几圈绝缘胶带进行保护和加固。2.1.2 CD4060振荡电路设计CD4060是一个14级二进制串行计数器/分频器内部自带振荡器。我将其配置为一个RC振荡器其中“水电容”就是这个RC网络中的C。电路原理是4060的振荡频率f ≈ 1 / (2.2 * R * C)。这里R是一个固定的高精度电阻C就是我们的“水电容”与一个固定小电容的并联值。因此水位变化 → 水电容C变化 → 振荡频率f变化。单片机要做的就是测量这个频率。我选择让4060振荡后经过若干级分频输出一个较低频率的方波信号给单片机的输入捕捉或定时器引脚。这样做的好处是降低了单片机需要测量的频率减轻了计算负担也提高了在低功耗模式下测量的可行性。2.2 微控制器与电源管理架构第二版硬件上最核心的进化是采用了“双MCU”架构分工明确各司其职。2.2.1 主控MCUPIC12F1572这是系统的大脑负责所有核心业务逻辑频率测量通过定时器模块精确测量来自4060的方波信号周期。水位计算与映射将测得的周期值或频率值通过预存或校准得到的参数转换为具体的水位百分比或等级。LED显示驱动根据水位等级控制红、橙、绿三个LED呈现出“常亮”、“慢闪”、“快闪”等不同状态形成6级视觉指示。按钮扫描与功能处理管理唯一按钮的短按、长按等事件切换显示模式、进入校准菜单等。校准算法执行执行“满水校准”和“空满水校准”流程将当前传感器读数存储到单片机的非易失性存储器如EEPROM中。选择PIC12F1572的原因是其性价比高8引脚封装节省空间具备足够的定时器、中断资源和EEPROM且其在MikroC环境下的开发工具链我很熟悉。2.2.2 电源管理MCUPIC10F322这个来自我另一个独立项目的小芯片在本系统中扮演了“智能电源管家”的角色彻底取代了机械开关。软开关机长按按钮5秒PIC10F322检测到后会控制一个MOSFET开关接通或断开主电路PIC12F1572、4060、LED等的电源。电池电压监测它通过内部ADC定期测量电池电压。当主系统开机后如果收到查询指令它会将电池电量状态如“充足”、“中等”、“低电”反馈给主MCU由主MCU通过LED闪烁模式来提示用户。极致待机功耗在系统完全关机状态下只有PIC10F322的极小部分电路以极低功耗运行监听按钮长按事件。其自身功耗可控制在1微安以下使得电池放置数月也不会耗尽。这种设计将功耗最高的主系统与需要始终待命的开关/电量检测功能物理隔离实现了最优的能耗比。2.2.3 供电与LED选型电池选用一枚小型可充电的100mAh锂聚合物电池。对于这个主要工作在间歇唤醒模式每10秒测量一次的系统来说足以提供数十小时的连续显示时间。在待机关机状态下功耗几乎可忽略不计。LED特意选用了高发光效率、低工作电流的型号。在驱动时单片机引脚输出高电平通过一个限流电阻通常几百欧姆点亮LED。通过PWM或控制亮灭时间可以进一步降低平均电流。实测每个LED在点亮时电流控制在2-3mA在闪烁模式下平均电流更低。3. 软件逻辑与实操流程3.1 主程序状态机与低功耗策略整个软件的核心是一个清晰的状态机围绕低功耗设计。3.1.1 主循环与睡眠模式程序上电初始化后进入主循环。其基本节奏由看门狗定时器WDT设定我将其调整为大约10秒。流程如下唤醒与测量单片机从睡眠模式被WDT超时唤醒。传感器读数立即对4060输出的频率信号进行测量。为了抗干扰通常会连续采样多次取平均。水位计算与显示根据校准参数将平均频率值转换为水位等级0-5级。然后更新LED的显示状态。例如水位80%为“绿灯常亮”50%-80%为“绿灯闪烁”30%-50%为“橙灯常亮”等等。按钮检测快速扫描一次按钮状态。如果没有按下单片机清理现场再次进入睡眠模式等待下一个10秒周期。按钮处理如果检测到按钮按下单片机则保持唤醒状态执行更复杂的按钮事件处理程序防抖、识别短按/长按并可能进入功能菜单模式。这种“工作-睡眠-工作”的间歇模式是电池供电设备长寿的关键。99%的时间系统都在深度睡眠中只有定时器、看门狗和维持SRAM的电路在运行电流可能只有几十微安。3.1.2 按钮多功能复用逻辑只有一个按钮要实现开关机、模式切换、校准确认等多种功能全靠“时间长短”和“上下文”来区分。在关机状态下长按 5秒电源管理MCU动作开启主系统电源。此功能由PIC10F322固件实现在开机显示状态下短按 (1秒)切换显示模式。例如第一次短按显示电池电量LED以特定颜色闪烁表示电量第二次短按返回水位显示。长按 (3-5秒)进入校准菜单。此时LED可能会以某种组合闪烁提示进入菜单模式。在校准菜单状态下短按在不同校准选项间切换如“空水袋校准”、“满水袋校准”、“恢复出厂设置”。长按确认并执行当前选中的校准选项完成后保存数据并退出菜单。所有按钮处理都需加入软件防抖通常延时20-50毫秒再判断状态并且长按计时要准确。3.2 校准功能实现详解校准功能是这个设计灵活性的体现使得同一个硬件可以适配不同形状、容量、甚至不同材质水袋。3.2.1 单点满水校准这是最简单的校准方式适用于对“空”状态精度要求不高但需要准确知道“满”的状态。将水袋完全灌满确保探测区域被水覆盖。长按按钮进入菜单选择“Full Calibration”。系统会提示如绿灯快闪此时再次长按确认。单片机读取当前的频率值F_full并将其存入EEPROM。此后系统将认为频率值 F_full或在一个很小的误差范围内时即为100%满水。3.2.2 空满两点校准这是更精确的方法能建立水位与频率的线性映射关系。空水袋校准将水袋完全排空、晾干内部无水滴。进入“Empty Calibration”模式并确认。单片机记录频率值F_empty。这个值对应0%水位或一个很小的基底值。满水袋校准完成空校准后灌满水袋进行“Full Calibration”。记录频率值F_full。线性插值单片机将F_empty和F_full存入EEPROM。在实际测量中测得当前频率F_current通过以下公式计算水位百分比水位百分比 (F_current - F_empty) / (F_full - F_empty) * 100%然后根据百分比映射到0-5的显示等级。实操心得两点校准时务必保证“空”状态是真正干燥的。残留的水珠会导致F_empty偏大从而在低水位段产生较大误差。我通常会在空校准前向水袋吹气并静置几分钟确保内部干燥。另外校准最好在水袋处于使用时的典型姿态如直立挂在背包里下进行因为水袋形状不规则姿态不同可能导致水位分布略有差异。3.2.3 参数重置这个功能用于恢复出厂预设的校准参数或者当用户觉得当前校准数据有误时使用。执行后单片机将EEPROM中的F_empty和F_full替换为程序编译时预设的默认值。3.3 开发环境与代码要点我使用MikroC for PIC进行开发。这是一款针对PIC单片机的C语言集成开发环境编译效率高库函数丰富对于快速原型开发非常友好。代码结构关键点中断服务程序尽可能简洁只做标志位设置。例如定时器溢出中断用于频率测量计时外部中断用于唤醒或按钮边沿检测。模块化将功能分解为独立模块如sensor.c/h频率测量、led.c/h显示驱动、button.c/h按键处理、eeprom.c/h参数存储。功耗管理在进入睡眠前确保所有未用的外设模块ADC、比较器等都已关闭IO口设置为输出低电平或输入带上拉避免悬空耗电。EEPROM操作对校准参数的读写要小心。写入前先检查数据是否已改变避免不必要的擦写EEPROM有写入次数限制。重要参数可以存储两份并加校验和防止数据损坏。4. 制作、调试与问题排查4.1 PCB设计与外壳制作第二版我重新设计了PCB主要改进是整合电源管理将PIC10F322及其周边电路与主电路集成在同一块板上减少了连接器和飞线。优化布局将4060振荡电路部分靠近板边接口减少传感信号走线长度降低干扰。电源滤波电容靠近两个MCU的VDD引脚放置。增加编程接口为两个PIC分别预留了ICSP在线串行编程接口。这样在焊接完成后可以分别对它们烧录和调试固件。小型化使用更小封装的阻容元件将板子尺寸控制在比一枚硬币略大的范围。外壳我用3D打印制作。设计了一个简单的上下盖结构用螺丝固定。外壳正面为三个LED开了透光孔侧面为按钮开了孔背面留有槽位用于穿过连接铜箔的导线。文件我已经开源大家可以根据自己的打印机和喜好进行优化比如做成卡扣式免螺丝或者增加防水胶圈槽位。4.2 系统调试与实测调试分步骤进行4.2.1 电源管理部分调试先单独给PIC10F322部分供电测试长按按钮是否能可靠控制MOSFET开关。用万用表测量输出端电压。测试其ADC电池检测功能通过调试器读取ADC值验证其在不同输入电压下的读数是否准确。4.2.2 传感与主控部分调试给主系统上电不接水袋探头。用示波器观察4060的振荡输出引脚应该能看到一个固定频率的方波此时C仅为板上的固定小电容。编写一个简单的测试程序让PIC12F1572测量这个固定频率并每秒通过LED闪烁次数发送出来或用调试口打印验证频率测量功能正常。连接水袋探头这是最关键的一步。将两条铜箔导线连接到板子对应接口。准备一个透明水杯将贴有铜箔的水袋片或直接用铜箔贴在杯外浸入水中。观察频率变化缓慢向杯中注水同时用示波器观察4060输出频率或用调试程序读取单片机计算出的频率值。应该能看到频率随着水位上升而单调变化通常是降低因为电容增大频率减小。记录下空杯和满杯时的频率值这就是你后续校准的参考。4.2.3 系统联调与功能验证烧录完整固件组装好设备。测试基本显示给水袋加满水看是否显示“绿灯常亮”。慢慢放水观察LED状态是否按预设顺序平滑变化绿闪 - 橙常 - 橙闪 - 红常 - 红闪。测试按钮功能逐一测试短按切换显示模式如水切换到电量长按进入和退出校准菜单。执行校准严格按照“空满两点校准”流程操作一次然后再次测试水位显示准确性。功耗测试使用万用表电流档串联在电池回路中分别测量设备在“显示瞬间”、“睡眠期间”和“完全关机”状态下的电流。确保睡眠电流在几十微安级别关机电流在几微安以下。4.3 常见问题与排查技巧在实际制作和测试中你可能会遇到以下问题问题现象可能原因排查步骤与解决方案LED完全不亮1. 电池没电或接反。2. 电源管理MCU未开机或损坏。3. 主MCU未正常工作。1. 检查电池电压确认极性。2. 测量电源管理MCU输出端是否有电压。检查其编程和焊接。3. 检查主MCU电源、复位电路尝试用编程器连接看能否识别。LED显示状态混乱不随水位变化1. 探头铜箔接触不良或短路。2. 4060振荡电路不起振或频率异常。3. 单片机频率测量程序有bug。4. 校准数据错误或丢失。1. 用万用表测量探头两线间电阻无水时应为无穷大检查焊接。2. 用示波器直接观察4060振荡输出引脚看是否有波形波形频率是否随水位变化。3. 用调试器单步执行或打印中间变量检查定时器捕获值是否正确。4. 进入校准菜单重新执行两点校准。检查EEPROM读写函数。水位显示跳变不稳定1. 电源噪声干扰。2. 探头信号受干扰如靠近电源线。3. 软件滤波算法不够强。4. 水袋内有气泡或水流晃动。1. 在MCU的VDD和GND之间靠近引脚处增加一个0.1uF的陶瓷去耦电容。2. 将探头导线绞合在一起或使用屏蔽线远离电源部分。3. 增加软件采样次数或采用中位值平均滤波等算法。4. 这是物理限制可在软件中增加“变化率限制”或“迟滞”处理避免因短暂晃动导致显示频繁跳变。静置后读数应稳定。电池电量显示不准1. PIC10F322的ADC参考电压不准。2. 电池电压检测分压电阻精度不够或温漂大。3. 电量百分比映射关系不合理。1. 检查MCU的VREF配置或使用外部基准。2. 使用1%精度的金属膜电阻。测量实际分压电压与计算值是否一致。3. 针对使用的锂电池实测其放电曲线建立电压-电量的对应表而非简单线性计算。按钮操作不灵敏或误触发1. 按钮硬件消抖不足。2. 软件防抖延时设置不当。3. 长按/短按判断阈值不合理。1. 在按钮两端并联一个0.1uF电容进行硬件消抖。2. 调整软件防抖延时时间通常20-50ms为宜。3. 根据实际手感调整长按判定时间如从3秒调到2秒或4秒。最后一点个人体会这种基于电容感应的项目其稳定性和准确性非常依赖于外部环境的一致性。水袋的材质、厚度、铜箔的粘贴牢固度、甚至环境湿度都会对基线电容值产生微小影响。因此定期校准是一个好习惯尤其是在更换水袋或经历剧烈环境变化如从干燥室内到潮湿户外后。这个项目的乐趣不在于追求实验室级别的精度而在于用简单的原理和巧妙的设计可靠地解决一个实际户外需求。当你骑行在荒野中不用取下背包回头瞥一眼肩带上闪烁的LED颜色就能对剩余水量心中有数时那种感觉正是DIY最大的成就感所在。