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

目录

一、模块概述

二、模块简介

[2.1 模块特点](#2.1 模块特点)

[2.2 电气特性](#2.2 电气特性)

[2.3 模块接口说明](#2.3 模块接口说明)

[2.4 结构与工作原理](#2.4 结构与工作原理)

[2.5 实际应用注意事项](#2.5 实际应用注意事项)

三、硬件设计

[3.1 硬件组成](#3.1 硬件组成)

[3.2 硬件连接](#3.2 硬件连接)

四、软件设计

[4.1 开发环境配置](#4.1 开发环境配置)

[4.2 关键代码实现](#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数字信号输出引脚):

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

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引脚 浑浊度传感器引脚 功能说明
5V VCC 为传感器供电
GND GND 共同地
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;            // 要转换的通道数量为1
    ADC_Init(ADC1, &ADC_InitStructure);

    // 4. 配置ADC通道规则组
    // 参数:ADCx, 通道号(PA1对应ADC1的通道1),采样顺序1,采样时间55.5个周期
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);

    // 5. 使能ADC
    ADC_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(); // 初始化ADC

    while(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的基本应用、传感器数据采集的基本流程以及数据处理的基本方法。此方案为基础框架,开发者可根据具体应用需求,进一步添加显示、通信、报警等功能,构建完整的水质监测系统。

相关推荐
GilgameshJSS4 小时前
【学习K230-例程21】GT6700-UDP-Client
网络·python·单片机·网络协议·学习·udp
深圳市尚想信息技术有限公司7 小时前
APT32F0042F6P6 32位微控制器(MCU)单片机 APT爱普特微电子 芯片核心解析
单片机·集成电路·电子元器件·爱普特
沐欣工作室_lvyiyi8 小时前
基于K210和STM32的小区门禁系统(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·人脸识别·k210·计算机毕业设计
殷忆枫9 小时前
基于STM32的智能语音识别饮水机系统设计
stm32·嵌入式硬件·语音识别
月阳羊10 小时前
【硬件-笔试面试题-93】硬件/电子工程师,笔试面试题(知识点:波特图)
java·经验分享·单片机·嵌入式硬件·面试
Wave84519 小时前
STM32--时间戳,BKB,RTC
stm32·单片机·嵌入式硬件
m0_5557629020 小时前
项目1——单片机程序审查,控制系统流程图和时序图
单片机·mongodb·流程图
ooolmf1 天前
照度传感器考虑笔记
笔记·单片机