1. 项目背景与核心需求拆解1.1 城市河道监控的现实痛点城市河道管理这件事没接触过的人可能觉得就是看看水位、清清垃圾但真正做过河道巡检的人都知道这里面的麻烦事远比想象中多。传统的人工巡检模式通常是一个班组沿着河道走一遍用肉眼观察水位标尺、看看有没有漂浮物、检查岸边有没有违规排放。这种方式有几个绕不开的问题一是时效性差河道情况是动态变化的可能上午刚巡完下午一场暴雨下来水位就暴涨了二是覆盖范围有限一个班组一天能走的距离就那么长对于穿城而过的长河道来说很难做到全时段全流域覆盖三是数据记录靠手写回头整理成报表又是一道工序信息滞后严重。我见过不少小型河道管理站值班室里就一台老式电脑值班人员每隔两小时去河边看一眼水尺回来在本子上记一笔。这种模式在汛期特别吃力因为水位变化快两小时的间隔可能就错过了关键预警窗口。而且夜间巡检基本靠手电筒效率和安全性都成问题。1.2 为什么选择单片机加LoRa这套组合这个毕业设计题目选的是“基于LoRa的城市河道监控系统”核心思路是用无线传感网络替代人工巡检。为什么是LoRa而不是WiFi或者4G这里面的选型逻辑值得说清楚。WiFi的覆盖半径通常只有几十米河道场景下节点分散不可能每隔几十米就布一个路由器而且WiFi的功耗高电池供电的节点撑不了几天。4G模块虽然覆盖广但每个节点都要插SIM卡长期运行有流量费用对于几十个节点的系统来说运营成本不低而且4G模块的功耗也不适合纯电池供电的场景。LoRa的核心优势在于远距离、低功耗、低成本这三个点的平衡。在城区环境下LoRa的通信距离通常能到1到3公里如果河道比较直、遮挡少5公里以上也能做到。它的发射功率可以低到十几毫安级别配合休眠机制一节锂电池能撑几个月甚至一年。而且LoRa工作在免授权频段不需要额外申请模块成本也便宜一个LoRa模块十几块钱就能买到。对于城市河道这种节点分散、数据量不大、需要长期值守的场景LoRa几乎是性价比最高的选择。单片机这边常见的选择是STM32系列或者51系列。考虑到这个项目需要驱动多个传感器、处理LoRa通信协议、还要做低功耗管理STM32F103系列是比较稳妥的选择资源够用资料多价格也合适。如果只是简单的数据采集51单片机也能凑合但扩展性和低功耗管理会吃力一些。1.3 系统整体架构与功能定义这套系统的完整链路是这样的分布在河道沿线的多个监测节点每个节点上挂载水位传感器、水质传感器比如浊度、pH值、雨量传感器等单片机定时采集数据通过LoRa发送到汇聚节点汇聚节点再通过串口或者4G模块把数据上传到上位机或者云平台。上位机负责数据存储、可视化展示和阈值报警。从功能上拆解系统需要实现几个核心能力第一是多参数采集至少包括水位和降雨量水质参数可以根据预算选配第二是无线数据传输节点到汇聚节点用LoRa汇聚节点到服务器可以用有线或者4G第三是低功耗运行节点用电池供电需要支持休眠唤醒机制第四是异常报警水位超过警戒线或者降雨量突增时系统要能及时推送告警。这个架构的好处是层次清晰节点只负责采集和发送汇聚节点负责汇总和转发上位机负责展示和决策。每个环节的职责明确调试的时候也容易定位问题。对于毕业设计来说这个规模既能体现技术含量又不至于复杂到做不完。2. 硬件选型与核心器件解析2.1 主控芯片的选型对比主控芯片是整个节点的核心选型的时候主要看几个维度引脚数量、外设资源、功耗表现、开发难度和成本。我整理了一个对比表格把常见的几个选项放在一起看。芯片型号内核主频Flash/RAM低功耗模式单价区间适用场景STM32F103C8T6Cortex-M372MHz64KB/20KB睡眠/停止/待机10-15元多传感器节点资源充足STM32L051Cortex-M032MHz32KB/8KB超低功耗12-18元电池供电功耗敏感STC89C52805111.0592MHz8KB/512B空闲/掉电3-5元简单采集成本敏感ESP32双核240MHz4MB/520KB深度睡眠15-25元需要WiFi/蓝牙的场景对于这个项目如果节点需要同时驱动水位、浊度、pH、雨量四个传感器再加上LoRa模块和OLED显示STM32F103C8T6的引脚和外设资源是比较合适的。它有两个USART、两个SPI、两个I2CADC有10个通道足够应付这些外设。如果对功耗要求特别高比如节点要放在没有市电的地方靠电池撑半年以上那STM32L051会更合适但它的RAM只有8KB编程时要更注意内存管理。注意选型时不要只看参数还要看社区资料和调试工具。STM32系列的ST-Link调试器和CubeMX配置工具非常成熟遇到问题容易找到解决方案。冷门芯片虽然参数好看但调试时可能连个像样的例程都找不到。2.2 LoRa模块的关键参数与选型LoRa模块市面上常见的有几类基于SX1278的裸模块、带MCU的透传模块、以及集成度更高的模组。对于毕业设计我建议用基于SX1278的SPI接口模块比如常见的Ra-01或者Ra-02。这类模块价格在15到25元之间通过SPI和单片机通信需要自己写驱动但这样能体现工作量也更容易理解LoRa的通信机制。关键参数方面需要关注这几个频率选433MHz还是868/915MHz国内一般用433MHz穿透性好一些扩频因子从6到12可调扩频因子越大通信距离越远但速率越低河道监控这种小数据量场景可以用SF10或11带宽通常选125kHz编码率选4/5。这些参数在发送端和接收端必须一致否则通信不上。发射功率方面SX1278最大可以到20dBm但实际使用中不建议一直开最大一是功耗高二是可能干扰其他设备。城区河道场景下14dBm到17dBm通常就够用了配合合适的扩频因子覆盖1到2公里没问题。2.3 传感器选型与接口设计水位传感器是这个系统的核心传感器。常见的有超声波水位计、压力式水位计和浮子式水位计。超声波水位计安装方便非接触式测量但价格偏高而且容易受水面漂浮物和温度影响。压力式水位计精度不错但需要接触水体长期使用会有淤积问题。对于毕业设计我建议用超声波水位计虽然贵一点但安装调试简单数据也直观。浊度传感器可以用常见的TSW-30或者类似的模拟输出模块输出0到4.5V的电压信号对应0到1000NTU的浊度值。pH传感器用玻璃电极加信号调理板输出模拟电压。雨量传感器用翻斗式雨量计每翻一次输出一个脉冲单片机用外部中断计数。接口设计上模拟传感器接STM32的ADC通道数字脉冲接外部中断引脚LoRa模块接SPIOLED显示接I2C。这里要注意的是ADC参考电压要稳定最好用单独的LDO给模拟部分供电否则水位和浊度的读数会跳动。3. 软件架构与通信协议设计3.1 节点端程序框架节点端的程序需要同时处理多个任务定时采集传感器数据、通过LoRa发送数据、管理电源模式、驱动本地显示。如果不用RTOS用前后台架构也能做但任务多了之后时序会变得复杂。我建议用时间片轮询加中断的方式主循环里按不同的时间间隔执行不同任务关键事件用中断处理。具体来说主循环里维护几个计数器传感器采集每30秒执行一次LoRa发送在采集完成后触发OLED显示每5秒刷新一次电源管理每10秒检查一次电池电压。中断方面雨量传感器的脉冲用外部中断计数LoRa模块的DIO0引脚用外部中断检测发送完成或接收完成。这种架构的好处是逻辑清晰不需要RTOS的开销对于STM32F103来说资源占用很小。但要注意的是LoRa发送过程中不能被打断太久否则可能丢包。所以发送时可以先关掉其他中断发完再开。3.2 LoRa通信协议的自定义LoRa本身只提供物理层的传输能力数据格式需要自己定义。对于河道监控这种场景我设计了一个简单的帧结构字段长度说明帧头2字节固定为0xAA 0x55用于同步节点ID1字节区分不同监测节点最多255个数据类型1字节0x01水位0x02浊度0x03pH0x04雨量数据长度1字节后续数据字节数数据内容N字节传感器读数浮点数或整型校验和1字节从节点ID到数据内容的累加和帧尾1字节固定为0x0D这个帧结构简单够用解析起来也方便。汇聚节点收到数据后先找帧头再读节点ID和数据类型然后根据数据长度读取内容最后校验。如果校验失败就丢弃等待下一次发送。提示LoRa通信中如果两个节点同时发送可能会碰撞。简单的解决办法是给每个节点分配不同的发送时间片比如节点1在第0秒发节点2在第2秒发以此类推。虽然效率低一点但避免了碰撞问题。3.3 上位机数据接收与展示上位机可以用Qt或者Python来做。Python的话用PySerial读串口数据用Matplotlib或者PyQtGraph做实时曲线数据存到SQLite数据库里。Qt的话用QSerialPort读串口用QCustomPlot画图数据存到MySQL或者SQLite。对于毕业设计我建议用Python加PyQt5的组合开发速度快代码量少而且图表效果也不错。核心逻辑是串口线程负责读数据解析后通过信号槽发给主界面主界面更新曲线和数值显示同时把数据写入数据库。报警逻辑可以在主界面里做当水位超过阈值时弹出提示或者改变曲线颜色。数据库表的设计可以简单一点一张表存原始数据字段包括时间戳、节点ID、数据类型、数值。另一张表存报警记录字段包括时间戳、节点ID、报警类型、报警值。这样查询和统计都方便。4. 实操过程与核心环节实现4.1 开发环境搭建与工程配置先说一下开发环境的搭建。单片机端用Keil MDK或者STM32CubeIDE我习惯用CubeIDE因为它是免费的而且集成了CubeMX配置工具。安装好之后新建工程选STM32F103C8T6配置时钟树外部晶振8MHz系统时钟拉到72MHz。然后配置外设USART1用于调试打印SPI1用于LoRa模块I2C1用于OLEDADC1的通道0到通道3用于模拟传感器PA0用于雨量计脉冲输入。CubeMX配置完之后生成代码然后在main.c里添加自己的逻辑。这里要注意的是CubeMX生成的代码里外设初始化部分不要随便改自己的代码要写在对应的USER CODE BEGIN和END之间否则重新生成代码时会被覆盖。LoRa模块的驱动需要自己写。SX1278的寄存器比较多但常用的就那么几个RegOpMode设置模式RegFrfMsb/Mid/Lsb设置频率RegPaConfig设置发射功率RegModemConfig1/2/3设置扩频因子和带宽。初始化的时候按顺序配置这些寄存器然后切换到接收模式等待数据。4.2 传感器数据采集与校准传感器采集这块水位和浊度是模拟量需要经过ADC转换。STM32的ADC是12位的参考电压3.3V所以分辨率是3.3/4096≈0.8mV。超声波水位计的输出通常是0到3V对应0到5米所以水位计算公式是水位 ADC值 × 3.3 / 4096 / 3.0 × 5.0。实际使用中这个公式需要校准因为传感器个体差异和电路误差都会影响精度。校准的方法是在已知水位的情况下记录ADC值然后调整公式里的系数。比如实际水位1米时ADC读数是800那系数就是1.0/(800×3.3/4096/3.0)算出来大概是0.0046。把这个系数写进代码里以后读数就准了。浊度传感器的校准类似用标准浊度液或者已知浊度的水样来标定。pH传感器需要两点校准用pH4.0和pH7.0的标准缓冲液。这些校准步骤在论文里要写清楚答辩时老师可能会问。雨量计的处理简单一些每翻一次斗产生一个脉冲单片机用外部中断计数每计数一次代表0.2mm或者0.5mm的降雨量具体看雨量计的规格。代码里用一个变量累加脉冲数定时读取并清零。4.3 LoRa通信的调试与优化LoRa调试是這個项目里最容易卡住的地方。常见的问题是发送端和接收端参数不一致、天线没接好、电源不稳导致模块复位。我建议先用两个LoRa模块加两个USB转TTL模块在电脑上用串口助手测试透传确认模块本身没问题再接到单片机上调。参数一致性检查清单频率必须相同比如都是433MHz、扩频因子相同、带宽相同、编码率相同、同步字相同。这些参数在SX1278的寄存器里配置任何一项不一致都通不了。天线方面433MHz的弹簧天线长度大概是17cm如果用的是PCB天线要注意匹配。天线没接或者接错通信距离会大幅缩短甚至完全通不了。电源方面LoRa模块在发射瞬间电流可能达到100mA以上如果电源供电能力不足电压会被拉低导致模块复位。解决办法是在模块的电源引脚旁边并一个100uF的电解电容和一个0.1uF的陶瓷电容提供瞬态电流。实操心得调试LoRa时先用最大扩频因子SF12和最小带宽125kHz这样灵敏度最高容易通。通了之后再逐步调整参数找到距离和速率的平衡点。4.4 低功耗管理与电池续航估算如果节点用电池供电低功耗管理就很重要。STM32F103的低功耗模式有睡眠、停止和待机三种。睡眠模式下内核停止外设还在跑功耗大概几毫安。停止模式下所有时钟停止功耗降到几十微安。待机模式下功耗最低大概几微安但唤醒后相当于复位需要重新初始化。对于这个项目我建议用停止模式。采集完数据、发送完之后把LoRa模块切到休眠STM32进入停止模式用RTC定时唤醒。唤醒周期根据需求定比如每30秒唤醒一次采集发送然后继续睡。电池续航估算假设节点用2000mAh的锂电池平均电流是2mA包括采集、发送和休眠的平均值那续航就是2000/21000小时大概41天。如果优化一下把发送间隔拉长到5分钟平均电流降到0.5mA续航就能到166天。这个估算在论文里可以写进去体现设计考虑。5. 常见问题与排查技巧实录5.1 硬件调试中的典型故障故障现象可能原因排查方法解决方案单片机不运行供电不足、晶振不起振、复位电路问题测电压、示波器看晶振、检查复位引脚换电源、换晶振、调整复位电容LoRa通信距离短天线问题、功率设置低、遮挡严重检查天线连接、读寄存器确认功率换天线、提高功率、调整节点位置ADC读数跳动参考电压不稳、模拟地干扰、传感器供电不足测参考电压、检查地线布局加LDO、分离模拟地和数字地、加滤波电容OLED不显示I2C地址错误、初始化时序不对用逻辑分析仪抓I2C波形确认地址、调整初始化延时雨量计不计数中断配置错误、上拉电阻缺失、脉冲太窄示波器看脉冲、检查中断配置改中断触发方式、加上拉电阻、加去抖这个表格里的问题都是我实际调试中遇到过的。特别是ADC读数跳动很多人以为是传感器问题其实是电源和地线布局的问题。模拟部分和数字部分共用一条地线数字电路的开关噪声会串到模拟地上导致ADC读数不稳。解决办法是用磁珠或者0欧电阻把模拟地和数字地分开最后在电源入口处单点接地。5.2 软件层面的常见坑软件方面最常见的问题是时序冲突。比如LoRa正在发送数据时如果ADC中断触发可能会打断SPI传输导致数据错乱。解决办法是在LoRa发送期间关闭全局中断发完再开。但这样会影响其他中断的响应所以发送时间要尽量短。另一个坑是浮点数传输。LoRa传输的是字节流浮点数需要转成字节数组再发。如果发送端和接收端的字节序不一致解析出来的数值就是错的。我建议统一用小端模式或者干脆把浮点数乘以100转成整型发送接收端再除以100这样简单可靠。还有看门狗的问题。如果程序跑飞了看门狗能复位但复位后如果问题还在就会反复复位。调试阶段可以先关掉看门狗等程序稳定了再开。开看门狗的时候喂狗的时间间隔要留足余量别卡在临界值上。5.3 通信距离不达标的排查思路LoRa通信距离不达标是最让人头疼的问题。排查的时候按这个顺序来先确认参数一致再检查天线然后看电源最后考虑环境因素。参数方面扩频因子、带宽、频率、同步字这四个必须一致。我遇到过有人频率写成434MHz另一个写成433MHz差了1MHz就通不了。还有同步字默认是0x12如果一边改了另一边没改也通不了。天线方面弹簧天线的长度要匹配频率。433MHz的四分之一波长是17.3cm天线长度接近这个值效果最好。如果天线太短或者太长驻波比会变差发射效率降低。有条件的话用驻波表测一下没条件就目测天线长度。电源方面用万用表测模块供电引脚发射瞬间电压不能跌到2.5V以下。如果跌了就加电容或者换更大容量的电池。环境方面城区河道两边通常有建筑物和树木这些都会吸收和反射无线电波。如果节点之间完全被建筑物挡住通信距离会大幅缩短。解决办法是把汇聚节点放在高处比如楼顶或者灯杆上减少遮挡。避坑技巧调试LoRa时准备一个便携式频谱仪或者带RSSI读取功能的接收端实时看信号强度。RSSI在-120dBm以下基本就通不了了-100dBm左右是可用范围-80dBm以上信号很好。根据RSSI调整节点位置和天线方向比盲试效率高得多。6. 系统联调与论文文档撰写要点6.1 从节点到上位机的全链路联调全链路联调的时候不要一上来就把所有节点都打开先用一个节点加一个汇聚节点调通再加第二个节点逐步增加。每加一个节点观察上位机的数据是否正常有没有丢包有没有数据错乱。联调的顺序是先调节点端的采集和发送用串口打印确认数据正确再调汇聚节点的接收和转发用串口打印确认收到数据最后调上位机的接收和显示确认数据能正确解析和展示。每一步都确认无误后再进行下一步这样出问题容易定位。丢包率的测试方法是节点连续发送1000包汇聚节点统计收到多少包丢包率就是1000-收到数/1000。城区环境下丢包率在5%以内是可以接受的如果超过10%就要检查天线、功率和干扰源。6.2 毕业设计论文的结构建议论文的结构一般包括绪论、系统总体设计、硬件设计、软件设计、系统测试、总结与展望。绪论部分写研究背景和意义引用一些河道管理的现状和无线传感网络的应用。总体设计部分画系统框图说明各模块的功能和关系。硬件设计部分详细写芯片选型、电路原理图和PCB设计。软件设计部分写程序流程图和关键代码。测试部分写测试方法和测试结果用表格和图表展示数据。总结部分写完成的工作和不足。查重方面硬件描述和软件流程这些内容容易重复建议用自己的话重新组织不要直接复制网上的内容。图表可以自己画数据用自己的实测数据这样查重率会低很多。6.3 答辩时容易被问到的几个问题答辩时老师通常会问几个问题为什么选LoRa不选其他通信方式低功耗是怎么实现的数据精度怎么保证系统的创新点在哪里第一个问题按前面选型分析的逻辑回答就行。第二个问题要讲清楚休眠唤醒机制和电源管理策略。第三个问题要讲校准方法和误差分析。第四个问题可以从多参数融合、自适应发送间隔、异常报警算法这些角度去说。还有一个常见问题是如果节点数量增加到100个系统还能正常工作吗这个问题考察的是对LoRa网络容量的理解。LoRa的容量受限于信道带宽和扩频因子节点多了之后碰撞概率增加需要做时分或者频分复用。可以回答通过分配不同的发送时间片和频率通道系统可以扩展到上百个节点但需要更复杂的调度算法。7. 个人实操体会与扩展思路这个项目我从头到尾做了大概两个月中间踩了不少坑也积累了一些经验。最大的体会是硬件调试比软件调试麻烦得多软件问题可以单步跟踪硬件问题往往要靠经验和仪器。所以建议在做PCB之前先用开发板和模块搭一个最小系统把关键电路验证一遍确认没问题再画板子。这样能省下不少打板和焊接的时间。另一个体会是通信协议的设计要留余量。我一开始设计的帧结构只有节点ID和数据类型后来想加电池电压上报发现没地方放。所以帧结构里最好预留几个字节的扩展位以后加功能不用改协议。扩展方面这个系统还可以做几个方向一是加GPS模块让节点能上报自己的位置方便移动部署二是加太阳能充电让节点在户外长期运行不用换电池三是把上位机改成云端部署用MQTT协议上传数据手机也能查看。这些扩展在论文的展望部分可以提一下体现对系统的深入思考。最后说一个实际部署时的小技巧节点安装的时候尽量把天线朝上远离金属物体和水面。水面会反射无线电波如果天线离水面太近反射波和直射波干涉会导致信号忽强忽弱。把节点固定在岸边的立杆上天线离水面至少1米以上通信会稳定很多。