基于光谱传感与LoRa的智能水质监测浮标设计与实践
1. 项目概述与核心价值
大家好,我是Akarsh。今天想和大家深入聊聊一个我投入了大量精力的实际项目——BIOLIGHT有害藻华监测浮标。如果你对嵌入式开发、环境传感或者物联网应用感兴趣,这个项目可能会给你带来不少启发。有害藻华,比如我们常听说的“赤潮”或蓝藻水华,已经不是一个遥远的环境问题,它对水产养殖、饮用水安全乃至整个水生生态系统的破坏力是惊人的。传统的监测方法要么依赖人工采样、实验室分析,周期长、成本高;要么使用大型昂贵的专业仪器,难以大规模部署。我们能不能做一个成本可控、能长期无人值守、还能实时上报数据的“哨兵”呢?这就是BIOLIGHT诞生的初衷。
这个项目的核心,是光谱传感技术。简单来说,就像给水体“验血”。藻类体内的叶绿素有一个特性:当用特定波长的蓝光(比如470nm)去照射它时,它会吸收光能,然后以另一种波长更长的红光(约680nm)重新发射出来,这种现象叫做荧光。藻类越多,叶绿素浓度越高,这种荧光信号就越强。因此,我们无需接触或破坏水样,通过测量680nm处的荧光强度,就能间接推算出藻类的相对丰度。BIOLIGHT系统就是围绕这一原理,构建了一个集光学激发、光谱检测、数据处理和无线传输于一体的智能浮标。它特别适合水库、湖泊、近海养殖区等场景的长期布放,为环境管理部门或研究机构提供连续、在线的预警数据。
2. 系统整体设计与方案选型
2.1 核心需求与设计思路拆解
在设计之初,我们明确了几个硬性约束和目标,这直接决定了后续的技术选型:
- 长期无人值守与低功耗:浮标依靠太阳能板和电池供电,必须能在阴雨天连续工作数周。这意味着MCU、传感器和无线模块在大部分时间必须处于深度睡眠状态,仅定时唤醒进行测量和发送。
- 可靠的远程数据传输:监测点往往位于偏远水域,没有蜂窝网络覆盖。需要一种远距离、低功耗的无线通信方式。
- 环境适应性:设备需要密封防水,能承受日晒、雨淋和水浪冲击。光学窗口必须防污,且内部光学路径设计要尽量减少环境杂散光的干扰。
- 成本与可制造性:在保证性能的前提下,尽可能采用通用、开源的硬件和软件方案,降低单台成本和后期维护难度。
基于这些需求,整个系统的架构变得清晰:一个低功耗的主控负责调度;一个高灵敏度的光谱传感器负责“看”;一个远距离无线模块负责“说”;再加上为它们持续供能的电源管理系统。所有的硬件都需要集成在一个坚固、密封的浮标壳体内。
2.2 关键组件选型解析
主控与无线通信:Seeed Studio LoRa-E5模块这是整个系统的“大脑”兼“嘴巴”。我选择了Seeed Studio的LoRa-E5模块,原因有三点:
- 高度集成:它内部集成了ST的STM32WLE5JC芯片,这是一颗ARM Cortex-M4内核的MCU与Sub-GHz LoRa射频前端的合封芯片(SoC)。用一颗芯片同时解决了计算和通信问题,极大地简化了外围电路设计,减少了布板面积和功耗点。
- 极低功耗:STM32WLE5系列专为低功耗LPWAN应用设计,支持多种低功耗模式。LoRa通信本身也具有“远距离、低数据率、低功耗”的特性,非常适合本项目中每天仅发送几次小数据包的应用场景。
- 开发生态友好:该模块支持LoRaWAN协议栈,并且有活跃的社区和丰富的示例代码。我选择基于Arm Mbed OS来开发固件,这是一个面向IoT设备的开源实时操作系统,它提供了完善的硬件抽象层、线程管理和电源管理框架,让我能更专注于应用逻辑,而不是底层驱动。
光谱传感器:Adafruit AS7341分光传感器这是系统的“眼睛”。选择Adafruit的AS7341 breakout板,主要看中其性能与易用性:
- 多通道光谱分析:AS7341拥有11个独立的光谱通道(8个可见光通道,1个近红外通道,1个透明通道,1个闪烁检测通道),其光谱响应范围覆盖约350nm到1000nm。虽然我们核心关注680nm(叶绿素荧光峰),但多通道数据有助于进行更复杂的光谱分析和背景光补偿。
- 集成度高:传感器本身集成了光学滤光片阵列和光电二极管,出厂已校准,避免了分立元件搭建光谱仪的复杂光学对准问题。Adafruit的板子进一步集成了电平转换和Qwiic/STEMMA QT接口,即插即用。
- 数字接口:通过标准的I2C接口与主控通信,电路连接简单,编程方便。
光学部件定制
- 激发光源:选用一颗中心波长在470nm的高亮度蓝色LED。这个波长非常接近叶绿素的最佳吸收峰(约450nm和660nm),能有效激发荧光。
- 光学滤光片:在传感器前方,加装了一片530nm长通滤光片。它的作用是只允许波长大于530nm的光通过,阻挡掉激发用的470nm蓝光及其附近的散射光。这样,到达传感器的就主要是叶绿素发射的680nm红光,极大提高了信噪比。
- 光学窗口:浮标与水接触的部分需要一块透明窗口。我选用BK7光学玻璃。它不仅透光性好、硬度高耐腐蚀,更重要的是其折射率稳定已知,这对于后期进行光学校准、修正光路偏差至关重要。
注意:光学设计是本项目的难点之一。LED的照射角度、与传感器的相对位置、滤光片的安装方向都需要仔细考虑,最好通过光学模拟软件(如TracePro)或实际搭建光路进行测试,确保激发光能均匀覆盖检测区域,同时传感器能有效收集荧光信号而避免直接接收到激发光的反射。
3. 硬件设计与实现要点
3.1 核心板卡:waveConnect定制板
为了满足低功耗和太阳能充电的需求,我没有使用现成的开发板,而是自主设计了一款名为waveConnect的定制PCB。这块板子的设计思路完全围绕“能源自治”和“接口整合”展开。
电源管理设计:
- 太阳能充电管理:板载了TI的BQ24650等高效太阳能充电管理芯片。它支持最大28V的输入,能根据锂电池的电压和电流状态,智能地在MPPT(最大功率点跟踪)、恒流、恒压等充电模式间切换,确保在各种光照条件下都能高效地为电池充电。
- 多路电压转换与功耗控制:系统内不同部件工作电压不同(如LoRa-E5是3.3V,AS7341是3.3V,LED驱动可能需要更高电压)。板子上使用了多个低静态电流的LDO和DC-DC转换器,并为传感器、LED等外围设备设计了由MCU GPIO控制的电源开关电路。当不测量时,可以彻底切断这些部件的供电,将静态功耗降到微安级别。
- 电池保护:集成了过充、过放、过流保护电路,确保常用的18650或LiPo电池在恶劣环境下也能安全、长久地工作。
接口与布局:
- 板子核心是LoRa-E5模块的焊盘,周围引出其所有关键GPIO。
- 专门设置了Qwiic/STEMMA QT接口,用于连接AS7341传感器。这种接口使用I2C总线,并自带3.3V电源和接地,通过一条4芯线缆即可完成连接,非常可靠且便于组装。
- LED驱动电路单独布局,靠近安装孔,以减少驱动电流对模拟信号的干扰。
- 所有对外接口(太阳能板接口、天线接口、调试接口)都做了防雷击和ESD保护设计。
实操心得:在绘制PCB时,务必将模拟部分(传感器、ADC参考电压)和数字部分(MCU、开关电源)进行分区布局,地线采用单点连接或磁珠隔离。为关键模拟电源路径增加π型滤波电路(如10μF钽电容并联0.1μF陶瓷电容),能显著提升传感器读数的稳定性。
3.2 机械结构与封装
浮标壳体使用3D打印(建议使用耐候性好的PETG或ASA材料)制作,分为上下两部分:
- 下半部分(水下舱):内部安装waveConnect主板、电池和配重块。底部开孔,用防水透气阀平衡内外气压,同时防止水汽凝结。侧面开有透明窗口,窗口内侧紧密安装光学组件(LED、滤光片、传感器),窗口外侧与水体接触。
- 上半部分(水上舱):安装太阳能电池板,内部可放置额外的备用电池或扩展传感器。顶部安装LoRa天线,天线类型需根据频率(如CN470, EU868等)选择,通常使用橡胶棒状天线即可,并确保其竖直向上。
- 密封与防水:上下壳结合面开有O型圈槽,使用硅胶O型圈和多个不锈钢螺丝压紧密封。所有穿线孔(如太阳能线)均使用防水格兰头。
组装关键:在安装光学组件时,要确保光学窗口内部洁净,LED发出的光路与传感器接收视场在待测水体区域有良好的重叠。可以在组装前,在暗室中用一张白纸模拟水面,点亮LED并观察光斑,同时用传感器读取数据,来微调组件的位置和角度。
4. 固件开发与传感器驱动
4.1 基于Mbed OS的软件架构
我选择Mbed OS 6作为开发框架。它的线程、事件队列和低功耗Ticker等组件,让构建一个状态机清晰的应用变得非常容易。
主程序流程:
- 初始化:系统上电后,初始化I2C(连接AS7341)、控制LED的GPIO、LoRa射频部分以及RTC(实时时钟)。
- 进入主循环(低功耗核心):
- 大部分时间,MCU通过调用
ThisThread::sleep_for()或配置低功耗定时器(LPTIM)进入Stop模式(深度睡眠),此时仅RTC和唤醒逻辑电路工作,功耗可低至几微安。 - RTC定时唤醒(例如每2小时一次)。唤醒后,系统执行测量任务。
- 大部分时间,MCU通过调用
- 测量任务:
- 打开传感器和LED的电源开关。
- 延时稳定(例如50ms)。
- 配置AS7341(选择增益、积分时间等参数,针对680nm通道进行优化)。
- 控制LED点亮,延时后读取传感器680nm通道(通常是通道F8或NIR)的原始ADC计数值。
- 控制LED熄灭,再次读取一次作为环境光本底(可选,因为已有530nm滤光片,但可进一步提高精度)。
- 关闭传感器和LED电源。
- 将原始数据代入校准公式计算反射率(或荧光强度相对值)。
- 数据发送任务:
- 判断是否达到发送周期(例如每12小时,或当测量值超过阈值时)。
- 如果满足条件,则唤醒LoRa射频部分,使用LoRaWAN协议(如OTAA入网)将打包好的数据(包含时间戳、通道值、计算值、电池电压等)发送到网络服务器(如Qubitro、TTN等)。
- 发送完成后,射频部分进入休眠,系统再次进入深度睡眠。
4.2 AS7341传感器驱动与配置
Adafruit提供了完善的Arduino库,但在Mbed OS下需要手动实现I2C读写。核心操作如下:
// 定义I2C引脚(以LoRa-E5的默认引脚为例) I2C i2c(PB_15, PB_14); // SDA, SCL (注意:需根据waveConnect板实际连接确认) DigitalOut led(PB_5); // 控制470nm LED // AS7341的I2C地址通常是0x39 #define AS7341_I2C_ADDR (0x39 << 1) // 写入一个寄存器 void writeRegister(uint8_t reg, uint8_t value) { char data[2] = {reg, value}; i2c.write(AS7341_I2C_ADDR, data, 2); } // 读取一个寄存器 uint8_t readRegister(uint8_t reg) { char regAddr = reg; char value; i2c.write(AS7341_I2C_ADDR, ®Addr, 1, true); // 发送寄存器地址,不发送停止位 i2c.read(AS7341_I2C_ADDR, &value, 1); return value; } // 初始化AS7341,配置为测量特定通道 void initAS7341() { // 1. 使能芯片,选择寄存器bank writeRegister(0x80, 0x01); // 写入ENABLE寄存器,PON=1, SP_EN=0(先关闭光谱测量) // 2. 配置测量模式,例如使用SMUX通道F8(680nm附近) // ... 详细的SMUX配置序列,需参考AS7341数据手册 // 3. 设置增益和积分时间 writeRegister(0x81, 0x02); // 设置增益,例如2倍增益 writeRegister(0x82, 0xC8); // 设置积分时间,例如200个ATIME周期(约5.6ms) }关键配置参数:
- 增益(AGAIN):根据水体浑浊度调整。清水可用高增益(如128x),浊水需用低增益(如1x),防止信号饱和。
- 积分时间(ATIME/ASTEP):决定了传感器“看”多久。时间越长,信噪比越好,但功耗越高且容易饱和。需要根据LED强度和预期藻类浓度在功耗和精度间权衡。通常从几十毫秒开始测试。
- SMUX配置:这是AS7341最灵活也最复杂的地方。它允许你将11个ADC映射到11个物理通道或进行特殊测量。对于本项目,我们主要关心680nm通道,需要查阅手册,正确编写SMUX配置命令序列,将该通道连接到ADC进行读取。
5. 传感器校准与数据分析
这是将原始ADC读数转化为有物理意义数据的关键步骤,也是项目中最需要耐心和技巧的部分。
5.1 校准的必要性与原理
传感器读出的原始值受到诸多因素影响:LED亮度随温度和老化变化、光学窗口的透射率、传感器各通道本身的灵敏度差异、电子电路的偏移等。因此,我们必须通过校准,建立一个从原始信号到“反射率”(或相对荧光强度)的映射关系。反射率是一个0到1之间的无量纲值,表示被测物反射(或发射)的光强与一个理想参考白板反射光强的比值,它排除了光源和系统本身的影响。
5.2 两步校准法实操
我们采用经典的“两点校准法”,需要获取两个基准值:最小反射率值和最大反射率值。
实验一:获取暗噪声值(Min_Value)这个值代表系统在完全无光条件下的本底噪声。
- 操作:将组装好的浮标光学窗口部分(或单独的传感器模块)放入一个完全黑暗的容器中(如用黑胶带密封的盒子)。确保没有任何光线进入。
- 测量:在固件中,在不打开LED的情况下,连续读取AS7341的680nm通道10-15次。
- 计算:将这组读数取平均值,作为
min_reflectance_value。这个值理论上应该非常小,接近0。
实验二:获取最大反射率值(Max_Value)这个值代表在当前光学系统下,传感器能接收到的“最强”信号。我们使用一个前表面反射镜作为参考物。
- 为什么是前表面镜?普通镜子(第二表面镜)的反射面在玻璃后面,光线会穿过玻璃两次,产生折射和吸收损失。前表面镜的反射涂层在玻璃表面,反射率极高(>95%),且光谱特性平坦,是理想的光学参考基准。
- 操作:将前表面镜紧贴浮标的光学窗口(或传感器窗口)。确保镜面清洁且与窗口平行。
- 测量:打开470nm LED,连续读取传感器10-15次。
- 计算:将这组读数取平均值,作为
max_reflectance_value。注意,此时测到的主要是LED光经镜面反射后,再通过530nm滤光片后的信号。由于滤光片会阻挡大部分470nm光,实际测到的可能是微弱的泄漏光或传感器暗噪声,这个操作主要是为了标定系统在“最强反射”条件下的读数上限。更严谨的做法是使用一个在680nm处有已知高反射率的漫反射白板(如Spectralon)作为参考。
计算样本反射率获取了min和max值后,对于任何待测水样,其反射率R可通过下式计算:R = (sample_value - min_reflectance_value) / (max_reflectance_value - min_reflectance_value)其中sample_value是测量水样时得到的原始ADC值。
重要提示:此校准过程应在稳定的环境(温度、湿度相对恒定)下进行,且校准后,系统的光学结构(LED、滤光片、传感器相对位置)绝对不能改变,否则需要重新校准。建议对每个生产批次的原型机都进行一次完整的校准,并将
min和max值存储在MCU的Flash或EEPROM中。
5.3 从反射率到藻类浓度
目前,我们得到了一个与叶绿素荧光强度相关的相对值R。要将其转化为藻类浓度(如μg/L叶绿素a),需要建立标定曲线。
- 采集标准样本:准备一系列已知叶绿素a浓度的标准溶液(可使用市售藻类标准品或通过实验室萃取测定获得)。
- 测量与记录:用校准好的BIOLIGHT浮标分别测量这些标准溶液,记录对应的
R值。 - 曲线拟合:在坐标系中,以浓度值为横坐标,
R值为纵坐标,绘制散点图。通常它们之间呈线性或指数关系。使用最小二乘法等工具进行拟合,得到公式浓度 = f(R)。 - 嵌入固件:将拟合得到的公式参数(如斜率和截距)写入固件。此后,设备每次测量后,即可直接计算并上报估算的藻类浓度。
现场快速验证方法:如果没有条件进行实验室标定,可以采用一种半定量方法。在目标水域,同时使用BIOLIGHT和一台便携式叶绿素荧光仪(如Turner Designs的Cyclops-7)进行平行测量,获取一组对照数据,从而建立经验换算关系。
6. 系统集成、测试与部署
6.1 整机组装与功能测试
在密封浮标壳体前,必须进行完整的系统测试:
- 功耗测试:使用精密电源或电流计,分别测量系统在深度睡眠、传感器测量、LoRa发射等不同状态下的电流。计算平均功耗,并结合电池容量(如3000mAh)和太阳能板日均充电电流,评估理论续航时间。确保在连续阴雨天数内,电池不会耗尽。
- 光学测试:在暗室中,将浮标光学窗口对准不同浓度的藻类溶液(或使用荧光标准片),查看测量值的变化趋势是否合理。尝试调整LED驱动电流和传感器积分时间,使测量值落在ADC量程的中间偏上区域(避免饱和或信噪比过低)。
- 通信测试:在计划部署的地点附近,测试LoRaWAN信号的连接质量。确认设备能成功加入网络(OTAA),并能稳定地将数据包发送至服务器。记录接收信号强度指示(RSSI)和信噪比(SNR)。
- 防水测试:将组装好的浮标(不含电子部件)或仅含核心部件的密封舱体,放入盛水容器中浸泡24小时以上,检查内部是否有水汽侵入。
6.2 数据平台与可视化
数据发送到LoRaWAN网络服务器(如The Things Network, ChirpStack)后,需要通过其内置的集成功能或自定义Webhook,将数据转发到应用服务器进行存储和展示。我使用了Qubitro这个IoT平台,它可以直接对接TTN,并提供数据看板、规则引擎和API。 在Qubitro上,我创建了一个仪表板,显示:
- 实时藻类浓度趋势图
- 电池电压变化曲线(判断设备健康状态)
- 信号强度地图(如果有多台设备)
- 可以设置报警规则,当浓度超过阈值时,自动发送邮件或短信通知。
6.3 部署与维护要点
- 选址:避开航道、渔网密集区。选择能代表整体水域状况的点位,避免靠近岸边或出水口等特殊区域。
- 锚定:使用合适的锚和缆绳,确保浮标能在一定范围内随风浪漂动,但不会漂失或相互碰撞。缆绳长度应为水深的3-5倍,以保证浮标有足够的活动范围。
- 防生物附着:长期浸泡,光学窗口和壳体上会附着藻类、贝类等生物,严重影响测量。可以在窗口周围涂抹防污涂料,或设计简单的机械刮擦装置。定期(如每季度)回收清理是必要的。
- 长期数据校验:即使部署后,也应定期(如每月)用便携式仪器进行现场比对测量,验证数据的可靠性,必要时进行远程软件校准(如更新校准参数)。
7. 常见问题与故障排查
在实际开发和部署中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 传感器读数始终为0或接近0 | 1. I2C通信失败 2. 传感器未上电 3. SMUX配置错误 | 1. 用逻辑分析仪或示波器检查I2C波形,确认地址、时序正确。 2. 检查waveConnect板上传感器电源开关电路及GPIO控制逻辑。 3. 仔细核对AS7341数据手册,确保SMUX配置命令序列完全正确,特别是使能光谱测量(SP_EN)的时机。 |
| 读数波动巨大,不稳定 | 1. 电源噪声 2. 环境光干扰 3. I2C上拉电阻问题 | 1. 检查模拟电源滤波电容是否焊接良好。测量时,可短暂关闭不必要的数字电路(如LoRa射频)。 2. 确认530nm长通滤光片安装正确且无破损。在强光下测试,看读数是否对光照变化敏感。 3. 确认I2C总线的上拉电阻(通常4.7kΩ)已正确连接。线缆过长也可能导致信号完整性变差。 |
| LoRa无法入网或通信距离极短 | 1. 天线问题 2. LoRaWAN参数配置错误 3. 地理位置信号差 | 1. 检查天线类型是否与所用频段匹配,连接器是否拧紧,天线是否未被金属壳体屏蔽。 2. 核对DevEUI、AppEUI、AppKey是否正确;确认频率计划(如CN470, EU868)、数据速率(DR)与网关匹配。 3. 使用网关的频谱扫描功能或设备侧的“空口监听”模式,检查所在位置的信号质量和干扰情况。 |
| 电池消耗过快,无法达到预期续航 | 1. 未进入深度睡眠 2. 外围设备漏电 3. 发送频率过高 | 1. 使用电流计观察睡眠时电流,应在微安级。检查Mbed OS的电源管理配置,确认所有外设时钟已关闭,GPIO设置为模拟输入等省电状态。 2. 逐个断开传感器、LED等外设,排查漏电元件。 3. 评估数据上报频率是否必要,尝试降低发送频率或仅在数据超阈值时发送。 |
| 测量数据与实验室结果偏差大 | 1. 校准失效 2. 光学窗口污染 3. 水体浊度影响 | 1. 重新进行暗噪声和最大反射率校准。 2. 清理光学窗口。考虑设计防污措施。 3. 叶绿素荧光法受浊度影响。可尝试利用AS7341的其他通道(如近红外通道)估算浊度,对结果进行补偿。需要建立更复杂的多元校正模型。 |
最后一点个人体会:硬件项目,尤其是涉及精密测量和户外部署的,调试周期往往比想象的长。不要期望第一次打板、第一次编程就能完美运行。耐心地分模块测试(电源、MCU、传感器I2C、LoRa射频),用逻辑分析仪、串口打印、电流计等工具把问题一个个揪出来。这个BIOLIGHT项目从构思到稳定运行,我前后迭代了三个版本的PCB,修改了无数次固件。当第一次从远程平台看到来自真实湖面的、有规律变化的数据时,那种成就感是无与伦比的。这个项目开源了所有硬件设计和软件代码,希望它能成为一个引子,大家可以根据自己的具体需求去修改、优化,比如增加pH、溶解氧、温度传感器做成多参数水质监测站,或者尝试不同的通信方式。物联网与传感技术的结合,能为我们理解和保护环境打开一扇新的窗户。
