基于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;//*MuddXXcase '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的热带鱼缸控制系统的设计。
感谢你的观看!

相关文章:
基于STM32的热带鱼缸控制系统的设计
文章目录 一、热带鱼缸控制系统1.题目要求2.思路3.电路仿真3.1 未仿真3.2 开始仿真,显示屏显示水温、浑浊度、光照强度等值3.3 当水温低于阈值,开启加热并声光报警3.4 当浑浊度高于阈值,开启自动换水并声光报警3.5 当光照低于阈值,…...
Vue项目整合与优化
前几篇文章,我们讲述了 Vue 项目构建的整体流程,从无到有的实现了单页和多页应用的功能配置,但在实现的过程中不乏一些可以整合的功能点及可行性的优化方案,就像大楼造完需要进行最后的项目验收改进一样,有待我们进一步…...
WinForm开发-自定义组件-1. 工具栏: UcompToolStrip
这里写自定义目录标题 1. 工具栏: UcompToolStrip1.1 展示效果1.2 代码UcompToolStrip.csUcompToolStrip.Designer.cs 1. 工具栏: UcompToolStrip 自定义一些Winform组件 1.1 展示效果 1)使用效果 2)控件事件 1.2 代码 设计 编码 UcompToolStrip.…...
法律专业legal case的留学论文写作技巧分析(1)
对于法律专业的留学生而言,案例的分析是写作的重要方面。无论留学的国家是英、美、澳洲还是加拿大,它们都属于case law 的法律体系。一个非常显著的特点便是通过对案例进行分析和提炼,从中总结提炼出principle和rules。case analysis的留学论…...
2025编程技术前沿:探索最新的开发工具与趋势
随着技术的飞速发展,编程领域每天都在演化,新的技术、框架和工具层出不穷。本文将聚焦2025年最具潜力和吸引力的编程技术与工具,从前沿语言到最受欢迎的开发框架,带您一起探索软件开发领域的最新趋势。 一、编程语言的新生代之星…...
sqlserver sql转HTMM邮件发送
通过sql的形式,把表内数据通过邮件的形式发送出去 declare title varchar(100) DECLARE stat_date CHAR(10),create_time datetime SET stat_dateCONVERT(char(10),GETDATE(),120) SET create_timeDATEADD(MINUTE,-20,GETDATE()) DECLARE xml NVARCHAR (max) DECLAR…...
GeoTrust True BusinessID Wildcard
GeoTrust由DigiCert 提供支持,是最受信任和尊重的品牌之一,以提供高保证的网站安全而闻名。 GeoTrust True BusinessID通配符证书 – 以低成本保护多个主机名。即使将其用于您的公司主页或电子邮件服务器主机名,保护所有敏感信息也是您的目标…...
R语言的数据结构
R语言的数据结构 R语言是专门为统计计算和数据分析而设计的一种编程语言,因其强大的数据处理能力而受到广泛欢迎。在R中,数据结构是理解和有效使用R语言的基础。本文将详细介绍R语言中的主要数据结构,包括向量、矩阵、数据框、列表、因子等&…...
安装和配置MySQL教程
以下是在不同操作系统下安装和配置MySQL的详细教程: Windows系统 下载MySQL安装包 访问MySQL官方网站(https://dev.mysql.com/downloads/mysql/),根据你的操作系统版本(32位或64位)下载相应的MySQL Commu…...
黑马Java面试教程_P10_设计模式
系列博客目录 文章目录 系列博客目录前言1. 工厂方法模式1.1 概述1.2 简单工厂模式1.2.1 结构1.2.2 实现1.2.3 优缺点 1.3 工厂方法模式1.3.1 概念1.3.2 结构1.3.3 实现1.3.4 优缺点 1.4 抽象工厂模式1.4.1 概念1.4.2 结构1.4.3 实现1.4.4 优缺点1.4.5 使用场景 总结࿰…...
043_小驰私房菜_MTK Camera,Hal层将camera型号写到property属性中
【问题背景】 app层需要知道当前设备的摄像头型号,然后做一些差异化处理。底下如何上报这个摄像头型号? 【分析】 在kernel和hal层,都是有地方能获取到当前摄像头的型号,就看在哪里添加方便。获取到摄像头硬件型号后,将其写入到property属性, 然后app就可以通过读取该…...
基础图形化界面的一个图片爬虫期末
下面是爬取界面: 点击即可自动化爬取 以下是完整代码: import tkinter as tk import requests import os #用于文件和目录操作。# 图片爬虫函数 def image_spider(textbox):headers = {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …...
Outlook2024版如何回到经典Outlook
Outlook2024版如何回到经典Outlook 如果新加入一家公司,拿到的电脑,大概率是最新版的Windows, 一切都是新的。 如果不coding, 使用国产的foxmail大概就可以解决一切问题了。可惜老程序员很多Coding都是基于传统Outlook的,科技公司所有人都是I…...
仿生的群体智能算法总结之二(十种)
群体智能算法是一类通过模拟自然界中的群体行为来解决复杂优化问题的方法。以下是10种常见的群体智能算法,接上文https://blog.csdn.net/lzm12278828/article/details/144933367仿生的群体智能算法总结之一(十种)-CSDN博客https://blog.csdn.net/lzm12278828/article/detail…...
SpringBoot入门之创建一个Hello World项目
文章目录 一、使用传统的方式1、创建一个SpringBoot项目2、配置pom.xml文件3、下载Maven依赖4、创建一个Controller类:com.devops.controller.HelloController5、创建一个引导类:com.devops.HelloApplication6、启动项目8、访问80809、完整项目结构 二、…...
MySQL与标准SQL的区别
我们试图使MySQL Server遵循ANSI SQL标准和ODBC SQL标准,但MySQL Server在某些情况下执行不同的操作: MySQL和标准SQL特权系统之间有一些区别。例如,在MySQL中,删除表时不会自动撤销表的特权。您必须显式发出REVOKE来撤销表的特权…...
docker中使用Dockerfile设置Volume挂载点
关于在docker中如何使用Volume,可以参考文章: docker中使用Volume完成数据共享-CSDN博客 如果想在生成docker镜像的时候设置好挂载点,而不是在运行镜像生成容器时生成。 下面以自建一个tomcat镜像为例,演示如何在生成镜像时设置…...
Samsung手机首次主要采用竞对Micron LPDDR5内存
根据韩国媒体《韩国先驱报》(The Korea Herald)的报道,即将在1月底发布的三星 Galaxy S25 系列智能手机将首次主要使用美光科技(Micron Technology)提供的移动DRAM,而非三星自家的产品。这一消息对于三星的…...
【项目开发】C#环境配置及VScode运行C#教程(学生管理系统)
原创文章,禁止转载。 文章目录 下载.NETVScode配置运行程序下载.NET 官网链接: https://dotnet.microsoft.com/en-us/download选择任意版本下载: 下载完成后,双击运行exe文件,等待安装完成。 在控制台输入: dotnet --version若出现版本信息,说明安装成功: VScode配…...
[241231] CachyOS 2024 年终总结:性能飞跃与社区繁荣 | ScyllaDB 宣布转向开源可用许可证
目录 CachyOS 2024 年终总结:性能飞跃与社区繁荣ScyllaDB 宣布转向开源可用许可证 CachyOS 2024 年终总结:性能飞跃与社区繁荣 CachyOS 2024 年的最后一个版本 (也是第 13 个版本) 已经发布,同时也迎来了辞旧迎新之际。让我们一起回顾 Cachy…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
