当前位置: 首页 > news >正文

STM32之水质浑浊度传感器模块

目录

一、模块概述

二、模块简介

2.1 模块特点

2.2 电气特性

2.3 模块接口说明

2.4 结构与工作原理

2.5 实际应用注意事项

三、硬件设计

3.1 硬件组成

3.2 硬件连接

四、软件设计

4.1 开发环境配置

4.2 关键代码实现

五、功能实现与优化

六、常见问题解决

七、总结


一、模块概述

        浑浊度是衡量水体清澈程度的重要指标,广泛应用于水质监测、污水处理、饮用水生产等领域。浑浊度传感器是一种基于光学传感原理的模拟输出传感器,通过测量水中悬浮物对光的散射程度来间接反映水的浑浊度。本指南详细介绍了如何利用性价比较高的STM32F103C8T6最小系统板及其标准外设库,实现对浑浊度传感器数据的准确采集与处理。

二、模块简介

模块实物图:

2.1 模块特点

- 工作原理: 采用光学感应,内置红外LED光源和光电晶体管。
- 输出信号: 模拟电压信号输出,浑浊度越高,输出电压越高。
- 测量范围: 通常可测量0~1000 NTU ( Nephelometric Turbidity Unit ) 或更宽范围(具体需参考产品手册)。
- 易于集成: 接口简单,只需供电和读取模拟电压即可。
- 需注意点: 测量结果易受环境光、液体颜色、气泡等因素干扰。

2.2 电气特性

- 工作电压: 通常为5V DC(务必确认模块规格书,部分型号可能为3.3V-5V宽电压)。
- 输出信号: 0 ~ 4.5V 模拟电压(在5V供电下)。
- 工作电流: 约40mA。

2.3 模块接口说明

浑浊度传感器模块通常引出3个引脚(有的模块多一个DO数字信号输出引脚):

编号名称功能
1GND供电电压负极
2VCC供电电压正极
3AO模拟信号输出引脚

2.4 结构与工作原理

        浑浊度传感器通过测量水中悬浮固体总量(TSS)的变化,来测量水中悬浮颗粒物的光透过率和散射率,利用光来检测悬浮颗粒物。随着 TTS 增加,液体浊度水平增加。
        传感器头部包含一个红外LED和一个光电晶体管。LED向水中发射光线,水中的悬浮颗粒会导致光线发生散射。散射光的角度和强度与颗粒物的数量(浑浊度)相关。光电晶体管用于检测与入射光呈90°方向的散射光强度,并将其转换为电流信号,内部电路再将电流信号处理并放大为一个线性的电压信号输出。

        传感器输出电压值大小受温度影响,输出电压与温度曲线关系如下图所示。进行浊度测量时需进行温度补偿以保证测量精度。

温度校正公式:∆U=- 0.0192×(T-25)

上式中∆ U 为温度变化引起的电压差; T 为当前测量温度值。

2.5 实际应用注意事项

1.  校准: 输出电压与浑浊度并非简单的线性关系,通常需要根据传感器手册提供的曲线或通过实验数据进行校准(例如使用标准浊度液),建立电压值与NTU值的对应公式。
2.  环境光屏蔽: 传感器头部应做好遮光处理,防止环境光进入干扰测量结果。
3.  气泡干扰: 水中的气泡会强烈散射光线,导致读数异常偏高,测量时应避免气泡。
4.  污染: 长期使用后,传感器光学窗口可能会被污染,需要定期清洁以保证精度。
5.  电源去耦: 在VCC附近并联一个100nF的电容到GND,以抑制电源噪声,提高ADC采样稳定性。

三、硬件设计

3.1 硬件组成

- 主控单元: STM32F103C8T6最小系统板
- 传感单元: 浑浊度传感器模块
- 供电电源: 5V USB电源(同时为开发板和传感器供电)
- 连接线: 杜邦线若干

3.2 硬件连接

STM32F103C8T6引脚浑浊度传感器引脚功能说明
5VVCC为传感器供电
GNDGND共同地
PA1 (或其他ADCx)AOUT模拟信号输入

四、软件设计

4.1 开发环境配置

1.  IDE: Keil uVision5 MDK
2.  固件库: 使用STM32F10x_StdPeriph_Lib_V3.5.0标准外设库。

4.2 关键代码实现

#include "stm32f10x.h"
#include "stdio.h" // 如果使用printf重定向// 简单的延时函数
void Delay_ms(uint32_t nCount) {for(; nCount != 0; nCount--) {for(uint32_t i = 0; i < 8000; i++);}
}// ADC初始化函数
void ADC1_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;// 1. 开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);// 2. 配置PA1为模拟输入模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 复位并配置ADC1参数ADC_DeInit(ADC1);ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;      // 单通道,非扫描模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;// 单次转换模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 软件触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 1;            // 要转换的通道数量为1ADC_Init(ADC1, &ADC_InitStructure);// 4. 配置ADC通道规则组// 参数:ADCx, 通道号(PA1对应ADC1的通道1),采样顺序1,采样时间55.5个周期ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);// 5. 使能ADCADC_Cmd(ADC1, ENABLE);// 6. ADC校准(提高精度)ADC_ResetCalibration(ADC1); // 重置校准寄存器while(ADC_GetResetCalibrationStatus(ADC1)); // 等待重置完成ADC_StartCalibration(ADC1); // 开始校准while(ADC_GetCalibrationStatus(ADC1)); // 等待校准完成
}// 读取指定ADC通道的转换值
uint16_t Get_ADC_Value(uint8_t ch) {// 1. 配置规则组通道(这里固定为通道1,可根据参数ch修改使其更通用)// ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5);// 2. 启动软件转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 3. 等待转换结束while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);// 4. 清除EOC标志位并返回转换结果ADC_ClearFlag(ADC1, ADC_FLAG_EOC);return ADC_GetConversionValue(ADC1);
}int main(void) {uint16_t adc_value = 0;float voltage = 0.0f;// float turbidity_ntu = 0.0f; // 用于存储计算后的NTU值// 初始化系统时钟等(默认使用内部8MHz RC振荡器,HCLK=72MHz)// 此处省略SystemInit(),因为最小系统板通常已配置好时钟ADC1_Init(); // 初始化ADCwhile(1) {// 1. 读取ADC原始值(12位精度,0-4095)adc_value = Get_ADC_Value(ADC_Channel_1);// 2. 将ADC值转换为电压值(单位:伏特)//    假设Vref+ = 3.3V (STM32F103C8T6的VDDA通常接3.3V)voltage = (float)adc_value * 3.3f / 4095.0f;// 3. (可选) 将电压值转换为浑浊度值(NTU)//    这一步需要根据传感器的校准曲线或公式进行。//    例如:turbidity_ntu = voltage * k + b; (k和b为校准系数)//    示例公式,请根据实际传感器校准修改!//    turbidity_ntu = -1120.4 * voltage * voltage + 5742.3 * voltage - 4352.9;// 4. 打印结果(需实现printf重定向至串口,此处省略实现)// printf("ADC: %d, Voltage: %.2f V\r\n", adc_value, voltage);// 或者通过其他方式显示,如OLED// 5. 延时一段时间后进行下一次采集Delay_ms(1000); // 每秒采样一次}
}

1.  初始化 (ADC1_Init): 
    - 首先开启GPIOA和ADC1的时钟。
    - 配置PA1引脚为模拟输入模式(GPIO_Mode_AIN),这是ADC输入的正确模式。
    - 使用ADC_Init函数设置ADC的工作模式为独立、单次转换、软件触发、数据右对齐。
    - 使用ADC_RegularChannelConfig指定要转换的通道(通道1)及其采样时间(55.5周期,提供足够的采样时间保证精度)。
    - 使能ADC并进行校准,这是一个重要步骤,可以减少内部电容带来的误差。

2.  读取转换值 (Get_ADC_Value):
    - 该函数启动一次软件转换,并等待转换结束标志(EOC)置位。
    - 读取ADC1->DR寄存器中的转换结果并返回。由于是单通道,结果直接存放在这个寄存器中。

3.  主循环 (main):
    - 循环调用Get_ADC_Value获取原始ADC值。
    - 根据ADC的参考电压(假设为3.3V)将原始值(0-4095)转换为实际的电压值。
    - 关键步骤: 根据校准数据将电压值转换为有物理意义的浑浊度值(NTU)。
    - 最后延时1秒,控制采样频率。

五、功能实现与优化

1.  基本功能实现: 上述代码成功实现了对TSW-30传感器输出电压的周期性采样和电压值计算。
2.  软件滤波: 为了抑制随机噪声,可以在软件中实现滤波算法。例如:
    - 多次采样求平均: 连续采样N次(如10次),然后取算术平均值作为最终结果。
    - 中值滤波: 采样N次,排序后取中值,能有效滤除脉冲干扰。

六、常见问题解决

- Q1: 读取的ADC值始终为0或4095。
  - A1: 检查硬件连接是否正确可靠,特别是GND是否共地。检查传感器供电电压是否正常。确认STM32的ADC引脚配置是否正确(必须为模拟输入`GPIO_Mode_AIN`)。

- Q2: 读数波动非常大,不稳定。
  - A2: 
    1.  检查电源质量,在传感器VCC和GND之间并联一个100nF和一个10uF的电容。
    2.  实施软件滤波(如平均值滤波)。
    3.  确保传感器光学窗口清洁且无气泡,并处于遮光环境中。
    4.  尝试增加ADC的采样时间(ADC_SampleTime),让采样电容充分充电。

- Q3: 转换得到的电压值/浑浊度值不准。
  - A3: 
    1.  确认STM32的ADC参考电压是否准确。如果板载LDO质量差或负载重,3.3V可能不准,可以使用外部精密基准电压源。
    2.  必须进行传感器校准。未经校准的读数只有相对参考意义,无法反映绝对物理值。

- Q4: 传感器对光线变化没反应。
  - A4: 检查传感器供电。用万用表测量AOUT引脚对地电压,并尝试遮挡传感器探头,观察电压是否有变化。若无变化,可能是传感器已损坏或接线错误。

七、总结

        本文详细阐述了如何使用STM32F103C8T6最小系统板和标准库驱动浑浊度传感器。核心在于正确配置ADC外设以读取传感器的模拟电压输出,并通过校准将电压值转换为有意义的浑浊度数值。硬件上需要注意电源质量和抗干扰,软件上则强调滤波和校准的重要性。

        通过本项目,开发者可以掌握STM32 ADC的基本应用、传感器数据采集的基本流程以及数据处理的基本方法。此方案为基础框架,开发者可根据具体应用需求,进一步添加显示、通信、报警等功能,构建完整的水质监测系统。


文章转载自:

http://64FIJjfu.nfdty.cn
http://Ww6yPUSt.nfdty.cn
http://jiWnFQGd.nfdty.cn
http://1qfVsjQl.nfdty.cn
http://hH5TQLXF.nfdty.cn
http://MSKREBVA.nfdty.cn
http://HZx4bcJq.nfdty.cn
http://ot7kSfYf.nfdty.cn
http://1ENDKwku.nfdty.cn
http://lZEw8Bzm.nfdty.cn
http://15XRsFc2.nfdty.cn
http://Rp5tjwvz.nfdty.cn
http://7TwasVof.nfdty.cn
http://IdPwrxFF.nfdty.cn
http://450N8s75.nfdty.cn
http://fxuKygxJ.nfdty.cn
http://7i0oL2Ra.nfdty.cn
http://SylOxERX.nfdty.cn
http://6YakKkBn.nfdty.cn
http://tJ2e5Pk3.nfdty.cn
http://rRWmQX7r.nfdty.cn
http://hbhR4Hir.nfdty.cn
http://V5xdJgRW.nfdty.cn
http://148cbrzk.nfdty.cn
http://PKHd8HdA.nfdty.cn
http://ExzIhRFo.nfdty.cn
http://gaqXA9gt.nfdty.cn
http://fGoQaft7.nfdty.cn
http://2LM95wrE.nfdty.cn
http://Do8m4CdA.nfdty.cn
http://www.dtcms.com/a/378927.html

相关文章:

  • 【Qt】【C++】虚析构函数及 virtual ~Base() = default
  • 马斯克访谈深度解读:机器人、AI芯片与人类文明的未来
  • 深入理解 CMake 脚本片段:文件查找、字符串替换与条件处理
  • Google Ads广告验证全攻略:如何借助动态住宅IP精准投放?
  • Linux防火墙配置指南:限制特定IP访问并允许其他所有流量
  • 使用动态IP 需要注意什么
  • 2025年- H128-Lc205. 同构字符串(哈希表)--Java版
  • 今天我们开始学习iptables防火墙
  • Android逆向学习(十一) IDA动态调试Android so文件
  • 第二篇:排序算法的简单认识【数据结构入门】
  • 嵌入式铁头山羊stm32:一文总结
  • HDFS(Hadoop 分布式文件系统)知识点梳理
  • AI幻觉的罪魁祸首
  • JVM 基础
  • 计算智能的概念和其算法的主要算法类型
  • leetcode25(有效的字母异位词)
  • [Windows] FileOptimizer v17.1.0_一款文件批量压缩工具
  • 淘宝/天猫按图搜索(拍立淘)item_search_img API接口实战指南
  • Java优选算法——二分查找
  • leetcode380:RandomizedSet - O(1)时间插入删除和获取随机元素(数组+哈希表的巧妙结合)
  • 经典蓝牙的 BR(Basic Rate(基础速率))
  • 牛客周赛 Round 108题解
  • Rocky9.0去堆叠双发arp(支持“ARP 广播双发”)
  • 「京墨」1.15.0 诗词、成语、对联、句子、诗歌…
  • AWS TechFest 2025: 风险模型的转变、流程设计的转型、生成式 AI 从实验走向实施的三大关键要素、评估生成式 AI 用例的适配度
  • 【Blender】二次元人物制作【二】:五官的制作
  • MinIO集群部署详细步骤(高性能的分布式对象存储系统)
  • 带地图的 RAG:多模态 + 地理空间 在 Elasticsearch 中
  • 使用 Spring AI Alibaba Graph 实现工作流
  • 【Debug日志 | DDP 下 BatchNorm 统计失真】