基于STM32的智能鱼缸水质净化系统设计

devtools/2025/2/9 7:10:49/

🤞🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是智能鱼缸水质净化系统

目录

1、设计要求

2、系统功能

3、演示视频和实物

4、系统设计框图

5、软件设计流程图

6、原理图

7、主程序

8、总结


1、设计要求

本毕业设计以单片机作为控制核心芯片,设计出一款具有监测鱼缸水的温度、水位、浊度和PH值等参数,并且通过WIFI模块连接云平台用来实现数据上传和下发,

 2、系统功能

(1)基于STM32F103C8T6为主控制器的智能鱼缸的设计与实现。其中包括基于STM32F103C8T6单片机的最小系统的搭建,温度传感器、浑浊度传感器、水位传感器等相关器件模块的选型和原理图设计,在上述原理图的基础上搭建硬件平台并验证其功能的完善性。

(1)ESP8266-01Wifi模块。通过本模块单片机系统可以连接到机智云,手机APP就可以远程控制鱼缸的开关。

(2)水位传感器器。水位传感器用来检测鱼缸内的水位,是鱼缸的水位保持在一定的范围内,通过比较水位和水位的阈值来控制补水泵和排水泵。

(3)温度传感器,温度传感器用来检测鱼缸内的水温,使鱼缸保持恒温。

(4)PH传感器,用来检测鱼缸内的PH值。

(5)水泵继电器模块,用继电器来驱动两个水泵。

(6)时钟模块。利用时钟振荡电路产生时钟信号。单片机时钟可以提供一个固定的时钟频率,用于同步和控制各个模块的操作。通过时钟信号的控制,可以确保单片机系统中各个模块按照一定的时间序列进行操作,从而实现定时功能。

(7)OLED显示模块。OLED显示模块采用0.96寸液晶显示屏,该模块用来实时显示传感器数据及鱼缸工作状态

(8)按键模块。按键模块用来控制模式选择和控制鱼缸的开启与关闭。

(9)蜂鸣器模块。设备出现故障用来报警。

(10)舵机用来控制净水系统的开关。

3、演示视频和实物

基于STM32的鱼缸水质净化系统

4、系统设计框图

5、软件设计流程图

6、原理图

7、主程序

#include "sys.h"                //有定制和购买的,可以联系VX:lwfw123456789
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "usart3.h"
#include "gizwits_product.h"
#include "Key.h"
#include "Buzzer.h"
#include "OLED.h"
#include "AD.h"
#include "MyRTC.h"
#include "Servo.h"
#include "ds18b20.h"
/***********************************************************************************************
同学好!我们是5132单片机设计,定制单片机设计,实物和说明书均可定制,欢迎大家咨询。VX:lwfw123456789
其他项目演示视频和说明请大家移步哔哩哔哩、CSDN和公众号等。
哔哩哔哩:5132单片机设计
CSDN:    5132单片机设计
公众号:  5132单片机设计
抖音  :  5132单片机设计
小红书:  5132单片机设计
咸鱼:    5132单片机设计
************************************************************************************************/uint8_t KeyNum;                               //存储按键值
uint32_t bufe[10];                     //存储传感器采集的数据
uint16_t AD0, AD1, AD2, AD3;             //存储5路ADC值uint32_t TempYu = 25;
uint32_t ShuiWeiYu_Xia = 10;
uint32_t ShuiWeiYu_Shang = 70;
uint32_t ZhuoYu = 70;
uint32_t PHYu = 5;
short temperature;                               //存放温湿度
u8 state, state2 = 2, state2_1, state2_2, state3;      //按键状态标志
u8 t = 0;                                     //传感器读取时间间隔
u8 flag;                               //远程控制标志
u8 flag2 = 0, flag1, flag3;
uint16_t RTC_Time[] = {0, 0, 0};
uint16_t RTC_Time1[] = {7, 0, 0};    //定时时间---开
uint16_t RTC_Time2[] = {19, 0, 0};   //定时时间---关
u8 T_state, T_state1, qingping = 1, state_dingshi_yu_guan, state_dingshi_yu_kai, state_dingshi_yu_switch, state3_1;
float PH;
extern void TimeSet(void);
extern void TimeRead(void);
extern void DingShiMoShi(void);
extern void YuZhiSet(void);
extern void ChuangGan(void);void MY_Gizwits_Init(void)              //机智云初始化函数
{TIM3_Int_Init(9, 7199); //1MS系统定时usart3_init(9600);//WIFI初始化memset((uint8_t *)&currentDataPoint, 0, sizeof(dataPoint_t)); //设备状态结构体初始化gizwitsInit();//环形缓冲区初始化gizwitsSetMode(2);   //设置模式userInit();
}
u16 Get_Adc_Average(u8 ADC_CHx, u8 times)
{u32 temp_val = 0;u8 t;for (t = 0; t < times; t++){temp_val += AD_GetValue(ADC_CHx);//SYSTICK_DelayMs(5);}return temp_val / times;
}void shoudong()
{TimeRead();if (KeyNum == 2)        //按键{delay_ms(20);if (KeyNum == 2){state2++;if (state2 > 1){state2 = 0;}}}if (state2 == 0){Servo_SetAngle(90);//外设操作}if (state2 == 1){Servo_SetAngle(0);//外设操作}if (KeyNum == 3)        //按键{delay_ms(20);if (KeyNum == 3){state2_1++;if (state2_1 > 2){state2_1 = 0;}}}if (state2_1 == 1){BuShuiBen_ON();//外设操作PaiShuiBen_OFF();}if (state2_1 == 0){BuShuiBen_OFF();//外设操作PaiShuiBen_OFF();}if (state2_1 == 2){BuShuiBen_OFF();//外设操作PaiShuiBen_ON();}if (KeyNum == 4)        //按键{delay_ms(20);if (KeyNum == 4){state2_2++;if (state2_2 > 1){state2_2 = 0;}}}if (state2_2 == 1){JiaRe_ON();//外设操作}if (state2_2 == 0){JiaRe_OFF();//外设操作}}
void zhidong()
{if (bufe[0] < ShuiWeiYu_Xia){BuShuiBen_ON();PaiShuiBen_OFF();}else if (bufe[0] > ShuiWeiYu_Shang){PaiShuiBen_ON();BuShuiBen_OFF();}else{			    PaiShuiBen_OFF();BuShuiBen_OFF();}if (bufe[3]/10 < TempYu){JiaRe_ON();}else{JiaRe_OFF();}if ((bufe[1]/10 < PHYu) || (bufe[2] > ZhuoYu)){Buzzer_Turn();}else{Buzzer_OFF();}}int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(9600);       //串口初始化为9600delay_init();      //延时函数初始化LED_Init();            //初始化与LED连接的硬件接口Buzzer_Init();             //下面为外设初始化OLED_Init();Key_Init();AD_Init();MyRTC_Init();Servo_Init();     //舵机初始化,并设置舵机初始角度while (DS18B20_Init()) //DS18B20初始化{printf("ds18b20 success!");delay_ms(200);}MY_Gizwits_Init();   //机智云初始化while (1){userHandle();    //数据上传gizwitsHandle((dataPoint_t *)&currentDataPoint);   //后台处理,必须放在while里if (t % 10 == 0){AD0 = AD_GetValue(ADC_Channel_0);    //水位传感器     PA0if (AD0 > 4000)AD0 = 4000;bufe[0] = (u8)(AD0 / 40);AD2 = Get_Adc_Average(ADC_Channel_2, 10);PH = (float)AD2 * (3.3 / 4096); //读取ADC通道4的值PH = -5.7541 * PH + 16.654; //输出电压范围0~3V3      因为STM32的ADC参考电压是3.3V//将ADC的原始值(adcx)转换为电压值。这里假设ADC的参考电压是3.3V,并且ADC的位数是12位(即最大值为4096)。bufe[1] = PH * 10;AD3 = AD_GetValue(ADC_Channel_3);    //浊度传感器     PA3if (AD3 > 4000)AD3 = 4000;bufe[2] = (u8)(100 - (AD3 / 40));temperature = DS18B20_Get_Temp();bufe[3] = temperature;}t++;KeyNum = Key_GetNum();if (KeyNum == 1){qingping = 0;state2 = 2,delay_ms(20);if (KeyNum == 1){state++;if (state > 3){state = 0;}}}if (state == 0)                                //远程模式{if (qingping == 0){OLED_Clear();qingping = 1;}           TimeRead();ChuangGan();OLED_ShowChinese(1, 7, 49);OLED_ShowChinese(1, 8, 50);}if (state == 2)                           //自动模式{OLED_ShowChinese(1, 7, 51);OLED_ShowChinese(1, 8, 52);TimeRead();zhidong();ChuangGan();}if (state == 1)                           //手动模式{OLED_ShowChinese(1, 7, 18);OLED_ShowChinese(1, 8, 52);ChuangGan();shoudong();}if (state == 3)                           //阈值设置{if (qingping == 0){OLED_Clear();qingping = 1;}YuZhiSet();}}
}void TimeSet()           //设置时间
{if (KeyNum == 2)    //PB10{delay_ms(20);if (KeyNum == 2){T_state++;if (T_state > 2){T_state = 0;}}}if (T_state == 0)    //时间显示模式{MyRTC_ReadTime();OLED_ShowNum(1, 5, MyRTC_Time[3], 2);    //时OLED_ShowString(1, 7, ":");OLED_ShowNum(1, 8, MyRTC_Time[4], 2);    //分OLED_ShowString(1, 10, ":");OLED_ShowNum(1, 11, MyRTC_Time[5], 2);   //秒RTC_Time[0] = MyRTC_Time[3];RTC_Time[1] = MyRTC_Time[4];RTC_Time[2] = MyRTC_Time[5];}if (T_state == 1)    //修改时间{if (KeyNum == 5){delay_ms(20);if (KeyNum == 5){T_state1++;if (T_state1 > 2){T_state1 = 0;}}}if (T_state1 == 0)  //修改时{if (KeyNum == 4)RTC_Time[0]++;if (KeyNum == 3)RTC_Time[0]--;if (RTC_Time[0] > 23 & RTC_Time[0] < 100)RTC_Time[0] = 0;if (RTC_Time[0] > 100)RTC_Time[0] = 23;OLED_ShowNum(1, 5, RTC_Time[0], 2);  //时}if (T_state1 == 1)  //修改分{if (KeyNum == 4)RTC_Time[1]++;if (KeyNum == 3)RTC_Time[1]--;if (RTC_Time[1] > 59 & RTC_Time[1] < 100)RTC_Time[1] = 0;if (RTC_Time[1] > 100)RTC_Time[1] = 59;OLED_ShowNum(1, 8, RTC_Time[1], 2);  //时}if (T_state1 == 2)  //修改秒{if (KeyNum == 4)RTC_Time[2]++;if (KeyNum == 3)RTC_Time[2]--;if (RTC_Time[2] > 59)RTC_Time[2] = 0;if (RTC_Time[2] > 59 & RTC_Time[2] < 100)RTC_Time[2] = 0;if (RTC_Time[2] > 100)RTC_Time[2] = 59;OLED_ShowNum(1, 11, RTC_Time[2], 2);  //时}}if (T_state == 2){MyRTC_Time[3] = RTC_Time[0];MyRTC_Time[4] = RTC_Time[1];MyRTC_Time[5] = RTC_Time[2];MyRTC_SetTime();T_state = 0;}
}void TimeRead()
{MyRTC_ReadTime();OLED_ShowNum(1, 5, MyRTC_Time[3], 2);    //时OLED_ShowString(1, 7, ":");OLED_ShowNum(1, 8, MyRTC_Time[4], 2);    //分OLED_ShowString(1, 10, ":");OLED_ShowNum(1, 11, MyRTC_Time[5], 2);   //秒
}void DingShiMoShi()
{TimeRead();//...............................定时模式..................................../if ((MyRTC_Time[3] == RTC_Time1[0]) && (MyRTC_Time[4] == RTC_Time1[1]) && (MyRTC_Time[5] == RTC_Time1[2])){//外设操作}if ((MyRTC_Time[3] == RTC_Time2[0]) && (MyRTC_Time[4] == RTC_Time2[1]) && (MyRTC_Time[5] == RTC_Time2[2])){//外设操作}//...............................修改定时时间..................................../OLED_ShowChinese(3, 1, 31);OLED_ShowString(3, 3, ":");OLED_ShowNum(3, 5, RTC_Time1[0], 2);OLED_ShowString(3, 7, ":");OLED_ShowNum(3, 8, RTC_Time1[1], 2);OLED_ShowString(3, 10, ":");OLED_ShowNum(3, 11, RTC_Time1[2], 2);OLED_ShowChinese(4, 1, 32);OLED_ShowString(4, 3, ":");OLED_ShowNum(4, 5, RTC_Time2[0], 2);OLED_ShowString(4, 7, ":");OLED_ShowNum(4, 8, RTC_Time2[1], 2);OLED_ShowString(4, 10, ":");OLED_ShowNum(4, 11, RTC_Time2[2], 2);if (KeyNum == 5){delay_ms(20);if (KeyNum == 5){state_dingshi_yu_switch++;if (state_dingshi_yu_switch > 2){state_dingshi_yu_switch = 0;}}}if (state_dingshi_yu_switch == 1)    //设置阈值开的时间{if (KeyNum == 2){delay_ms(20);if (KeyNum == 2){state_dingshi_yu_kai++;if (state_dingshi_yu_kai > 2){state_dingshi_yu_kai = 0;}}}if (state_dingshi_yu_kai == 0)    //时{if (KeyNum == 3) RTC_Time2[0]++;if (KeyNum == 4) RTC_Time2[0]--;}if (state_dingshi_yu_kai == 1)//分{if (KeyNum == 3) RTC_Time2[1]++;if (KeyNum == 4) RTC_Time2[1]--;}if (state_dingshi_yu_kai == 2)//秒{if (KeyNum == 3) RTC_Time2[2]++;if (KeyNum == 4) RTC_Time2[2]--;}}else{if (KeyNum == 2){delay_ms(20);if (KeyNum == 2){state_dingshi_yu_guan++;if (state_dingshi_yu_guan > 2){state_dingshi_yu_guan = 0;}}}if (state_dingshi_yu_guan == 0)    //时{if (KeyNum == 3) RTC_Time1[0]++;if (KeyNum == 4) RTC_Time1[0]--;}if (state_dingshi_yu_guan == 1)//分{if (KeyNum == 3) RTC_Time1[1]++;if (KeyNum == 4) RTC_Time1[1]--;}if (state_dingshi_yu_guan == 2)//秒{if (KeyNum == 3) RTC_Time1[2]++;if (KeyNum == 4) RTC_Time1[2]--;}}if (state3_1 == 0)    //时{if (KeyNum == 5) RTC_Time1[0]++;if (KeyNum == 6) RTC_Time1[0]--;}if (state3_1 == 1)//分{if (KeyNum == 5) RTC_Time1[1]++;if (KeyNum == 6) RTC_Time1[1]--;}if (state3_1 == 2)//秒{if (KeyNum == 5) RTC_Time1[2]++;if (KeyNum == 6) RTC_Time1[2]--;}
}void YuZhiSet()
{zhidong();OLED_ShowChinese(1, 3, 72);   //显示“阈值设置”OLED_ShowChinese(1, 4, 73);OLED_ShowChinese(1, 5, 74);OLED_ShowChinese(1, 6, 75);OLED_ShowString(2, 1, "S_W_X:");OLED_ShowNum(2, 7, ShuiWeiYu_Xia, 2);OLED_ShowString(3, 1, "S_W_S:");OLED_ShowNum(3, 7, ShuiWeiYu_Shang, 2);	OLED_ShowString(4, 10, "PH:");OLED_ShowNum(4, 13, PHYu, 2);OLED_ShowString(2, 10, "Temp:");OLED_ShowNum(2, 15, TempYu, 2);OLED_ShowString(3, 10, "Z_D:");OLED_ShowNum(3, 14, ZhuoYu, 2);if (KeyNum == 2)                          //自动模式下PB0按键控制阈值切换{delay_ms(20);if (KeyNum == 2){state3++;if (state3 > 4){state3 = 0;}}}if (state3 == 0){if (KeyNum == 3)ShuiWeiYu_Xia++;if (KeyNum == 4)ShuiWeiYu_Xia--;}if (state3 == 1){if (KeyNum == 3)ShuiWeiYu_Shang++;if (KeyNum == 4)ShuiWeiYu_Shang--;}if (state3 == 4){if (KeyNum == 3)PHYu++;if (KeyNum == 4)PHYu--;}if (state3 == 2){if (KeyNum == 3)TempYu ++;if (KeyNum == 4)TempYu --;}if (state3 == 3){if (KeyNum == 3)ZhuoYu ++;if (KeyNum == 4)ZhuoYu --;}
}void ChuangGan()
{OLED_ShowChinese(2, 1, 39);OLED_ShowChinese(2, 2, 40);OLED_ShowString(2, 5, ":");OLED_ShowNum(2, 6, bufe[0], 2);OLED_ShowString(2, 8, "%");OLED_ShowString(4, 8, "%");OLED_ShowString(2, 11, "PH:");OLED_ShowNum(2, 14, bufe[1] / 10, 1);OLED_ShowString(2, 15, ".");OLED_ShowNum(2, 16, bufe[1] % 10, 1);OLED_ShowChinese(3, 1, 26);OLED_ShowChinese(3, 2, 28);OLED_ShowString(3, 5, ":");if (temperature < 0){OLED_ShowString(3, 6, "-");     //显示负号temperature = -temperature;                 //转为正数}else OLED_ShowString(3, 6, "+");        //去掉负号OLED_ShowNum(3, 7, temperature / 10, 2);OLED_ShowString(3, 9, ".");OLED_ShowNum(3, 10, temperature % 10, 1);OLED_ShowChinese(4, 1, 78);OLED_ShowChinese(4, 2, 79);OLED_ShowString(4, 5, ":");OLED_ShowNum(4, 6, bufe[2], 2);
}

8、总结

本设计以单片机作为控制核心芯片,设计出一款具有监测鱼缸水的温度、水位、浊度和PH值等参数,并且通过WIFI模块连接云平台用来实现数据上传和下发。


http://www.ppmy.cn/devtools/157284.html

相关文章

C#常用744单词

1.visual 可见的 2.studio 工作室 3.dot 点 4.net 网 5.harp 尖端的&#xff0c;锋利的。 6.amework 骨架&#xff0c;构架&#xff0c;框架 7.beta 测试版&#xff0c;试用版 8.XML&#xff08;全称&#xff1a;eXtensible Markup Language&#xff09…

【项目日记(四)】thread cache 层

前言 前面我们对整个项目的框架进行了介绍&#xff0c;本期开始我们将进行第一层线程缓存层(thread cache)的详细介绍与实现。 目录 前言 一、thread cache 的整体设计 二、内存对齐规则和哈希映射关系 2.1 如何对齐&#xff1f; 2.2 这样设计对齐规则的好处&#xff1f…

基于DeepSeek模型的思维导图智能系统

基于DeepSeek模型的思维导图智能系统 摘 要&#xff1a;本文研究了Prompt技术在自然语言处理&#xff08;NLP&#xff09;中的应用&#xff0c;重点探讨了其在用户输入语言转换任务中的作用。基于DeepSeek模型&#xff0c;文章通过设计不同的Prompt并结合API调用&#xff0c;…

飞算JavaAI 如何帮助初级工程师提升设计能力?

在 Java 开发的广袤天地里&#xff0c;初级工程师就像一群怀揣梦想却又在迷雾中摸索的冒险者。设计能力&#xff0c;对他们而言&#xff0c;仿佛是一座高耸入云、难以攀登的山峰。传统的开发学习路径中&#xff0c;初级工程师往往需要在浩如烟海的代码范例里苦苦钻研&#xff0…

计算机毕业设计Tensorflow+LSTM空气质量监测及预测系统 天气预测系统 Spark Hadoop 深度学习 机器学习 人工智能

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

SQL Server查询计划操作符(7.3)——查询计划相关操作符(6)

7.3. 查询计划相关操作符 48)Key Lookup:该操作符对一个有簇索引的表进行书签查找。参数列包含簇索引的名字和用于查找簇索引中数据行的簇键。该操作符总是伴随一个Nested Loops操作符。如果其参数列中出现WITH PREFETCH子句,则查询处理器已决定使用异步预取(预读,read-ah…

C# OpenCV机器视觉:学生注意力监测

小王是一位充满活力的年轻教师&#xff0c;刚接手了一个新班级。他满心欢喜地准备在课堂上大显身手&#xff0c;把自己的知识毫无保留地传授给学生。可没上几节课&#xff0c;他就发现了一个让人头疼的问题&#xff1a;课堂上总有那么几个学生注意力不集中&#xff0c;要么偷偷…