目录
[六、实验效果 编辑](#六、实验效果 编辑)
一、前言
项目成品图片:

哔哩哔哩视频链接:
(资料分享见文末)
二、项目简介
1.功能详解
基于STM32的水质检测系统(升级版)
功能如下:
- 主控芯片为STM32F103C8T6单片机
- DS18B20温度传感器测量水温度
- TDS电导率传感器测量水的电导率
- PH值传感器检测水的酸碱度
- 浊度传感器测量水的浑浊度
- OLED显示屏实时显示当前水温、电导率、浊度和PH值
- 按键可设置阈值和模式切换
- 自动模式下水温、电导率、浊度和PH值超过阈值范围触发蜂鸣器报警,并打开继电器
- 手动模式下可通过按键控制继电器开关
- 手机机智云APP显示信息并完成控制指令下发
2.主要器件
- STM32F103C8T6单片机
- OLED 屏幕
- DS18B20数字温度传感器
- TDS电导率传感器
- PH传感器
- 浊度传感器
- 继电器
- 蜂鸣器
三、原理图设计

四、PCB硬件设计
PCB图


五、程序设计
cpp
#include <stdio.h>
#include "stm32f10x.h"
#include "delay.h"
#include "stdarg.h"
#include "string.h"
#include "timer.h"
#include "flash.h"
#include "usart2.h"
#include "adc.h"
#include "gizwits_product.h"
#include "ds18b20.h"
#include "beep.h"
#include "Modules.h"
#include "jdq.h"
#include "key.h"
#include "main.h"
#include "oled.h"
#include "misc.h"
/****************异方辰电子工作室*******************
STM32
*项目 : STM32智能水质监测(升级版)
*版本 : V1.0
*MCU : STM32F103C8T6
*接口 : 见代码
*BILIBILI : 异方辰电子
*小红书 : 异方辰电子
*CSDN : 异方辰电子
*授权IP : 辰哥单片机设计、异方辰、YFC电子、北海单片机设计
**********************BEGIN***********************/
#define turbidity_K 2047.19
void Key_Init(void);//按键函数声明
void display(void);
u8 eer_f;
float TDS_DAT;
float T;
u8 b_1s;
extern uint8_t valueFlashFlag;
u8 smart_config;
#define KEY_Long1 11
#define KEY_1 1
#define KEY_2 2
#define KEY_3 3
#define KEY_4 4
#define FLASH_START_ADDR 0x0801f000 //写入的起始地址
SensorModules sensorData; //声明传感器数据结构体变量
SensorThresholdValue Sensorthreshold; //声明传感器阈值结构体变量
DriveModules driveData; //声明驱动器状态结构体变量
uint8_t mode = 1; //系统模式 1自动 2手动 3设置
//系统静态变量
static uint8_t count_a = 1; //自动模式按键数
static uint8_t count_m = 1; //手动模式按键数
static uint8_t count_s = 1; //设置模式按键数
unsigned char p[16]=" "; //显示水温数据缓冲区
unsigned char t[16]=" "; //显示TDS数据缓冲区
unsigned char z[16]=" "; //显示浊度数据缓冲区
unsigned char h[16]=" "; //显示PH数据缓冲区
/**
* @brief 显示菜单内容
* @param 无
* @retval 无
*/
enum
{
AUTO_MODE = 1,
MANUAL_MODE,
SETTINGS_MODE
}MODE_PAGES;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置中断优先分组
usart2_init(9600);//串口2初始化
delay_init(72); //系统延时函数初始化
DelayMs(500);
TIM2_Int_Init(10000,3600);//输出话定时器 这边用到定时器2作为0.5秒钟中断发生源
ADC1_DMA_Config();
Key_Init(); //按键引脚初始化
JDQ_Init(); //继电器初始化
BEEP_Init(); //蜂鸣器初始化
OLED_Init();//OLED屏幕初始化
OLED_Clear();
TIM1_Int_Init(72-1,1000-1);//按键扫描
DS18B20_Init();//初始化温湿度传感器
DelayMs(100);
Sensorthreshold.tempValue = FLASH_R(FLASH_START_ADDR); //从指定页的地址读FLASH
Sensorthreshold.NTUValue = FLASH_R(FLASH_START_ADDR+2); //从指定页的地址读FLASH
Sensorthreshold.PHValue_L = FLASH_R(FLASH_START_ADDR+4); //从指定页的地址读FLASH
Sensorthreshold.PHValue_H = FLASH_R(FLASH_START_ADDR+6); //从指定页的地址读FLASH
Sensorthreshold.TDSValue = FLASH_R(FLASH_START_ADDR+8); //从指定页的地址读FLASH
DelayMs(10);
userInit();
Gizwits_Init(); //机智云初始化
gizwitsHandle((dataPoint_t *)¤tDataPoint);//机智云协议处理
//默认设置机智云一键配网WIFI_AIRLINK_MODE模式
gizwitsSetMode(WIFI_AIRLINK_MODE);
ScanGizwitsMode();
delay_ms(1000);
OLED_Clear();
Sensorthreshold.tempValue=30;
Sensorthreshold.NTUValue=500;
Sensorthreshold.TDSValue=200;
Sensorthreshold.PHValue_L=4;
Sensorthreshold.PHValue_H=10;
while (1)
{
do
{
currentDataPoint.valuetempts = Sensorthreshold.tempValue;
currentDataPoint.valuePH_L =Sensorthreshold.PHValue_L;
currentDataPoint.valuePH_H = Sensorthreshold.PHValue_H;
currentDataPoint.valuezhuodu_ts = Sensorthreshold.NTUValue;
currentDataPoint.valuetds_ts = Sensorthreshold.TDSValue;
}while(0);//阈值上传机智云
SensorScan(); //获取传感器数据
userHandle(); //更新机智云数据点变量存储的值
gizwitsHandle((dataPoint_t *)¤tDataPoint); //数据上传至机智云
switch(mode)
{
case AUTO_MODE: //自动模式
OLED_autoPage1(); //显示主页面1固定信息
SensorDataDisplay1(); //显示传感器1数据
AutoControl();//自动模式控制函数
/*按键1按下时切换模式*/
if (KeyNum == KEY_1)//短按 //系统模式mode 1自动 2手动 3设置
{
KeyNum = 0;
mode = MANUAL_MODE;//手动模式
count_m = 1;//手动模式下key2按下的次数置一
OLED_Clear();
}
if (KeyNum == KEY_Long1)//长按
{
KeyNum = 0;
mode = SETTINGS_MODE;//阈值调节模式
count_s = 1;//阈值调节模式下key2按下的次数
OLED_Clear();
}
Control_Manager();//执行器执行相应的指令
userHandle(); //更新机智云数据点变量存储的值
gizwitsHandle((dataPoint_t *)¤tDataPoint); //数据上传至机智云
break;
case MANUAL_MODE://手动模式
OLED_manualOption(SetManual());//手动模式页面主信息显示
ManualControl(SetManual());//手动模式下相应的标志位置一或置零
if (SetManual() <= 2)
{
OLED_manualPage1();//手动模式界面1显示
ManualSettingsDisplay1();//手动模式下开/关的显示
}
if (KeyNum == KEY_1) //系统模式mode 0手动 1自动(默认)
{
KeyNum = 0;
mode = AUTO_MODE;//回到自动模式
count_a = 1;//自动模式下key2按下的次数
OLED_Clear();
}
Control_Manager();//执行器执行相应的指令
userHandle(); //更新机智云数据点变量存储的值
gizwitsHandle((dataPoint_t *)¤tDataPoint); //数据上传至机智云
break;
case SETTINGS_MODE://阈值调节模式
OLED_settingsOption(SetSelection()); //实现阈值设置页面的选择功能
ThresholdSettings(SetSelection()); //实现阈值调节功能
if (SetSelection() <= 4)
{
OLED_settingsPage1(); //显示阈值设置界面1固定信息
SettingsThresholdDisplay1(); //显示传感器阈值1数据
}
else //否则显示设置页面2
{
OLED_settingsPage2(); //显示阈值设置界面2固定信息
SettingsThresholdDisplay2(); //显示传感器阈值2数据
}
//判断是否退出阈值设置界面
if (KeyNum == KEY_1)
{
KeyNum = 0;
mode = AUTO_MODE; //跳转到主界面
count_a = 1;//自动模式下key2按下的次数
OLED_Clear(); //清屏
//存储修改的传感器阈值至flash内
FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue,
Sensorthreshold.NTUValue,
Sensorthreshold.PHValue_L,
Sensorthreshold.PHValue_H,
Sensorthreshold.TDSValue);
}
userHandle(); //更新机智云数据点变量存储的值
gizwitsHandle((dataPoint_t *)¤tDataPoint); //数据上传至机智云
break;
default: break;
}
if (valueFlashFlag)
{
valueFlashFlag = 0;
FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue,
Sensorthreshold.NTUValue,
Sensorthreshold.PHValue_L,
Sensorthreshold.PHValue_H,
Sensorthreshold.TDSValue);
}
userHandle(); //更新机智云数据点变量存储的值
gizwitsHandle((dataPoint_t *)¤tDataPoint); //数据上传至机智云
}
}
六、实验效果 
七、包含内容
