首页 > 其他分享 >零基础学会制作 基于STM32/51的智能水质监测系统设计/水检测/鱼塘检测/水质量检测

零基础学会制作 基于STM32/51的智能水质监测系统设计/水检测/鱼塘检测/水质量检测

时间:2024-08-11 23:22:54浏览次数:18  
标签:检测 globalParam 51 isPH STM32 InitStructure ADC ADC1 GPIO

项目介绍

本论文是在研究和设计一套基于STM32单片机的智能水质监测系统,本系统主要包括监测模块、无线通信模块、报警模块、显示模块、电源模块等。当监测到的水质相关参数(如水温、水位、浑浊度、电导率、PH值等)与设定阈值不符时,则STM32的智能水质监测系统发出对应报警,并通过无线通信上传至手机APP,通过探索系统设计的技术路线、关键技术和实现方法,能够提供准确的水质监测方法,确保水资源的质量和安全,同时进行水质监测,进行查看使工作人员快速的处理污染,从而减少环境污染风险。

功能介绍

设计一个以单片机为主控芯片的智能水质监测系统。该系统主要包括控制模块、监测模块、无线通信模块、报警模块、显示模块、电源模块等。当监测到的水质相关参数(如水温、水位、浑浊度、电导率、PH值等)与设定阈值不符时,则系统发出相应报警,并通过无线通信模块将实时监测到的数据上传到手机端显示对象信息。
(1)监测采集水质相关参数(水温、水位、浑浊度、电导率、PH值);
(2)无线传输水质参数至手机端APP;
(3)显示相应参数及报警状态;
(4)报警提醒;

所用模块

基于STM32的智能水质监测系统是一个综合性的解决方案,旨在通过多个监测模块实时收集和分析水质参数,以确保水资源的安全和质量。本系统基于STM32单片机,利用其高性能和低功耗的特点,整合了多个水质监测模块,包括电源模块、水位监测模块、电导率检测模块、pH检测模块[8]、浊度检测模块、温度检测模块,以及无线通信模块。系统设计充分考虑了模块化和扩展性,以便于后续升级和维护[10]。电源模块负责为整个水质监测系统提供稳定和持续的电源。根据系统的功耗和工作环境,电源模块可以设计为支持电池供电,以保证系统能够在各种环境中长期稳定工作。采用水位检测传感器进行水位监测,用于实时监控水体的水位高度,对于防洪和水资源管理具有重要意义。通过电导率传感器监测水的电导率,从而推算出水中溶解盐分的浓度,这对于评估水质的纯净度非常重要。使用pH传感器实时监测水的酸碱度,对于水体的环境健康和生态平衡至关重要。通过浊度传感器监测水中悬浮物的浓度,评估水质的清澈程度。利用温度传感器监测水温,因为水温对水体的化学反应速率和生物活性有直接影响。系统通过无线通信模块将监测到的数据发送到远程服务器或云平台。这使得用户可以通过网络实时接收和查看水质数据,同时系统可以根据数据分析结果进行相应的报警和指导。系统软件包括嵌入式软件和服务器端软件。嵌入式软件运行在STM32单片机上,负责数据采集、初步处理和通过无线模块发送数据。服务器端软件负责数据的进一步分析、存储和展示,并提供用户界面,以便用户查询历史数据、实时数据和接收报警通知。
本设计采用STM32F103C8T6 微处理器为主控模块,确保系统架构的高效性和稳定性。该系统将包括控制模块、监测模块、无线通信模块、报警模块、显示模块和电源模块等。开发监测模块,以实时监测关键的水质参数,如水温、水位、浑浊度、电导率和PH值等[11]。设计一个智能报警系统,当水质参数超出预设阈值时,系统能够及时发出报警,以警告用户或相关管理人员采取措施。无线通信模块用于将监测到的水质数据实时传输到用户的移动设备,开发一个用户友好的界面,用于在手机端或其他移动设备上显示实时的水质数据和警报信息。

系统原理图

在这里插入图片描述

实物图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

部分代码

#include “App_SysInclude.h”

static Timer *AppSecondTimer_Handle;

static const char NetProtocolBuffer[] = {
“\r\nPH值: %d\r\n水质: %d\r\n
水位: %d\r\n浑浊度: %d\r\n”
};

/* 阈值 /
struct {
uint16_t usTurbidity;
uint16_t usWarterLine;
/
下限阈值 /
int16_t isPH_L;
/
上限阈值 */
int16_t isPH_H;
} threshold = {
.usTurbidity = 1000,
.usWarterLine = 500,
.isPH_L = 3,
.isPH_H = 11
};

static struct {
/* 浑浊度 /
uint16_t usTurbidity;
/
水位 /
uint16_t usWarterLine;
/
PH /
int16_t isPH;
/
水质 */
int16_t iWaterQuality;
} globalParam = {
.usTurbidity = 0,
.usWarterLine = 0,
.isPH = 0,
.iWaterQuality = 0
};

/******************************************************************

  • Name : adc_turbidity_Init

  • Description : 浑浊度传感器初始化

  • Input :

  • Output :

  • Return :
    ********************************************************************/
    static void adc_turbidity_Init(void)
    {
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);

    GPIO_InitStructure.GPIO_Pin = TURBIDITY_ADC_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(TURBIDITY_GPIO_TYPE, &GPIO_InitStructure);

    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;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Cmd(ADC1, ENABLE);
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));

    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
    }

/******************************************************************

  • Name : get_turbidity_value

  • Description : 读取浑浊度传感器数值

  • Input :

  • Output :

  • Return :
    ********************************************************************/
    static uint16_t get_turbidity_value(void)
    {
    // 设置指定ADC的规则组通道,一个序列,采样时间
    ADC_RegularChannelConfig(ADC1, TURBIDITY_ADC_Channel, 1, ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));

    return ~ADC_GetConversionValue(ADC1) & 0x0FFF;
    }

/******************************************************************

  • Name : adc_ph_Init

  • Description : ph传感器初始化

  • Input :

  • Output :

  • Return :
    ********************************************************************/
    static void adc_ph_Init(void)
    {
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);

    GPIO_InitStructure.GPIO_Pin = PH_VAL_ADC_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(PH_VAL_GPIO_TYPE, &GPIO_InitStructure);
    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;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Cmd(ADC1, ENABLE);
    ADC_ResetCalibration(ADC1);

    while (ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);

    while (ADC_GetCalibrationStatus(ADC1));
    }

/******************************************************************

  • Name : get_ph_value

  • Description : 读取ph值

  • Input :

  • Output :

  • Return :
    ********************************************************************/
    static int16_t get_ph_value(void)
    {
    uint16_t usValue;

    // 设置指定ADC的规则组通道,一个序列,采样时间
    ADC_RegularChannelConfig(ADC1, PH_VAL_ADC_Channel, 1, ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));

    usValue = ADC_GetConversionValue(ADC1);
    return (int32_t)(-5.7541 * ((float)usValue * 3.3 / 4096) + 16.654);
    }

/******************************************************************

  • Name : sencond_process

  • Description :

  • Input :

  • Output :

  • Return :
    ********************************************************************/
    static void sencond_process(void *arg)
    {
    static uint8_t globalCnt = 0;
    static uint8_t ucStep = 0;
    float fWQValue = 0;

    switch(ucStep)
    {
    case 0:
    globalParam.usWarterLine = (~get_voice_value() & 0xFFF);
    ucStep ++;
    break;
    case 1:
    globalParam.usTurbidity = get_turbidity_value();
    ucStep ++;
    break;
    case 2:
    globalParam.isPH = get_ph_value();
    ucStep ++;
    break;
    case 3:
    /* 计算电导水质 */
    fWQValue = get_smoke_value() * 3.3 / 4096;
    fWQValue = (133.42 * fWQValue * fWQValue * fWQValue - 255.86 * fWQValue * fWQValue + 857.39 * fWQValue) * 0.5;
    globalParam.iWaterQuality = (int16_t)fWQValue;
    ucStep = 0;
    break;
    default:
    ucStep = 0;
    break;
    }

    if(globalParam.usTurbidity > threshold.usTurbidity) {
    GPIO_SetBits(RELAY_LEVEL_GPIO_TYPE,RELAY_LEVEL_GPIO_PIN);
    } else {
    GPIO_ResetBits(RELAY_LEVEL_GPIO_TYPE,RELAY_LEVEL_GPIO_PIN);
    }

    if(globalParam.usWarterLine < threshold.usWarterLine) {
    GPIO_SetBits(RELAY_LEVEL2_GPIO_TYPE,RELAY_LEVEL2_GPIO_PIN);
    } else {
    GPIO_ResetBits(RELAY_LEVEL2_GPIO_TYPE,RELAY_LEVEL2_GPIO_PIN);
    }

    if(globalParam.isPH < threshold.isPH_L || globalParam.isPH > threshold.isPH_H) {
    Buzzer_Config(ENABLE);
    } else {
    Buzzer_Config(DISABLE);
    }

    if(globalCnt >= 12)
    {
    if(globalParam.isPH >= 0) {
    OLED_8X16_PRINTF(0,0,“PH: %03d”,globalParam.isPH);
    } else {
    OLED_8X16_PRINTF(0,0,“PH: %03d”,globalParam.isPH);
    }
    if(globalParam.iWaterQuality >= 0) {
    OLED_8X16_PRINTF(2,0,“WQ: %05d”,globalParam.iWaterQuality);
    } else {
    OLED_8X16_PRINTF(2,0,“WQ: %05d”,globalParam.iWaterQuality);
    }
    OLED_8X16_PRINTF(4,0,“WL: %05d”,globalParam.usWarterLine);
    OLED_8X16_PRINTF(6,0,“TUR: %05d”,globalParam.usTurbidity);

     moudle_esp8266_tcpserver_printf(NetProtocolBuffer,globalParam.isPH,globalParam.iWaterQuality, \
                                     globalParam.usWarterLine,globalParam.usTurbidity);
     globalCnt = 0;
    

    }
    globalCnt ++;
    }

资料下载链接

「实物制作资料 分享.rar」,来自夸克网盘分享。
夸克网盘无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
/7b80346jCs

标签:检测,globalParam,51,isPH,STM32,InitStructure,ADC,ADC1,GPIO
From: https://blog.csdn.net/weixin_55654459/article/details/141114004

相关文章

  • 34.x86游戏实战-XXX过检测代码分析
    免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!本次游戏没法给内容参考于:微尘网络安全工具下载:链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3提取码:6tw3复制这段内容后打开百度网盘手机App,操作更方便哦上一个内容:33.x86游戏实战-喊话C......
  • P9751 [CSP-J 2023] 旅游巴士
    原题链接分析很逆天的一道题设\(dp[i][j]\)为到达第\(i\)个点的时刻\(t\)且满足\(t\modk=j\)的最小\(t\)则有答案为\(dp[n][0]\)更新也很简单,设当前点为\(u\),当前时间为\(t\)需要遍历的下一个点\(v\),则有\(dis[v][(t+1)\%k]=dis[u][t\%k]+1\)如果道路还没开......
  • spring使用validation参数及全局异常检测
    1.validation参数验证工具1.1.validation-api技术链validation-api是一个Java的数据校验规范,它定义了一套用于校验JavaBean的API。它是JSR303规范的一部分,也被称为BeanValidation。validation-api提供了一系列的注解,用于在Java类的字段、方法参数和方法返回值上添加校验规......
  • YOLOv3:多尺度检测的巅峰之作
    目录前言3.1简介3.2网络结构3.3改进之处3.4性能表现前言   自从2016年JosephRedmon等人首次提出YOLO(YouOnlyLookOnce)这一实时目标检测框架以来,YOLO系列算法就以其高效性和准确性成为了计算机视觉领域的明星。YOLO系列的核心思想是在单一网络中完成目......
  • CF1515F Phoenix and Earthquake 题解
    CF1515F给定一张\(n\)个点\(m\)条边的无向连通图和正整数\(x\),点有非负权值\(a_i\)。如果一条边\((u,v)\)满足\(a_u+a_v\gex\),可以将\(u,v\)缩起来,新点的点权为\(a_u+a_v-x\)。判断这张图是否可以缩成一个点。如果是,还要输出每次缩的是哪条边。\(2\len\le3......
  • JS【详解】数据类型检测(含获取任意数据的数据类型的函数封装、typeof、检测是否为 nul
    【函数封装】获取任意数据的数据类型/***获取任意数据的数据类型**@paramx变量*@returns返回变量的类型名称(小写字母)*/functiongetType(x){//获取目标数据的私有属性[[Class]]的值constoriginType=Object.prototype.toString.call(x);//......
  • USB type-c CC管脚如何做到正反接检测功能
    USBType-C连接器的CC(ConfigurationChannel)管脚用于实现插头方向检测和电源管理。具体来说,USBType-C连接器具有两个CC管脚:CC1和CC2。正反接检测功能的实现主要依赖于这两个CC管脚的电压状态。正反接检测原理CC管脚的布局:在USBType-C接口中,CC1和CC2分......
  • STM32学习记录(九):RTC
    RTC框图实时时钟(Real-timeclock:RTC)是一个独立的计时器。RTC提供一组连续运行的计数器,可以与合适的软件一起使用,以提供时钟日历功能。可以写入计数器值以设置系统的当前时间/日期。可以选择以下三种作为RTC时钟源:HSE时钟进行128分频LSE振荡器时钟LSI振荡器时钟有关时......
  • 在线仿真平台+C语言实现:STM32驱动0.96寸OLED屏幕显示DHT11温湿度传感器测量值
    这里推荐一款由深圳航天科技创新研究院推出的在线电路仿真软件,该软件不仅具备原理图绘制与代码编写功能,还支持在线编译代码、上传自定义代码以及进行仿真模拟,此外还能在线生成并允许下载.bin和.hex文件。官网地址如下:Document进入网页后先注册一个账号。  注册完账号后即可......
  • 【STM32】ADC模拟数字转换-规则组单通道
    本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发 目录 ADC简介ADC时钟配置引脚模拟输入模式规则组通道选择ADC初始化 工作模式数据对齐 触发转换方式连续与单次转换模式扫描模式组内的通道个数ADC初始化框架ADC上电ADC校验 获取转换数......