
光电式液位检测红外对射管阵列—— 最可靠、最稳定的液位检测方案关键词红外对射管、液位检测、光电液位、输液泵、智能水杯前言做了大半辈子电子从 80 年代的模拟电路到后来的单片机、ARM、物联网经手的项目少说也有上百个。如果你问我在液位检测这个细分领域什么方案最值得信赖我会毫不犹豫地告诉你红外对射管阵列。这玩意儿的原理简单到不需要智商去理解——有水没水光是直射还是偏折就这么回事。但恰恰是这种物理层面的简单造就了它近乎变态的可靠性。我早年做医疗输液泵的时候这个方案用了十几年批量出货几十万台从来没有因为液位检测本身出过任何一起医疗事故级别的故障。零。后来做智能水杯也是这套方案稳如老狗。今天就把这个方案掰开揉碎了讲清楚。目录核心原理系统架构硬件实现电路设计详解结构设计要点软件算法抗干扰与可靠性设计与其它方案的对比实际应用案例常见问题与排查1. 核心原理1.1 光学基础一切的基础就是一个中学物理实验光的折射。当一束红外光从空气射入水中时由于空气和水的折射率不同空气 ≈1.0水 ≈1.33光线会在界面处发生折射传播方向发生偏折。我们在杯子容器的一侧安装红外发射管IR LED正对面安装红外接收管光电三极管两者组成一对对射管。无水状态 有水状态 ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ LED ●─────→│→→→→→→→→→→→→→→→ │ PD │ │ │ 光线直射 │ │ │ (空气) │ 光强大 │ (空气) │ │ │ │ │ │ LED ●─────→│→→→↘ │ PD │ │ │ 光线偏折 │ │ │ ( 水 ) │ 光强小 │ ( 水 ) │ │ │ │ │ └─────────────┘ └─────────────┘ LED 红外发射管 PD 光电接收管Photodiode/光敏三极管 ● 发射端 → 光线路径1.2 判断逻辑 —— 比你想的更简单状态光线路径接收管电流判断无水直线穿过大几十到几百μA该档位 0干有水折射偏折小几μA甚至为零该档位 1湿这不是一个模棱两可的概率判断而是一个确定性的物理二值判断。光要么直射过来要么偏折走了——不会有第三种情况。这就是为什么我说它绝对可靠的根本原因。2. 系统架构2.1 对管阵列沿容器侧壁垂直排列5~8 组红外对管每一组对应一个液位档┌──────────────────┐ │ │ ─────┤ D8 ←──●── E8 │ ← 第8档 (最高) │ │ ─────┤ D7 ←──●── E7 │ ← 第7档 │ │ ─────┤ D6 ←──●── E6 │ ← 第6档 │ │ ─────┤ D5 ←──●── E5 │ ← 第5档 │ │ ─────┤ D4 ←──●── E4 │ ← 第4档 │ │ ─────┤ D3 ←──●── E3 │ ← 第3档 │ │ ─────┤ D2 ←──●── E2 │ ← 第2档 │ │ ─────┤ D1 ←──●── E1 │ ← 第1档 (最低) │ │ └──────────────────┘ E1~E8 红外发射管 (Emitter) D1~D8 红外接收管 (Detector) ●→ 红外光线路径 ───── 液面当前液位 从下往上数最后一个无水档位对应的接收管。举个例子D1、D2、D3 接收到光无水D4~D8 没接收到有水说明液面在第 3 档和第 4 档之间当前液位 3 档。2.2 档位数量的选择档位数适用场景优缺点3~4 档低成本、小容量容器够用但粗糙5~6 档智能水杯推荐性价比最佳7~8 档高精度需求输液泵等医疗设备精度高但增加成本和布线10 档特殊场景一般不需要结构复杂度上升对于智能水杯6 档是我最推荐的配置配合 300~400ml 的杯子每档约 50~60ml分辨率和成本达到最优平衡。3. 硬件实现3.1 器件选型红外发射管IR LED参数推荐值说明波长940nm标准近红外便宜且与接收管配对好封装0603 或 0805 SMD体积小适合贴在杯壁外侧正向电流 If5~20mA典型实际使用时可以降额到 3~5mA 以省电发散角±15° ~ ±25°窄角更好减少散射干扰单价¥0.05 ~ ¥0.15对你没看错几毛钱都不要推荐型号仅作参考亿光EverlightIR91-21C/TR100603欧司朗OsramSFH 4045N更贵但性能更好医疗设备用红外接收管光电三极管 / Phototransistor参数推荐值说明封装0603 或 3mm 插件与发射管对齐安装峰值波长匹配发射管~940nm光谱匹配度直接影响灵敏度集电极电流 Ic(on)0.5~5mA典型光照下越大越容易检测暗电流100nA越小越好影响信噪比单价¥0.10 ~ ¥0.30推荐型号仅作参考亿光 PT91-21C/TR100603与发射管配对威世VishayTEPT5700插件性能优异一对管子的总物料成本不到 5 毛钱。6 组就是 3 块钱。加上 PCB 和 MCU整个液位检测模块的 BOM 成本不超过 8 块钱。3.2 MCU 选择基本没有要求有足够的 GPIO 即可6 组对管需要 6 个输出驱动 LED 6 个 ADC 输入或数字输入 12 个 GPIO任意一颗 Cortex-M0 以上的芯片都绰绰有余推荐STM32F030、GD32E230、STM8S003、华大 HC32L110 等如果 GPIO 不够可以用 74HC595串转并驱动发射管用 74HC165并转串读接收管或者干脆用模拟开关轮询。4. 电路设计详解4.1 发射端驱动最简单的驱动方式GPIO 直接通过限流电阻驱动红外 LED。VCC (3.3V) │ │ ┌┴┐ │ │ R_limit │ │ 100Ω ~ 330Ω └┬┘ │ ├────→ 接红外LED阳极 │ ┌─┴─┐ │LED│ 红外发射管 └─┬─┘ │ ├────→ 接GPIO (推挽输出) │ ═══ GND R_limit (VCC - Vf_LED) / If 假设: VCC3.3V, Vf_LED1.2V, If5mA 则: R_limit (3.3 - 1.2) / 0.005 420Ω 取标称值: 390Ω 或 470Ω如果 GPIO 驱动电流不够某些 MCU 单引脚最大 5mA用 NPN 三极管增强驱动VCC (3.3V) │ ┌┴┐ │ │ R_limit └┬┘ │ ┌─┴─┐ │LED│ └─┬─┘ │ C GPIO ──[Rb]──B NPN (如 S8050) E │ ═══ GND4.2 接收端检测光电三极管接成共射极放大形式VCC (3.3V) │ ┌┴┐ │ │ R_load 负载电阻关键参数 │ │ 10kΩ ~ 100kΩ └┬┘ │ ├────────────→ 接MCU ADC输入 │ C ┌────────B NPN光电三极管 │ E │ │ │ ═══ │ GND │ (受红外光照射) 有水时: Ic↓ → Vout↑ (接近VCC) 无水时: Ic↑ → Vout↓ (接近GND)负载电阻 R_load 的选择是核心——选大了灵敏度高但容易饱和选小了区分度不够。我的经验值发射管驱动电流 5mA、接收距离 10~20mmR_load 47kΩ发射管驱动电流 3mA、接收距离 20~30mmR_load 100kΩ发射管驱动电流 10mA、接收距离 5~10mmR_load 10kΩ不要盲信计算结果一定要用示波器实测波形找到有水和无水状态下电压差最大的 R_load 值。4.3 完整电路示例下面是一个 6 通道的完整电路设计发射端6通道: 接收端6通道: GPIO_PA0 ──[R0]──[LED0]──GND VCC─[Rload0]──┬── ADC_IN0 ─ MCU GPIO_PA1 ──[R1]──[LED1]──GND C GPIO_PA2 ──[R2]──[LED2]──GND [PD0]B GPIO_PA3 ──[R3]──[LED3]──GND E GPIO_PA4 ──[R4]──[LED4]──GND │ GPIO_PA5 ──[R5]──[LED5]──GND GND R0~R5 390Ω (限流电阻) LED0~LED5 940nm 红外发射管 PD0~PD5 940nm 光电三极管 Rload0~Rload5 47kΩ (负载电阻) 不用的ADC通道也要接地或拉高不要浮空4.4 省电设计电池供电场景智能水杯通常用锂电池供电省电是关键。以下手段可以把液位检测的平均功耗做到 50μA间歇检测每 100ms 检测一次每次亮 100μs占空比 100μs / 100ms 0.1%平均功耗 峰值功耗 × 0.1%分时点亮不要 6 个 LED 同时亮逐个点亮逐个检测瞬时电流小电源纹波也小睡眠时完全断电用 GPIO 控制 LED 供电的 PMOS 开关不检测时完全关断具体时序: ┌──── 100ms ────┐┌──── 100ms ────┐ │ ┌100μs┐ ││ │ │ │Ch1~6│ 休眠 ││ ... │ └──┴─────┴──────┘└───────────────┘ 每100ms唤醒 → 依次扫6个通道(每通道~15μs) → 总共~100μs → 休眠5. 结构设计要点结构设计是这套方案最容易踩坑的地方也是很多新手搞不定的环节。5.1 透光窗口 —— 核心中的核心普通塑料比如 ABS、PP对红外光是不透明的——或者说透过率极低。如果不做处理直接把管子贴在杯子外壁上你会发现不管有水没水接收管都收不到光。解决方案有三种方案做法优点缺点推荐度A. 开窗在杯壁上对应位置挖孔或留透明窗光学性能最好需要模具配合增加成本⭐⭐⭐⭐⭐B. 透红外塑料杯体用 PCTG、透明 PP 等材料不开窗外观完整材料成本略高⭐⭐⭐⭐C. 二次注塑双色模在杯壁嵌入透明 PC/PCTG 镶件兼顾外观和光学模具复杂成本高⭐⭐⭐方案 A开窗是性价比最高的选择也是我在量产产品中最常用的做法。具体操作在杯体模具上设计 6 组对穿的窗口每个窗口 3×3mm 左右窗口用透明 PC 或 PMMA 薄片覆盖可以做成装饰件的一部分发射管和接收管的 PCB 贴在窗口外侧关键尺寸参考窗口直径2~4mm太小对不准太大漏光对射距离8~25mm杯子壁厚决定管子的安装位置要精确——发射管、窗口、接收管三者必须在同一光轴上5.2 对管安装精度0603 封装的 LED 尺寸是 1.6×0.8mm这么小的东西要对准确实不容易。量产做法在 PCB 上做好定位孔/定位边管子上件后用 AOI自动光学检测检查偏移装配时用定位柱/卡扣保证 PCB 和杯体的相对位置如果有条件用 UV 胶把 PCB 和杯体固定在一起手动对位的土办法做样品时用先在杯壁上画好位置标记接通发射管在接收端用手机摄像头看红外光斑手机摄像头对红外敏感调整到光斑最亮的位置做好标记最后用热熔胶或快干胶固定5.3 环境光隔离红外接收管不光对发射管的红外光敏感对太阳光、白炽灯、甚至某些 LED 灯具中的红外成分也敏感。必须做遮光设计物理遮挡PCB 和杯体之间加黑色硅胶垫圈阻断外部光路遮光罩在接收管周围加一个黑色的小围挡软件相减检测时先读一次发射管关闭状态环境光本底再读一次发射管打开状态两者相减得到净信号调制检测发射管用 38kHz 调制接收端带通滤波——这是最彻底的方案但电路稍复杂对于绝大部分消费类产品方案 123 就足够了。6. 软件算法6.1 基本检测流程// 伪代码 #define CHANNEL_COUNT 6 #define THRESHOLD 1500 // ADC阈值根据实测标定 typedef struct { uint16_t adc_water; // 有水时的ADC值标定存入 uint16_t adc_air; // 无水时的ADC值标定存入 uint16_t threshold; // 判决阈值 (adc_water adc_air) / 2 } channel_cal_t; channel_cal_t cal[CHANNEL_COUNT]; // 出厂标定数据存在Flash/EEPROM里 uint8_t detect_liquid_level(void) { uint8_t level 0; for (int ch 0; ch CHANNEL_COUNT; ch) { // 1. 关闭发射管读环境光本底 led_off(ch); delay_us(10); uint16_t ambient adc_read(ch); // 2. 打开发射管读信号 led_on(ch); delay_us(50); // 等光电三极管稳定 uint16_t signal adc_read(ch); led_off(ch); // 3. 净信号 信号 - 本底 uint16_t net (signal ambient) ? (signal - ambient) : 0; // 4. 判断净信号 阈值 → 无水 → 该档位有效 if (net cal[ch].threshold) { level ch 1; // 1-based 档位 } else { break; // 一旦某个档位有水上面档位必然也有水 } } return level; }6.2 标定流程出厂必须做每台设备出厂前都需要标定——千万不要用一个固定的阈值原因每个杯子的透光率、管子的安装偏差、PCB 公差都不一样。标定流程步骤1: 空杯标定 —— 记录每个通道的无水ADC值 杯内完全干燥 → 检测6个通道 → 记录 adc_air[0..5] 步骤2: 满杯标定 —— 记录每个通道的有水ADC值 杯内装满水 → 检测6个通道 → 记录 adc_water[0..5] 步骤3: 计算自适应阈值 threshold[ch] (adc_air[ch] adc_water[ch]) / 2 步骤4: 写入Flash生产完成标定时的附加检查检查adc_air是否在合理范围不能太小否则说明光路没对准检查adc_air - adc_water的差值是否足够大建议 500 个 ADC 字如果差值太小说明该通道有问题标记不良返修6.3 喝水行为检测智能水杯核心功能前文说了红外对管只能做档位检测无法连续测量液位。但智能水杯需要记录用户的饮水量怎么办答案通过对喝水行为建模。#define DEBOUNCE_MS 2000 // 消抖时间液位变化需持续2秒才确认 uint8_t last_stable_level 0; uint32_t level_change_time 0; typedef struct { uint32_t timestamp; uint8_t level_before; uint8_t level_after; uint16_t volume_ml; // 估计饮水量 } drink_event_t; void check_drinking(void) { uint8_t current_level detect_liquid_level(); // 消抖液位必须稳定一段时间才确认变化 if (current_level ! last_stable_level) { if (level_change_time 0) { level_change_time get_tick_ms(); // 开始计时 } else if (get_tick_ms() - level_change_time DEBOUNCE_MS) { // 确认液位变化 if (current_level last_stable_level) { // 液位下降 → 喝水事件 uint8_t diff last_stable_level - current_level; uint16_t volume diff * ML_PER_LEVEL; // 每档对应的毫升数 drink_event_t event { .timestamp get_tick_ms(), .level_before last_stable_level, .level_after current_level, .volume_ml volume, }; log_drink_event(event); } // 液位上升 → 加水事件不计入饮水量 last_stable_level current_level; level_change_time 0; } } else { level_change_time 0; // 液位恢复重置计时器 } }喝水检测的几个经验参数参数推荐值说明消抖时间1500~3000ms太短容易把拿起杯子误判为喝水每档毫升数50~70ml取决于杯子容量和档位数最小饮水间隔30s30秒内的多次检测合并为一次倾斜补偿角度45°杯子倾斜时暂停检测避免误判7. 抗干扰与可靠性设计7.1 常见干扰源及对策干扰源现象对策环境红外光阳光、白炽灯无水时 ADC 读数异常高环境光相减法 物理遮光杯子晃动液面晃动导致档位跳变软件消抖2s 延时确认水珠/水雾挂在杯壁干扰光路误判为有水涂层疏水处理 窗口位置避开水流路径杯子倾斜液面倾斜导致各档位不一致加姿态传感器或至少加一个倾角开关LED 老化发射光强逐年下降出厂标定时留余量 MCU 动态调整驱动电流水垢/污渍窗口透光率下降标定时记录原始值发现异常偏移时触发清洗提醒7.2 故障检测与容错做医疗设备养成的习惯任何一个传感器都可能坏你必须知道它坏了。typedef enum { CH_OK 0, // 正常 CH_OPEN_CIRCUIT, // 开路管子虚焊/断线 CH_SHORT_CIRCUIT, // 短路 CH_LOW_SIGNAL, // 信号太弱水垢/老化/错位 CH_STUCK_HIGH, // 卡在高电平 CH_STUCK_LOW, // 卡在低电平 } channel_status_t; channel_status_t self_test_channel(uint8_t ch) { // 测试1: LED关闭时ADC应该接近0检查接收管是否短路到VCC led_off(ch); if (adc_read(ch) ADC_VCC * 0.9) return CH_SHORT_CIRCUIT; // 测试2: LED打开时应有明显信号检查光路是否正常 led_on(ch); delay_us(50); uint16_t signal adc_read(ch); led_off(ch); if (signal cal[ch].threshold * 0.1) return CH_LOW_SIGNAL; if (signal ADC_VCC * 0.95) return CH_STUCK_HIGH; return CH_OK; }7.3 EMC/ESD 保护所有对外接口触摸按键、USB 充电口加 TVS 管红外管的引线尽量短PCB 走线远离开关电源的 SW 节点接收管的 ADC 输入端并联 100pF 小电容滤除高频干扰生产线上 ESD 枪打 ±8kV 接触放电±15kV 空气放电不能复位/死机/误报8. 与其它方案的对比说实话市面上智能水杯用的液位检测方案五花八门但真正靠谱的不多。方案原理精度可靠性成本功耗适用场景红外对管阵列本文方案光折射档位级⭐⭐⭐⭐⭐¥3~850μA智能水杯、输液泵、咖啡机电容式液位介质常数变化连续⭐⭐⭐¥5~15中等水箱、油箱超声波回波测距连续±2mm⭐⭐⭐⭐¥20~50较高工业储罐气压计底部压力连续±5ml⭐⭐¥5~10极低智能水杯精度依赖校准称重重量换算连续±1ml⭐⭐⭐⭐⭐¥15~40中等高端水杯、实验设备电极式导电性档位级⭐⭐¥2~5低低成本方案受水质影响大浮子霍尔机械浮子连续⭐⭐⭐¥8~20零咖啡机、马桶水箱为什么我不推荐气压计方案这几年有些智能水杯用气压计大气压力传感器来测液位通过测量杯底水压来推算液位高度。听起来很高级但实际上温漂大得离谱气压计对温度极其敏感喝水时倒入热水温度一变读数就飘绝对精度差消费级气压计的分辨率虽然高可以到厘米级水柱但绝对精度和重复性完全不够需要频繁校准大气压本身就在变化天气每次使用前都要校准零点杯口不密封水杯不是密闭容器气压计方案先天不足相比之下红外对管方案不受温度、水质、气压的任何影响。9. 实际应用案例9.1 医疗输液泵2005~2012年本人在某医疗电子公司输液泵需要对输液袋/输液瓶中的剩余药液进行实时监测在药液即将耗尽时报警并自动停止输液。为什么用红外对管医疗设备不允许出错——输液空了还在输液会产生气栓严重可致死输液袋里的药液种类繁多生理盐水、葡萄糖、化疗药……pH 值、电导率、粘度都不一样电极法受药液电导率影响电容法受介电常数影响——只有光学法对所有液体一视同仁配置8 组对管2cm 间距输液袋挂在挂钩上对管阵列贴在输液袋外侧。这个产品拿到了 CFDA 三类医疗器械注册证出货量超过 30 万台。液位检测模块零故障。9.2 智能水杯2016~2018年某消费电子创业公司在智能水杯项目上我们沿用了红外对管方案6 组对管覆盖 350ml 容量每档约 58ml杯体采用PCTG 透明材料Tritan省去开窗工序BLE 蓝牙连接手机 APP实时上传饮水量数据一杯电200mAh 锂电池续航约45 天液位检测的低功耗设计功不可没量产数据首批 5000 台液位检测不良率 0.8%不良品分析70% 是装配对位偏差20% 是焊接虚焊10% 是来料问题改进装配工装后不良率降至 0.1%9.3 水位报警器一个很小的副项目还做过一个简单的水位报警器在鱼缸、花盆、地面积水检测等场景用。只有 2 组对管一组在底部检测是否有水一组在顶部检测是否满水。整个电路不到 5 块钱一节 CR2032 用大半年。10. 常见问题与排查Q1: 同一个通道有水和无水的 ADC 差值很小怎么解决排查步骤用示波器看接收管两端的电压波形——是不是根本没有变化检查窗口是否有异物遮挡贴膜、污渍、胶水溢出增大 R_load 电阻试试翻倍提高增益增大 LED 驱动电流减少限流电阻检查管子型号——是不是用了可见光 LED 而不是 940nm 红外 LED换个方向看——发射管和接收管是不是装反了真的有批量装反的惨案Q2: 为什么空杯时 ADC 值也很低应该很高的排查步骤管子装反了发射和接收互换发射管正负极反了光路被遮挡杯体材料对红外不透明把杯子放在发射管和接收管之间用手电筒照一下看透不透接收端 R_load 虚焊/变值Q3: 有水无水能区分但档位偶尔跳变排查步骤消抖时间够不够增加到 3 秒试试杯子是否倾斜加个倾角检测是否有气泡附着在窗口上水里加点洗洁精再测试如果问题消失就是气泡检查电源纹波——纹波大了会导致 ADC 不稳Q4: 开窗方案会不会漏水不会。窗口是在杯体外壳上不是在内胆上。杯体内胆是完整的密封容器玻璃或不锈钢内胆红外对管检测的是透过外壳和内胆的光路。外壳上的窗口只是个观测窗不影响密封。Q5: 能不能用在金属杯子上不能直接贴在外面用。金属对红外光完全不透明。如果一定要用金属杯子方案 1在金属杯体上开窗机械加工成本高方案 2在杯口上方做一个小型的透明液位柱连通器原理在液位柱上做检测方案 3换方案——金属杯子建议用称重法结语写了这么多其实归根到底就一句话好的方案往往是简单的方案。红外对管测液位这个东西原理简单到不用解释器件便宜到不用还价可靠到不用怀疑。它不是什么新科技——80 年代就有成熟应用了。但它就是好用经过了时间的检验。在一个动不动就上激光雷达、AI 视觉、毫米波传感器的时代能用几毛钱的红外对管解决的问题就别搞那么复杂。这也算是我做了 40 年电子工程的一点心得工程技术的最高境界不是把事情做复杂而是把事情做简单。版权声明本文为作者原创欢迎转载转载请注明出处。联系与合作如有技术问题或合作需求欢迎私信交流。但别问我能不能免费帮你画板子我的退休金还没攒够。写于 2026 年 7 月某个周末的午后一壶铁观音一台示波器调了一下午的电源纹波顺便写了这篇。