ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

C语言基于STM32的水质检测系统:从传感器到云端的完整方案

C语言基于STM32的水质检测系统:从传感器到云端的完整方案 简介本资源是一套基于STM32F103系列单片机开发的嵌入式水质监测系统完整工程面向嵌入式初学者、电子类课程设计学生及物联网实践开发者解决水质多参数实时采集与云平台上传的核心需求。系统采用标准C语言编写支持PH值、TDS总溶解固体浓度及水温三参数同步检测并通过ESP8266或类似Wi-Fi模块将数据稳定上传至OneNet物联网平台具备完整的硬件驱动ADC、I2C、定时器等、传感器通信协议及网络传输逻辑。压缩包共280个文件含72个头文件.h、46个源码文件.c、46个编译中间文件.o及调试配置、链接脚本、Hex/AXF固件等整体大小为11.12MB结构符合Keil MDK工程规范便于直接编译烧录与二次开发。已有2038人学习下载提供可运行的全功能工程模板、清晰的模块化代码组织及典型外设驱动实现参考是理解嵌入式传感采集、RTOS轻量级应用与IoT端云协同的优质实践案例。 做水质检测项目的人不少但能把传感器、主控、软件代码串成一套完整系统的真不多见。这个标题我一看就很熟C语言基于STM32的水质检测系统简简单单一个压缩包里面装的通常是源码、原理图、论文文档和PCB工程正是高校毕设、电子设计竞赛和物联网课设里最常被翻牌的一种项目形态。它解决的是这样一个问题用一块几十块钱的STM32开发板接上TDS溶解性总固体、pH、温度等传感器把测量结果实时显示在屏幕上同时通过串口或无线模块上报到上位机甚至能联动继电器做自动处理。听上去不复杂但真正动手做的时候ADC采集、信号调理、滤波、标定、通信协议、状态机……每一个环节都能卡死人。适合谁来参考一是电子信息、自动化、物联网相关专业的应届生拿它做毕业设计或课程设计能快速理解“硬件软件”的完整流程二是刚想把单片机从点灯带到“带传感器数据处理”阶段的新手三是想给鱼缸、养殖场做低成本水质监测方案的爱好者。下文我会按照从方案选型到代码实现、再到调试标定的顺序把整套系统的关键细节拆开讲代码工程部分会直接给出C语言的组织方式和核心片段。1. 项目概述与整体设计思路1.1 这套水质检测系统能做什么从功能上看这套系统大致分成四个环节采集、处理、显示、上报。采集端负责把水里的物理量变成电信号常见的检测项包括TDS、pH值、温度进阶一点会加浊度、溶解氧、余氯。TDS反映的是水中可溶性固体总量单位是ppm或者mg/L日常判断自来水、纯净水、鱼缸水质都会用到pH值体现酸碱度是水质健康程度的核心指标温度则是几乎所有水质参数都要用到的补偿基准没有温度数据TDS和pH的换算都不准。处理环节由STM32承担它要把传感器送来的模拟电压通过ADC变成数字量再做滤波、标定、温度补偿最终换算成用户能看懂的水质数值。显示通常在0.96寸OLED上完成滚动显示TDS、pH、温度、电量或报警状态上报则是通过串口打印或ESP8266模块把数据发到上位机、云端实现远程监控。有些版本还会加一个继电器当某指标越限时自动启动水泵、换水阀或投药装置。你可能会觉得功能多但实际拆开看这套系统的核心链路并不长模拟信号进来ADC采样C语言做滤波和标定最后输出到显示和通信。真正决定系统好不好用的不是某个模块多高级而是信号链路上每一步是否处理干净了。1.2 为什么是STM32C语言而不是51单片机或Arduino这是很多新手会问的问题。先说结论STM32在这个项目里的优势是“外设够用、处理能力余量大、生态资料多”C语言则是嵌入式开发里绕不开的主语言。51单片机最大的问题不在能不能跑而在外设实在太简陋。ADC通常只有8~10位多路扫描还要软件切换通道采样过程中CPU被占得死死的内部Flash也小烧个标准库加OLED驱动就快满了调试手段基本靠串口打印真出问题定位很痛苦。Arduino虽然上手快但它的优势在快速原型验证真要写一套带标定参数存储、状态机、故障处理的产品级代码靠几十行的setup和loop函数撑不起来而且Arduino自带库隐藏了太多底层细节做完这个项目你还是不明白寄存器到底发生了什么。STM32F103C8T6这种芯片72MHz主频3个ADC、多个定时器、USART、I2C、SPI全都有跑这套系统绰绰有余。更重要的是STM32的生态已经非常成熟HAL库配合CubeMX配置外设能省掉大量底层时间遇到问题随便一搜江科大或者各路博主的教程都能帮你定位。C语言在其中的角色从底层寄存器操作到应用层的状态机、滤波算法、协议解析全部贯穿。做完这个项目你对指针、结构体、函数指针、数组、宏定义这些C语言核心特性的理解会比刷一百道题都深刻。2. 硬件电路与传感器选型细节2.1 传感器选型TDS、pH、温度分别怎么挑市面上的水质传感器五花八门价格从十几块到几千块都有。毕设和课设场景下我建议按“够用、有成熟模块、资料多”这三个原则来选没必要一开始就上工业级传感器。TDS传感器一般长这样两根或四根金属电极通过测量水的电导率来推算TDS。常见模块会把电极信号调理成0~2.3V或者0~3.3V的模拟电压主控直接读ADC就行。选的时候注意两点一是探头材质不锈钢电极耐腐蚀适合长期泡在水里二是模块输出是否已经做了交流激励因为直流激励会让电极极化读数漂得厉害。很多便宜模块其实是直流方案短暂测试还行放十分钟数据就开始乱跳这种就得在软件里做更多的滤波处理否则没法用。pH传感器是这套系统里最“娇气”的部分。它的核心是玻璃电极和参比电极产生的电压信号非常微弱内阻极高通常几十兆欧到几百兆欧。所以模块上必须有一颗高输入阻抗的运放做阻抗变换和信号放大典型模块如pH-4502C输出0~5V或0~3V的模拟电压pH范围0~14对应不同的电压值。选模块时确认它有没有信号调理电路别买那种裸电极STM32的ADC直接接上去读数基本是废的。温度传感器就简单多了DS18B20和NTC二选一。DS18B20走单总线协议数字输出精度可以到0.5℃以内接线就一根数据线非常适合初学者NTC成本更低但需要自己做分压电路和查表换算精度受电阻误差影响大。考虑到温度是用来做补偿的建议直接用DS18B20省事且稳定。2.2 信号调理与电源设计别让模拟信号毁在布线上很多系统做出来跑不起来不是代码问题而是硬件连接和电源处理没到位。水质检测项目里最典型的坑就是模拟小信号被数字噪声淹没了。STM32跑在72MHzIO口翻转、OLED刷新、无线模块发射都会在电源和地线上产生毛刺。如果传感器的模拟信号线走在数字信号线旁边或者供电直接从数字3.3V上拉出来ADC采到的数据往往跳得像心电图。解决方法不复杂模拟部分和数字部分在PCB上分区走线ADC采样引脚附近加一个0.1uF去耦电容传感器模块的电源入口加一个磁珠或10Ω电阻隔离必要时用独立的LDO给传感器供电。供电方案上整个系统用5V直流输入板载一颗AMS1117-3.3给STM32和OLED供电TDS和pH模块直接吃5V因为它们的运放电路需要5V才能保证输出动态范围。STM32的ADC参考电压VREF一般直接接3.3V但要注意很多开发板上的3.3V不是精密基准芯片之间存在偏差实测可能是3.27V。如果代码里硬按3.3V计算电压最终TDS和pH值会整体偏大或偏小。严谨的做法是用万用表实测VREF电压作为ADC换算的基准或者用STM32内部的VREFINT通道做片上校准。3. C语言工程实现与核心代码拆解3.1 代码目录规划与模块划分一套能长期维护的单片机工程代码组织一定要清晰。我见过不少毕设代码所有功能堆在一个main.c文件里写了上千行循环里又是采样又是显示又是按键改一个模块就得牵动全局这种代码看起来“能用”但实际上可读性和可移植性都很差。做这个水质检测系统我会把工程按功能拆成这几个模块main.c负责初始化和主循环调度adc.c负责ADC和DMA配置把原始采样值存到全局缓冲区sensor.c负责从ADC缓冲区取数据做滤波和电压换算再调用标定参数得到TDS和pH值ds18b20.c负责读温度display.c负责OLED的绘制和刷新uart.c负责串口打印和协议解析app.c负责主状态机把采集、显示、上报、报警这些动作串起来calib.c负责标定参数的读取和写入Flash。模块化带来两个直接好处第一每个文件只做一件事代码量小调试时定位问题快第二以后想换传感器或者换显示设备只需要改对应的模块不用动主逻辑。C语言里的头文件就是模块的“接口说明书”我习惯在头文件里只暴露必要函数内部的静态变量和Helper函数都用static修饰防止外部误调用。这种做法借鉴了面向对象的封装思想用C语言完全可以实现。3.2 ADCDMA采样多点扫描CPU全程不参与水质传感器输出的是缓变信号不需要很高的采样率但需要采样稳定、抗干扰。我的方案是配置ADC1的三个通道分别接TDS、pH和一个预留通道比如备用的浊度传感器用扫描模式加连续转换配合DMA循环模式让硬件自动把转换结果搬进内存缓冲区。用STM32CubeMX配置非常直观ADC1的IN0、IN1、IN2三个通道开启扫描模式转换模式设为ContinuousDMA设为Circular。在代码里定义一个16位无符号数组adc_buf[3]DMA会不停地把三通道的转换结果写进去CPU完全不用管采完直接拿数据就行。采样率不需要拉满实际测试下来人眼看着稳定大概需要每秒10次以上的有效更新但DMA连续跑起来是远远超这个速度的。为了避免数据被读一半时DMA又写入导致撕裂我通常用DMA的半传输完成中断或者直接把缓冲区数组放在不会被编译优化掉的全局区在主循环里一次性memcpy出来再处理。这里有个关键参数要交代清楚ADC采样时间。STM32的ADC是逐次逼近型采样时间太短内部采样电容充不满读数会偏小。我用的是ADC_SAMPLETIME_239CYCLES_5也就是最长那档配合RCC的PCLK2分频到12MHz能最大程度保证采集准确。ADC时钟不要超过14MHz这是芯片手册给出的上限超了转换结果会非线性。电压换算公式很简单float adc_to_voltage(uint16_t raw) { return (float)raw * 3.3f / 4096.0f; }注意3.3这个值只是个示例前面我提过最好用实测值替换。如果你的系统用了内部基准校准这里的分母可以改成从VREFINT换算出来的实际参考电压精度还能再提一点。3.3 数据处理滤波、电压换算、斜率标定ADC裸数据不能直接用这是水质检测项目里最容易踩的坑。传感器模块本身就有噪声电源上又有纹波ADC采样结果经常在几个码值之间来回跳。如果不滤波直接显示TDS数值会在几十ppm范围内乱飘观感非常差。我常用的是一阶滑动平均滤波维护一个环形缓冲区每次新采样进来就替换最旧的数据然后算平均值。窗口长度取8到16个点在实时性和平滑性之间比较均衡。为了去掉偶发尖峰我还会再加上中位值滤波把连续5个采样排一下序取中间值作为有效值然后再进滑动平均。两段滤波串起来之后TDS读数基本能稳定在个位数变化这在实际展示中足够用了。TDS的换算要分情况看。如果是买回来的成品TDS模块它内部通常已经用运放阵列把电导率换算成了TDS值输出的电压直接对应ppm这种就简单直接曲线拟合就行。如果是自己用裸电极做电导率测量则要先把电压转成电导率EC单位uS/cm再乘系数换算成TDS。常见做法是用公式校准float ec_to_tds(float ec, float temp) { // 温度补偿到25℃的基准电导率 float ec_25 ec / (1.0f 0.02f * (temp - 25.0f)); // k是TDS与电导率的比例系数通常取0.5~0.9按水质情况调整 float k 0.7f; return ec_25 * k; }pH值的换算思路类似但更具线性。pH电极在理想情况下每1个pH单位对应59.16mV的电势变化输出电压和pH呈线性关系。我用两点标定法确定直线的斜率和截距先用pH6.86的标准缓冲液测出一对电压和pH值再用pH4.0的标准液测出另一对然后算出斜率和零点偏移。typedef struct { float slope; // 电压变化量 / pH变化量mV/pH float offset; // pH7时的电压mV } PhCalib_t; PhCalib_t g_ph_calib { -59.16f, 0.0f }; float ph_calc(float voltage_mv) { return 7.0f (voltage_mv - g_ph_calib.offset) / g_ph_calib.slope; }这个结构体和标定参数的存储直接相关后面会在Flash保存章节再讲。3.4 主逻辑状态机与显示刷新主程序不建议用一个大while套所有功能的写法那样按键、显示、通信之间容易互相卡住。我用一个简单状态机系统上电后进入初始化然后循环执行“采集处理→显示刷新→串口上报→按键检测→报警判断”这几个状态。状态机的好处是逻辑清晰而且方便扩展。如果某次采集耗时长可以先处理其他状态如果温度异常可以跳到错误处理状态。对水质检测这种多任务不强、又希望代码可维护的场景状态机比RTOS更轻量也更容易让评审老师看懂。显示刷新上OLED是I2C接口I2C时钟一般400kHz刷新一屏全信息大约要几十毫秒如果一直刷CPU浪费很大。我习惯用1秒定时器来触发显示刷新中间用局部区域更新代替整屏刷新比如只有TDS数值变化时才重绘数字区域图标和文字不变。这样不仅减少了I2C通信量也减少了OLED的残影和闪烁问题。OLED的驱动库我用过u8g2也用过自写的SSD1306驱动。u8g2功能全但ROM占用比较大F103C8T6的64KB Flash如果再加上其他库空间会比较紧张。我也试过自写精简驱动只保留显示字符串和数字的函数最终能省出15KB以上Flash。毕设这种场景压缩包里有完整自写驱动往往比套一个大而全的库更讨喜。4. 串口协议与物联网上报4.1 串口协议怎么设计最省心串口在这套系统里承担两个任务一是调试时打印日志二是和ESP8266这种无线模块通信。调试日志怎么随意都行但和无线模块通信必须有一个稳定的帧协议否则数据乱了你自己都看不懂。我常用的简单协议是这么设计的帧头固定两个字节0xAA 0x55紧接着是数据长度、命令字、数据区最后是校验和。数据区里依次放TDS、pH、温度、报警标志每种数值占2字节避免浮点数在网络上传输的字节序问题。发送端用memcpy把float拆成字节再拼帧接收端再拼回去。C语言里这属于典型的字节流处理场景会用到联合体或指针强转正好练手。#pragma pack(1) typedef struct { uint16_t tds; // 实际值 * 100 int16_t ph; // 实际值 * 100 int16_t temp; // 实际值 * 100 uint8_t alarm; } WaterData_t; #pragma pack()数据区里我用定点数代替浮点数把TDS乘100塞进uint16_t这样传输过程不会因为浮点格式差异而出错。实际测试下来串口9600波特率传这帧数据一秒钟传20次都没问题远够用了。关键是接收端要能正确判断帧边界处理好粘包半包这里就要用到状态机解析每收到一个字节就判断当前处于哪个状态。4.2 ESP8266接入从AT指令到MQTT如果要把数据放到云平台ESP8266是最便宜的方案十几块钱。它的用法分两种AT指令模式和SDK二次开发模式。水质检测系统这种数据量小、上报频率低的应用AT指令就够。基本流程是STM32通过串口2给ESP8266发AT指令配置WiFi和TCP连接把数据通过TCP socket发到服务器。第一步配置工作模式ATCWMODE1 // Station模式 ATCWJAPSSID,密码 // 连接WiFi ATCIPSTARTTCP,47.xx.xx.xx,1883 // 连接服务器 ATCIPSEND数据长度 // 进入透传发送模式这里有一个很常见的坑AT指令返回的时间不确定ESP8266上电后需要好几秒才启动完成如果STM32复位后立刻发指令大概率没响应。所以代码里必须加超时和重试机制我第一次写的时候就是没做等待开机后系统根本连不上WiFi最后在串口日志里看到一堆AT指令被丢弃才反应过来。更稳妥的做法是给ESP8266刷MQTT固件把数据以MQTT协议发到支持MQTT的物联网平台。这样不用自己写TCP协议栈平台端接入也更标准化。STM32只需要按MQTT的PUBLISH报文格式组包然后通过串口透传出去。代码里要处理的是报文长度、主题、QoS这些字段涉及的结构体和字节序转换正好又是对C语言基本功的一次检验。5. 标定与温度补偿数据靠谱的关键5.1 为什么出厂数据不能直接用很多第一次接触水质传感器的同学会有个误区模块买回来手册上说“输出电压对应多少TDS”于是代码里直接套公式就以为完了。但实际测试会发现不同批次的电极灵敏度、运放零点都不一样出厂曲线只能作为参考直接用来测量误差可能超过20%。以pH传感器为例玻璃电极的老化速度挺快用半个月零点就能偏出去将近0.2个pH单位。如果系统长期在线运行不重新标定测出来的数据会越来越不准。因此一套完整的水质检测系统必须预留标定功能让用户能在现场用标准液体修正参数这才是工程实践和纯demo之间的分水岭。标定的本质是求传感器输入输出曲线的斜率和截距。TDS用两点标定标准液选电导率已知的溶液比如84uS/cm和1413uS/cm两种pH用两点或三点标定常用标准缓冲液是4.0、6.86、9.18。标定完成后把斜率和截距写进STM32内部Flash保存系统重启后仍然有效。5.2 两步标定法和温度补偿实操标定流程做成菜单式交互比较友好长按按键进入标定模式屏幕提示“浸入标准液1按确认”系统采集稳定后的ADC值再提示换上标准液2同样流程走完程序内部自动解算出斜率和截距。具体到实现标定参数用一个结构体统一管理然后通过内部Flash的扇区保存。STM32F103的Flash不能按字节写必须按扇区擦除再写入我的做法是把标定参数放在最后一个扇区每次进入标定模式时先读出来用户重新标定后再擦除重写。这里有个注意事项频繁擦写Flash会缩短寿命虽然理论上能写上万次但也不要每秒钟都写标定完成写一次就够了。温度补偿这块最容易被忽略。电导率和pH测量都受温度影响电导率的温度系数大约是每摄氏度2%左右pH电极的斜率本身也会随温度变化。经验公式是电导率补偿到25℃基准前面代码里已经给出来了pH的温度补偿比较复杂简单实现可以只补偿斜率float ph_slope_temp(float slope_25, float temp) { // 以25℃为基准温度每升高1℃斜率按0.34%/℃修正近似值 return slope_25 * (1.0f 0.0034f * (temp - 25.0f)); }实际的补偿系数不同电极差异很大最好是看电极手册。我自己的经验是把温度补偿函数独立出来这样不管传感器怎么换主逻辑都不用改只要改补偿系数即可。这种设计思路本身也值得在C语言代码评审时作为亮点提。6. 调试排错我踩过的坑和排查清单6.1 ADC数据跳动、偏移、悬空ADC读出来的值乱跳这是水质检测项目里最常见的故障。先别急着改代码用万用表量一下传感器模块的输出引脚看电压是否稳定。如果硬件电压本身就在跳那是传感器供电或信号调理的问题如果硬件电压稳定但ADC读数乱跳问题在ADC配置和代码。我遇到过两个特殊情况。一是ADC引脚没有配置成模拟模式默认是浮空输入结果采样值满量程乱跳代码里漏写了GPIO初始化检查半天才发现。二是DMA缓冲区没有清零系统复位后缓冲区里残留上一次的数据上电瞬间会显示一个巨大的异常值。解决方法是定义一个全局变量在主函数入口处用memset清零再启动DMA。如果ADC读数偏大或偏小优先查参考电压。VREF引脚如果有跳线帽连接3.3V以外的情况或者板上LDO实际输出3.27V那代码里的换算基准必须改。用万用表实测是一个比较稳妥的做法比相信芯片手册快多了。6.2 传感器漂移与接线干扰传感器放水里几分钟后数值开始缓慢漂移这通常不是代码问题而是探头本身还没有稳定。TDS电极在刚放入水样时电极表面会有一层电荷迁移过程需要1到5分钟才能稳定pH玻璃电极更是号称“至少要浸泡24小时才能获得稳定读数”虽然实际使用中没这么夸张但至少要让电极在保存液中充分活化。接线干扰也很好排查把传感器模块和单片机用杜邦线连接信号线旁边再走一根电源线示波器上能看到明显的串扰。遇到这种情况最有效的方法是换屏蔽线或者把信号线远离大电流走线同时缩短导线长度。如果项目进入PCB阶段除了分区布线还要在ADC引脚入口加一个RC低通滤波器时间常数取1ms左右能滤掉大部分高频噪声。还有个小坑DS18B20的单总线要求上拉电阻很多开发板上虽然引出了接口但不一定带了4.7kΩ上拉。我用某款板子时温度读出来一直是-55℃就是上拉电阻缺失导致的。这时外接一个4.7kΩ电阻到3.3V就能解决。6.3 DMA丢数据、OLED花屏、Flash写入异常DMA丢数据这个问题我之前遇到的情况是ADC初始化前DMA时钟没开DMA通道配置成外设到内存模式但外设地址写错了导致数据乱跳。排查DMA问题要按顺序确认RCC里DMA时钟、DMA通道映射ADC1对应DMA1_Channel1、外设基地址、内存地址、传输方向、缓冲区大小、工作模式。如果配置都没问题剩下的优先级问题也很重要DMA中断优先级低于某个高频中断时可能出现丢数据我习惯把DMA中断优先级设高一点。OLED花屏的常见原因是I2C地址不对或者没有外部上拉电阻。SSD1306的I2C地址通常是0x3C或0x3D代码里配置错了屏幕要么没反应要么花屏。如果系统里同时挂了其他I2C设备还要注意总线上拉电阻并联后总阻值是否太小阻值太低了信号边沿会变差显示就花。把标定参数写进Flash后系统重启发现参数是乱的这个问题我遇到过一次。原因是写Flash之前忘了擦除扇区数据虽然写进去了但和原来的0xFF混在一起读出来就成了乱码。另外Flash写入要在Flash空闲状态下进行并且需要关闭全局中断否则写入过程中被中断打断会导致写入失败。代码里我加了DMA和中断临界区保护之后再没出过问题。7. 项目打包内容与二次开发建议7.1 压缩包里一般有什么像“水质检测-单片机.zip”这种命名压缩包内的标准配置通常包括这几块源码工程KEIL MDK工程或CubeMX生成工程、原理图PDF、PCB工程文件、元器件清单BOM、论文或设计报告Word、演示视频可能还有仿真工程。拿到包之后建议按“先看文档、再跑Demo、最后拆代码”的顺序入手。先读论文里的系统框图和功能描述快速理解设计意图然后打开工程把环境搭好编译下载跑通Demo确认硬件接线和串口输出最后再逐模块读代码把ADC采样、滤波、标定逻辑对应到电路图上这是最快的学习路径。但要注意网上流传的代码质量参差不齐有的工程在旧版HAL库上写的用新版CubeMX打开会报一堆错有的代码变量名全是拼音缩写读起来很吃力。我自己的习惯是拿到任何代码包先把工程里的全局宏和头文件列表过一遍梳理由上到下的依赖关系再用git做一次初始化方便后续改坏了回滚。7.2 还能往哪个方向升级这套系统做到现在这一步“能用”已经没问题了但离“好用”还有不少距离。我给几个后续扩展方向按优先级排列每个的成本都不高。第一是加浊度传感器。浊度传感器也是一个模拟输出模块信号调理方式类似TDS只需要占用一个ADC通道在代码里把滤波和标定流程复制一份即可。第二是加继电器和自动控制逻辑比如pH低于阈值时启动加药泵温度过高时启动散热风扇这就把检测系统变成了闭环控制系统难度和档次都会上去。第三是改用低功耗方案把STM32从72MHz降频到32MHz进入STOP模式定时唤醒采样可以实现电池供电适合水产养殖野外部署场景。第四是本地数据记录加一块SPI Flash或者SD卡定时存储历史数据并预留USB读取接口这样脱离上位机也能保有数据记录能力。扩展的时候C语言的模块化设计会帮大忙现有的adc.c、sensor.c直接复用新增模块只需要提供对应的头文件接口主状态机里挂一个新的状态就行。做这个项目我个人最大的体会是水质检测的难点从来不在单片机本身而在从“传感器出来的模拟电压”到“屏幕上显示的最终数值”这整条链路上每一环的误差都在累积。你把ADC采样时间调长一档、把滤波窗口加大一点、把基准电压实测校准一番数值变化肉眼可见。很多同学问我说为什么我的TDS一直显示380多怎么调都不一样我让他们先量一下VREF结果发现是3.19V而代码里写的是3.3V就这一项就差了3%。所以如果你也打算复现或者改造这个项目我的建议是先花时间把传感器标定做扎实再用软件滤波把数据稳住最后才去折腾显示和云平台。基础链路如果糊里糊涂后面所有花哨功能都是空中楼阁。最后再分享一个小技巧标定参数不管存没存Flash都建议在串口日志里打印出来复位后先核对一遍参数再进主循环能帮你少走很多“程序好像没问题但数据就是不对”的弯路。本文还有配套的精品资源点击获取
返回列表