基于STM32的热带鱼缸控制系统的设计

文章目录

  • 一、热带鱼缸控制系统
    • 1.题目要求
    • 2.思路
    • 3.电路仿真
      • 3.1 未仿真
      • 3.2 开始仿真,显示屏显示水温、浑浊度、光照强度等值
      • 3.3 当水温低于阈值,开启加热并声光报警
      • 3.4 当浑浊度高于阈值,开启自动换水并声光报警
      • 3.5 当光照低于阈值,开启补光并声光报警
      • 3.6 手动开启增氧和喂食
      • 3.7 远程监控水温等数据,远程控制增氧喂食以及修改温度阈值等
    • 4.仿真程序
      • 4.1 程序说明
      • 4.2 主程序
      • 4.3 OLED显示程序
      • 4.4 串口指令程序
  • 二、总结



一、热带鱼缸控制系统

1.题目要求

部件:
主控:STM32
显示:OLED
温度:防水型DS18B20
浑浊度:TSW-30
光照:光敏电阻
无线通信:蓝牙
继电器5(换水、加热、增氧、喂食、补光)
声光报警:蜂鸣器+LED
按键
5

主要功能需求:

1、实时监测水温、水体浑浊度、光照强度,并显示在OLED屏幕上。

2、通过蓝牙模块将监测到的各项数据传输到手机APP,实现远程监控,同时可以通过手机进行远程控制。

3、水温、光照低于阈值或浑浊度高于阈值开启声光报警。当浑浊度超过阈值,自动开启换水;光照低于阈值,开启补光;水温低于阈值,开启加热。

4、通过按键可以开启增氧、喂食,以及修改温度、浑浊度和光照强度的阈值。

2.思路

主控是STM32,这里我们选择常用的STM32F103C8T6单片机

在这里插入图片描述

显示:OLED

显示的内容比较多1个界面可能不够显示,所以用多个界面,界面切换选择按键切换

在这里插入图片描述

温度:防水型DS18B20

在这里插入图片描述

浑浊度:TSW-30(proteus仿真没有该传感器,所以采用滑动变阻器模拟)

在这里插入图片描述

光照:光敏电阻

在这里插入图片描述

无线通信:蓝牙

在这里插入图片描述

继电器*5(换水、加热、增氧、喂食、补光)和 声光报警:蜂鸣器+LED

在这里插入图片描述

按键*5

通过按键手动开启/关闭增氧,手动开启/关闭喂食,这里两个按键
要修改温度,浑浊度,光照强度的阈值,一共3个阈值,选择用1个按键来切换选择的阈值,另外2个按键增大/减小阈值,这里三个按键。

在这里插入图片描述

3.电路仿真

3.1 未仿真

在这里插入图片描述

3.2 开始仿真,显示屏显示水温、浑浊度、光照强度等值

在这里插入图片描述

3.3 当水温低于阈值,开启加热并声光报警

在这里插入图片描述

3.4 当浑浊度高于阈值,开启自动换水并声光报警

在这里插入图片描述

3.5 当光照低于阈值,开启补光并声光报警

在这里插入图片描述

3.6 手动开启增氧和喂食

在这里插入图片描述

3.7 远程监控水温等数据,远程控制增氧喂食以及修改温度阈值等

远程监控水温,浑浊度,光照强度等数据

远程控制打开增氧,关闭增氧

远程控制打开喂食,关闭喂食

在这里插入图片描述

按下切换按键,切换为设置温度阈值界面,更改温度阈值为50

在这里插入图片描述

按下切换按键,切换为设置浑浊度阈值界面,更改温度阈值为66

在这里插入图片描述
按下切换按键,切换为设置光照阈值界面,更改温度阈值为80
在这里插入图片描述

4.仿真程序

4.1 程序说明

主控芯片:STM32F103C8
HSI:64MHZ
Systick: 1ms

浑浊度传感器:ADC(PA0)

光照传感器:LDR(PA2)

DS18B20温度传感器:DAT(PA4)

模拟蓝牙模块(Uart1):9600(PA9:tx1,PA10:rx1)

声光报警:BUZZER(PA15)

按键:
KEY1(PB0)
KEY2(PB1)
KEY3(PB2)
KEY2(PB3)
KEY5(PB4)

换水:RELAY1(PB6)
加热:RELAY2(PB7)
增氧:RELAY3(PB8)
喂食:RELAY4(PB9)
补光:RELAY5(PB10)

OLED显示屏:SCL(PB14),SDA(PB15)

在这里插入图片描述

串口协议
举例如发送*Temp50,即设置温度阈值位50度
*TempXX 设置温度阈值 XX取值为0-99
*MuddXX 设置浑浊度阈值 XX取值为0-99
*IlluXX 设置光照阈值 XX取值为0-99
*oxygX 开启/关闭增氧 X取值为0-1
*feedX 开启/关闭喂食 X取值为0-1
*Read 远程监控水温、水体浑浊度、光照强度等数据,

4.2 主程序

/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
	UserSystemInit();//用户配置初始化		
	while (1)
	{			
			if(stSysTime.flg._10ms + TEN_MILLISECOND < Time_millis()) //10ms
			{
				stSysTime.flg._10ms = Time_millis();	
                Key_Scan();//按键扫描					
			}	
			if(stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
			{
				stSysTime.flg._50ms = Time_millis();
                ADC_Scan();//采集浑浊度和光照强度				
			}				
			if(stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
			{
				stSysTime.flg._100ms = Time_millis();		
                DS18B20_Collect_data();//DS18B20采集温度数据					
				OLED_Handel();//OLED显示			
                Forewarning_Handel();//预警函数		
                Receive_data_Handel();//数据接收判断				
				IWDG_ReloadCounter();//清开门狗 				
			}				
  }
}

4.3 OLED显示程序

/*******************************************************************************
 * 函数名:OLED_Handel
 * 描述  :OLED显示
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :100ms
*******************************************************************************/
void OLED_Handel(void)
{  	
		if(ADC_Flag)
		{	
			if(Threshold_switching == 0)
			{
				OLED_Show_Character(1,1,0,16);//水
				OLED_Show_Character(1,2,1,16);//温		
				OLED_Show_Character(1,3,2,16);//:	
			
				OLED_ShowNum(1,7,Temp_High,2);	
			
				OLED_ShowString(1, 9, ".");	
				OLED_ShowNum(1,10,Temp_Low,1);	

				OLED_Show_Character(1,6,3,16);//°
				OLED_ShowString(1, 13, "C");
				
				OLED_Show_Character(2,1,4,16);//浑
				OLED_Show_Character(2,2,5,16);//度
				OLED_Show_Character(2,3,6,16);//度				
				OLED_Show_Character(2,4,2,16);//:

				OLED_ShowNum(2,9,ADC1_Value,2);	
				OLED_ShowString(2, 11, "%");			

				OLED_Show_Character(3,1,7,16);//光
				OLED_Show_Character(3,2,8,16);//照
				OLED_Show_Character(3,3,9,16);//强
				OLED_Show_Character(3,4,10,16);//度		
				OLED_Show_Character(3,5,2,16);//:		

				OLED_ShowNum(3,11,ADC2_Value,2);	
				OLED_ShowString(3, 13, "%");
		  }
			else if(Threshold_switching == 1)
			{
				OLED_Show_Character(1,1,0,16);//水
				OLED_Show_Character(1,2,1,16);//温		
				OLED_Show_Character(1,3,11,16);//阈
				OLED_Show_Character(1,4,12,16);//值					
				OLED_Show_Character(1,5,2,16);//:	

				OLED_ShowNum(1,11,Temp_Threshold,2);	

				OLED_Show_Character(1,7,3,16);//°
				OLED_ShowString(1, 15, "C");				
			}
			else if(Threshold_switching == 2)
			{
				OLED_Show_Character(1,1,4,16);//浑
				OLED_Show_Character(1,2,5,16);//度
				OLED_Show_Character(1,3,6,16);//度		
				OLED_Show_Character(1,4,11,16);//阈
				OLED_Show_Character(1,5,12,16);//值					
				OLED_Show_Character(1,6,2,16);//:	

				OLED_ShowNum(1,13,ADC1_Threshold,2);	

				OLED_ShowString(1, 15, "%");				
			}	
			else if(Threshold_switching == 3)
			{	
				OLED_Show_Character(1,1,7,16);//光
				OLED_Show_Character(1,2,8,16);//照					
				OLED_Show_Character(1,3,11,16);//阈
				OLED_Show_Character(1,4,12,16);//值					
				OLED_Show_Character(1,5,2,16);//:	

				OLED_ShowNum(1,13,ADC2_Threshold,2);	

				OLED_ShowString(1, 15, "%");				
			}			
		}			
}

4.4 串口指令程序

/*******************************************************************************
 * 函数名:Send_Cmd1
 * 描述  :设置温度阈值
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :举例如发送*Temp50,即设置温度阈值位50度
 *******************************************************************************/
void Send_Cmd1(void)
{
	uint8_t i = 0; 
	variable1 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));
	if(variable1 < 99)
	{
		Temp_Threshold = variable1;
		printf("手机设置的温度阈值 = %d\r\n",Temp_Threshold);	
	}
	else
	{
		printf("手机设置的温度阈值超出设置范围 \r\n");			
	}
}

/*******************************************************************************
 * 函数名:Send_Cmd2
 * 描述  :设置水体浑浊度阈值
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :
 *******************************************************************************/
void Send_Cmd2(void)
{
	uint8_t i = 0;
	variable2 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));
	if(variable2 < 99)
	{
		ADC1_Threshold = variable2;
		printf("手机设置的水体浑浊度阈值 = %d\r\n",ADC1_Threshold);	
	}	
	else
	{
		printf("手机设置的水体浑浊度阈值超出设置范围 \r\n");			
	}	
}

/*******************************************************************************
 * 函数名:Send_Cmd3
 * 描述  :设置光照阈值
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :
 *******************************************************************************/
void Send_Cmd3(void)
{
	uint8_t i = 0;
	variable3 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));
	if(variable3 < 99)
	{
		ADC2_Threshold = variable3;
		printf("手机设置的光照阈值 = %d\r\n",ADC2_Threshold);
	}		
	else
	{
		printf("手机设置的光照阈值超出设置范围 \r\n");			
	}	
}

/*******************************************************************************
 * 函数名:Send_Cmd4
 * 描述  :开启/关闭增氧 
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :
 *******************************************************************************/
void Send_Cmd4(void)
{
	uint8_t i = 0;
	variable4 = AsciiToHex(uart1_rx_buf[i+5]);
	if(variable4 == 0)
	{
		Relay3_Off();	
		printf("关闭增氧\r\n");
	}		
	else if (variable4 == 1)
	{
		Relay3_On();			
		printf("打开增氧 \r\n");			
	}	
	else 
	{
		printf("手机设置的供氧模式超出设置范围 \r\n");			
	}
}


/*******************************************************************************
 * 函数名:Send_Cmd5
 * 描述  :开启/关闭喂食
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :
 *******************************************************************************/
void Send_Cmd5(void)
{
	uint8_t i = 0;
	variable5 = AsciiToHex(uart1_rx_buf[i+5]);
	if(variable5 == 0)
	{
		Relay4_Off();	
		printf("关闭喂食\r\n");
	}		
	else if (variable5 == 1)
	{
		Relay4_On();			
		printf("打开喂食 \r\n");			
	}	
	else 
	{
		printf("手机设置的喂食模式超出设置范围 \r\n");			
	}
}

/*******************************************************************************
 * Function    : Receive_data_Handel
 * Description : 数据接收判断
 * Input       : 无
 * Return      : 无
 * Call        : 100ms
 * Others      :
 *******************************************************************************/
void Receive_data_Handel(void)
{
	uint8_t i = 0;
	if(uart1_rx_finsh)
	{	  
			for(i = 0;i< 20; i++)
			{
					if(uart1_rx_buf[i] == '*')	
					{
							switch(uart1_rx_buf[i+1])
							{
								case  'T':Send_Cmd1();break;//*TempXX		
								case  'M':Send_Cmd2();break;//*MuddXX
								case  'I':Send_Cmd3();break;//*IlluXX		
								case  'o':Send_Cmd4();break;//*oxygX		
								case  'f':Send_Cmd5();break;//*feedX		
								case  'R':Printf_Task();break;//*Read							
								default:break;							
							}							
					}
			}
			uart1_rx_finsh = 0;	
			uart1_rx_count = 0;
			memset(uart1_rx_buf,0,RX_MAX_NUM);				
	}	
}

/*******************************************************************************
 * Function    : Printf_Task
 * Description : 打印数据任务
 * Input       : 无
 * Return      : 无
 * Call        : 1s
 * Others      :
 *******************************************************************************/
void Printf_Task(void)
{
   if(ADC_Flag)
   {	
	     printf("水温=%d.%d 水体浑浊度=%d 光照强度=%d\r\n",Temp_High,Temp_Low,ADC1_Value,ADC2_Value);	
   }
}

二、总结

今天主要讲了基于STM32的热带鱼缸控制系统的设计。

感谢你的观看!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948205.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【DevOps】Jenkins项目发布

Jenkins项目发布 文章目录 Jenkins项目发布前言资源列表基础环境一、Jenkins发布静态网站1.1、项目介绍1.2、部署Web1.3、准备gitlab1.4、配置gitlab1.5、创建项目1.6、推送代码 二、Jenkins中创建gitlab凭据2.1、创建凭据2.2、在Jenkins中添加远程主机2.3、获取gitlab项目的UR…

SSM-SpringMVC

目录 “为什么要学 SpringMVC&#xff1f;它和 Servlet 是什么关系&#xff1f;” “什么是异步&#xff1f;为什么异步交互中常用 JSON 格式&#xff1f;异步请求和 JSON 如何配合&#xff1f;” 一、概述 SpringMVC主要负责 1 SpringMVC的常用组件 2 SpringMVC的工作流程…

基层医联体医院患者历史检验检查数据的快速Python编程分析

​​​​​​​ 一、引言 1.1 研究背景与意义 在当今数字化医疗时代,医疗数据呈爆炸式增长,涵盖患者的基本信息、病史、检验检查结果、治疗方案等各个维度。这些海量且复杂的数据蕴含着巨大价值,为精准医疗决策提供了关键依据。通过对患者历史检验检查数据的深入对比分析…

计算机网络基础(7)中科大郑铨老师笔记

应用层 目标&#xff1a;  网络应用的 原理&#xff1a;网络应用协议的概念和实现方面 传输层的服务模型 客户-服务器模式 对等模式(peerto-peer) 内容分发网络  网络应用的 实例&#xff1a;互联网流行的应用层协 议  HTTP  FTP  SMTP / POP3 / IMAP  DNS…

Fabric环境部署-Git和Node安装

一.安装Git&#xff08;v2.43.0&#xff09; Git 是一个开源的分布式版本管理系统&#xff08;也是全球最大的开源软件存储服务器&#xff09;&#xff0c;用于敏捷高效地处理任何或小或大的项目。搭建区块链需要使用Git&#xff0c;因为区块链的开发和部署需要使用版本控制工…

SAP MM物料管理模块常见BAPI函数清单

【SAP系统研究】 #SAP #MM #物料管理 #函数 #BAPI 1、物料主数据 BAPI_MATERIAL_SAVEDATA 创建/更改物料主数据 BAPI_MATERIAL_SAVEREPLICA 物料主数据视图扩充 BAPI_MATERIAL_EXISTENCECHECK 检查物料主数据是否存在 BAPI_MATERIAL_GETLIST 显示物料主数据明细 BAPI_MATERIALG…

Windows11安装Oracle11g以及plsqldev工具连接配置

文章目录 一、安装Oracle数据库软件二、配置数据库三、配置监听&#xff08;listener.ora&#xff09;四、本地网络服务名配置&#xff08;tnsnames.ora&#xff09;五、网络服务名配置以及监听文件路径六、plsqldev工具连接Oracle配置 一、安装Oracle数据库软件 点击“setup.…

unity学习6:unity的3D项目的基本界面和菜单

目录 1 unity界面的基本认识 1.1 file 文件 1.2 edit 编辑/操作 1.3 Assets 1.4 gameobject 游戏对象 1.5 组件 1.6 windows 2 这些部分之间的关系 2.1 关联1&#xff1a; Assets & Project 2.2 关联2&#xff1a;gameobject & component 2.3 关联3&#xf…

HTML5新特性|06 文本效果text-shadowword-wrap自定义字体

文本效果 1、CSS3包含多个新的文本特性 属性: text-shadow:水平阴影 垂直阴影 模糊距离 阴影颜色 word-wrap&#xff1a;用于指定当文本溢出其容器的边界时如何处理换行的问题 浏览器支持: Internet Explorer 10、Firefox、 Chrome、 Safari 以及Opera支持text-shadow属性…

【踩坑指南2.0 2025最新】Scala中如何在命令行传入参数以运行主函数

这个地方基本没有任何文档记录&#xff0c;在学习的过程中屡屡碰壁&#xff0c;因此记录一下这部分的内容&#xff0c;懒得看可以直接跳到总结看结论。 踩坑步骤 首先来看看书上让我们怎么写&#xff1a; //main.scala object Start {def main(args:Array[String]) {try {v…

【路径跟踪】PIDMPC

路径跟踪&#xff08;Path Tracking&#xff09;是指在实际行驶过程中&#xff0c;根据预先规划好的路径进行控制&#xff0c;能够沿着设定的路径行驶。常见的路径跟踪算法包括基于模型的控制方法&#xff08;如PID控制器&#xff09;、模型预测控制&#xff08;Model Predicti…

python3GUI--智慧交通监控与管理系统 By:PyQt5

文章目录 一&#xff0e;前言二&#xff0e;预览三&#xff0e;软件组成&技术难点1.软件组成结构2.技术难点3.项目结构 四&#xff0e;总结 大小&#xff1a;35.5 M&#xff0c;软件安装包放在了这里! 一&#xff0e;前言 博主高产&#xff0c;本次给大家带来一款我自己使…

HP 电脑开机黑屏 | 故障判断 | BIOS 恢复 | BIOS 升级

注&#xff1a;本文为 “HP 电脑开机黑屏 | 故障判断 | BIOS 恢复 | BIOS 升级” 相关文章合辑。 引文图片 csdn 转储异常&#xff0c;重传。 篇 1&#xff1a;Smart-Baby 回复中给出故障现象判断参考 篇 2、篇3 &#xff1a;HP 官方 BIOS 恢复、升级教程 开机黑屏&#xff0c…

三甲医院等级评审八维数据分析应用(一)--组织、制度、管理可视化篇

一、引言 1.1 研究背景与意义 在当今医疗领域,三甲医院作为医疗服务的核心载体,肩负着保障民众健康、推动医学进步的重任。随着信息技术的飞速发展,数据已成为医院运营管理、医疗质量提升以及科学决策的关键要素。三甲医院等级评审作为衡量医院综合实力与服务水平的重要标…

数据表中列的完整性约束概述

文章目录 一、完整性约束概述二、设置表字段的主键约束三、设置表字段的外键约束四、设置表字段的非空约束五、设置表字段唯一约束六、设置表字段值自动增加七、设置表字段的默认值八、调整列的完整性约束 一、完整性约束概述 完整性约束条件是对字段进行限制&#xff0c;要求…

关于PINN进一步的探讨

pinn 是有监督、无监督、半监督&#xff1f; PINN&#xff08;Physics-Informed Neural Networks&#xff0c;物理信息神经网络&#xff09;通常被归类为一种有监督学习的方法。在PINN中&#xff0c;神经网络的训练过程不仅依赖于数据点&#xff08;例如实验观测数据&#xff0…

VUE条件树查询 自定义条件节点

之前实现过的简单的条件树功能如下图&#xff1a; 经过最新客户需求确认&#xff0c;上述条件树还需要再次改造&#xff0c;以满足正常需要&#xff01; 最新暴改后的功能如下红框所示&#xff1a; 页面功能 主页面逻辑代码&#xff1a; <template><div class"…

游戏如何检测iOS越狱

不同于安卓的开源生态&#xff0c;iOS一直秉承着安全性更高的闭源生态&#xff0c;系统中的硬件、软件和服务会经过严格审核和测试&#xff0c;来保障安全性与稳定性。 据FairGurd观察&#xff0c;虽然iOS系统具备一定的安全性&#xff0c;但并非没有漏洞&#xff0c;如市面上…

GraphRAG vs 传统 RAG:如何通过知识图谱提升 AI 检索能力

相比传统 RAG 仅能独立检索文本片段的局限性&#xff0c;GraphRAG通过构建实体关系图谱实现了信息间的连接&#xff0c;让 AI 能更完整地理解和检索复杂的关联信息&#xff0c;从而生成更准确和连贯的回答 问题背景: 想象有一本详细记录某人(X)成就的传记,每个章节都描述了他的…

Linux平台下实现的小程序-进度条

目录 1.换行、回车概念 2.缓冲区 2.1缓冲区 2.2强制刷新 3.进度条程序 Makefile文件 ProgressBar.h ProgressBar.c Main.c 执行结果 1.换行、回车概念 /n&#xff1a;换行回车&#xff08;\r&#xff1a;回车&#xff09; 2.缓冲区 如下图在vim编辑器中的命令模式下…