【STM32项目开源】基于STM32的智能养殖场环境监测系统

目录

一、设计背景和意义

1.1设计背景

1.2设计意义

二、实物效果展示

2.1实物图片

2.2实物演示视频

三、硬件功能简介

3.1项目功能详解

3.2元器件清单

四、主框图与软件流程图

五、硬件PCB展示

六、软件程序设计

七、项目资料包内容

资料获取:查看主页介绍"充哥单片机设计"


一、设计背景和意义

1.1设计背景

在现代农业快速发展的背景下,智能化养殖已成为推动农业产业升级的重要方向之一。传统养殖方式普遍存在人工管理强度大、实时性差、环境控制滞后等问题,特别是在温湿度、光照、水质、空气质量等关键环境因素无法实现精确调控的情况下,极易导致动物应激、饲料浪费、疫病传播等风险,从而制约了养殖效益的提升与规模化发展。当前市场上虽然存在部分商用的智能养殖解决方案,但往往存在价格高昂、系统封闭、部署复杂、定制性差等问题,难以被广大中小型养殖户广泛接受。同时,这类产品在灵活性和可扩展性方面也存在一定局限性,难以根据具体的养殖需求进行灵活配置。

1.2设计意义

传统养殖业中,人工巡检存在效率低下、误差较大且难以实现 24 小时连续监测的问题,这往往导致环境异常不能被及时发现,进而影响养殖生物的生长甚至存活。而该系统能够实时、精准地监测养殖环境中的温湿度、空气质量、光照强度等多参数,一旦发现异常便能迅速响应,有效减少环境变化对养殖生物的不良影响,显著提高养殖生物的存活率。不仅如此,远程控制与自动调节功能的实现,大幅降低了人工干预的成本,让养殖管理不再受地域和时间的限制,极大提升了养殖管理的智能化水平。

二、实物效果展示

2.1实物图片

2.2实物演示视频

【开源】基于STM32的智能养殖环境监测系统

三、硬件功能简介

3.1项目功能详解

  1. 传感器检测:检测温湿度、氨气浓度、饲料重量、水槽水位、光照强度等数据。
  2. 数据显示:0.96OLED屏幕显示全部的传感器数据以及传感器的阈值等数据。
  3. 执行机构:控制风扇、水泵、LED灯、步进电机(喂食)。
  4. 接入云平台:系统通过ESP8266 WIFI联网后,接入机智云平台。
  5. App远程监控:通过App远程监控全部传感器数据;App远程控制LED和步进电机。
  6. 阈值数据设定:系统通过按键设定阈值,也可以通过手机App远程设定。
  7. 模式切换:可以通过按键或者手机App实现自动/手动模式的切换。
  8. 手动模式:通过手机App或小程序控制开关
  9. 自动模式: 检测到光照强度低于阈值,自动打开补光灯; 检测到水位低于阈值,自动打开水泵;检测到氨气浓度或温度超过阈值,打开风扇通风,并蜂鸣器报警;检测到饲料重量低于阈值,自动打开步进电机喂食。

3.2元器件清单

  1. 主控STM32F103C8T6最小系统板
  2. 0.96OLED显示屏幕
  3. DHT11温湿度传感器
  4. MQ-135氨气浓度传感器
  5. 光敏电阻传感器
  6. 水位传感器
  7. 称重传感器
  8. 继电器
  9. 加热片
  10. 加水水泵
  11. 风扇水泵
  12. 步进电机
  13. 蜂鸣器
  14. 按键

四、主框图与软件流程图

主框图

流程图

五、硬件PCB展示

六、软件程序设计

cpp 复制代码
#include "delay.h"
#include "sys.h"
#include "bmp.h"
#include "adc.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "control.h"
#include "dht11.h"
#include "hx711.h"
#include "uln2003.h"
#include "timer.h"

int NH3_value_door = 50;
int food_time = 0;
int food_space = 0;
int food_num = 0;
int food_high = 0;
int food_low = 0;
int water_time = 0;
int water_high = 0;
int water_low = 0;

uint8_t water_mode = 0;
uint8_t food_mode = 0;

uint16_t timeone = 0;
uint16_t timetwo = 0;
uint16_t timethree = 0;
uint16_t timefore = 0;
uint8_t food_flag = 0;
uint8_t water_flag = 0;
uint8_t option = 0;
uint8_t keu_num = 0;
uint8_t page_num = 1;
void LED_Init(void);
void OLED_Show_FirstPage();
void OLED_Show_SecondPage();
void OLED_Show_ThirdPage();

void get_all_sensor_data();
void Sensor_Data_Handle();

int value;
float weight;
int32_t reset;
u8 bufff[30];

float Weights=19231.0;  //100g
int32_t Weights_100=8493860;  //100g

int main(void)
{
	
	delay_init();
	OLED_Init();
	OLED_Show_FirstPage();
	uart3_init(9600);
	uart1_init(115200);
//	uart2_init(115200);
	HX711_Init();
	reset = HX711_GetData();         
	Uln2003_Init();
	TIME_Config();
	KEY_Init();
	DHT11_Init();
	Adc_Init();
	Control_Init();

	while(1)
	{
		get_all_sensor_data();
		Sensor_Data_Handle();
	 if(page_num == 1){
		 OLED_Show_FirstPage();
	 }else if(page_num == 2){
		 OLED_Show_SecondPage();
	 }else if(page_num == 3){
		 OLED_Show_ThirdPage();
	 }

	}
}

void Sensor_Data_Handle()
{
	
	if(food_mode==1){
		if(weight<food_low*1000)food_flag=1;
		else if(weight>=food_high*1000)food_flag=0;
		
		if(food_flag==1)Stepper_RotateByLoop(Forward,1,1);
			
		if(timeone>=food_space*5&&food_flag==0){
			Stepper_RotateByLoop(Forward,food_num,1);
			timeone=0;
		}
		//5秒钟代替1分钟
		if(timetwo>=food_time*5){
			food_mode=0;
		}
	}
	
	if(water_mode==1){
		if(Water_Value<water_low)water_flag=1;
		else if(Water_Value>=water_high)water_flag=0;
		
		if(water_flag==1)Watertwo=1;
		else Watertwo=0;
			
		//5秒钟代替1分钟
		if(timefore>=water_time*5){
			water_mode=0;Watertwo=0;
		}
	}else{
		Watertwo=0;
	}
	
	
	if(NH3_Value>NH3_value_door)Waterone=1;
	else Waterone=0;
	if(temp>27)Wind=1;
	else Wind=0;

}

void get_all_sensor_data()
{
	DHT11_Read_Data(&temp,&hum);    //获取温湿度数据
	value = HX711_GetData();
	weight=(float)(value-reset)*Weights/(float)(Weights_100-reset);
	weight=(int)weight;
	Get_NH3_Value(&NH3_Value);
	Get_Water_Value(&Water_Value);
}

void Key_event_handle(void)
{
	keu_num = KEY_Scan(0);
	switch(keu_num)
	{
		case 1:
			if(page_num == 1){
				option++;
				if(option==4)option=0;
				OLED_Show_FirstPage();
			}else if(page_num == 2){
				option++;
				if(option==6)option=0;
				OLED_Show_SecondPage();
			}else if(page_num == 3){
				option++;
				if(option==4)option=0;
				OLED_Show_ThirdPage();
			}
			break;
		case 2:
			if(page_num==1&&option==2){		
				page_num=2;option=0;
				OLED_Clear();OLED_Show_SecondPage();
			}else if(page_num==1&&option==3){
				page_num=3;option=0;
				OLED_Clear();OLED_Show_ThirdPage();
			}else if(page_num==2||page_num==3){
				page_num=1;option=0;
				OLED_Clear();OLED_Show_FirstPage();
			}
			break;
		case 3:
			if(page_num==1&&option==1){
				NH3_value_door++;
				OLED_Show_FirstPage();
			}else if(page_num==1&&option==2){		
				food_mode=0;
				OLED_Show_FirstPage();
			}else if(page_num==1&&option==3){
				water_mode=0;
				OLED_Show_FirstPage();		
			}else if(page_num==2&&option==1){
				food_time+=10;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==2){
				food_space+=1;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==3){
				food_num+=1;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==4){
				food_low+=1;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==5){
				food_high+=1;
				OLED_Show_SecondPage();
			}else if(page_num==3&&option==1){
				water_time+=10;
				OLED_Show_ThirdPage();
			}else if(page_num==3&&option==2){
				water_high+=1;
				OLED_Show_ThirdPage();
			}else if(page_num==3&&option==3){
				water_low+=1;
				OLED_Show_ThirdPage();
			}
			break;
		case 4:
			if(page_num==1&&option==1){
				NH3_value_door--;
				OLED_Show_FirstPage();
			}else if(page_num==1&&option==2){		
				food_mode=1;
				OLED_Show_FirstPage();
			}else if(page_num==1&&option==3){
				water_mode=1;
				OLED_Show_FirstPage();		
			}else if(page_num==2&&option==1){
				food_time-=10;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==2){
				food_space-=1;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==3){
				food_num-=1;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==4){
				food_low-=1;
				OLED_Show_SecondPage();
			}else if(page_num==2&&option==5){
				food_high-=1;
				OLED_Show_SecondPage();
			}else if(page_num==3&&option==1){
				water_time-=10;
				OLED_Show_ThirdPage();
			}else if(page_num==3&&option==2){
				water_high-=1;
				OLED_Show_ThirdPage();
			}else if(page_num==3&&option==3){
				water_low-=1;
				OLED_Show_ThirdPage();
			}
			break;
	}
}



/*
 氨(0) 气(1) 浓(2) 度(3) 温(4) 水(5) 位(6) 自(7) 动(8) 喂(9) 食(10) 补(11) 水(12) 间(13) 隔(14) 次(15)
 数(16) 时(17) 长(18) 开(19) 关(20) ℃(21) 饲(22) 料(23) 设(24) 置(25) 最(26) 低(27) 高(28 重(29) 量(30)
*/
void OLED_Show_FirstPage(){
	
	OLED_ShowChar(8*0,0,'T',16,1);
	OLED_ShowChar(8*1,0,':',16,1);				//	":"
	OLED_ShowNum(16*1,0,temp,2,16,1);		//	temp
	OLED_ShowChinese(16*2,0,21,16,1);			//	"湿"

	OLED_ShowChinese(16*4-8,0,5,16,1);
	OLED_ShowChinese(16*5-8,0,6,16,1);
	OLED_ShowChar(16*6-8,0,':',16,1);
	OLED_ShowNum(16*6,0,Water_Value,2,16,1);
	
	OLED_ShowString(16*0,16,"NH3:",16,1);
	if(option==1)OLED_ShowNum(16*2,16,NH3_value_door,2,16,0);
	else OLED_ShowNum(16*2,16,NH3_Value,2,16,1);
	
	OLED_ShowChinese(16*4-8,16,22,16,1);
	OLED_ShowChinese(16*5-8,16,23,16,1);
	OLED_ShowChar(16*6-8,16,':',16,1);
	OLED_ShowNum(16*6,16,weight,4,16,1);
	
	
	OLED_ShowChinese(16*0,32,7,16,1);
	OLED_ShowChinese(16*1,32,8,16,1);
	OLED_ShowChinese(16*2,32,9,16,1);
	OLED_ShowChinese(16*3,32,10,16,1);
	OLED_ShowChar(16*4,32,':',16,1);
	if(food_mode==1)OLED_ShowChinese(16*4+8,32,19,16,1);
	else OLED_ShowChinese(16*4+8,32,20,16,1);
	
	OLED_ShowChinese(16*0,48,7,16,1);
	OLED_ShowChinese(16*1,48,8,16,1);
	OLED_ShowChinese(16*2,48,11,16,1);
	OLED_ShowChinese(16*3,48,12,16,1);
	OLED_ShowChar(16*4,48,':',16,1);
	if(water_mode==1)OLED_ShowChinese(16*4+8,48,19,16,1);
	else OLED_ShowChinese(16*4+8,48,20,16,1);
	
	if(option == 2){
		OLED_ShowChar(16*5+8,32,'<',16,1);
		OLED_ShowChar(16*5+8,48,' ',16,1);
	}else if(option == 3){
		OLED_ShowChar(16*5+8,32,' ',16,1);
		OLED_ShowChar(16*5+8,48,'<',16,1);
	}else{
		OLED_ShowChar(16*5+8,32,' ',16,1);
		OLED_ShowChar(16*5+8,48,' ',16,1);
	}
	
	OLED_Refresh();
	
}

void OLED_Show_SecondPage(){
	
	OLED_ShowChinese(16*1,0,7,16,0);
	OLED_ShowChinese(16*2,0,8,16,0);
	OLED_ShowChinese(16*3,0,9,16,0);
	OLED_ShowChinese(16*4,0,10,16,0);
	OLED_ShowChinese(16*5,0,24,16,0);
	OLED_ShowChinese(16*6,0,25,16,0);
	
	OLED_ShowChinese(16*0,16,17,16,1);
	OLED_ShowChinese(16*1,16,18,16,1);
	OLED_ShowChar(16*2,16,':',16,1);
	if(option==1)OLED_ShowNum(16*2+8,16,food_time,3,16,0);
	else OLED_ShowNum(16*2+8,16,food_time,3,16,1);
	OLED_ShowString(16*4,16,"m",16,1);

	OLED_ShowChinese(16*0,32,13,16,1);
	OLED_ShowChinese(16*1,32,14,16,1);
	OLED_ShowChar(16*2,32,':',16,1);
	if(option==2)OLED_ShowNum(16*2+8,32,food_space,2,16,0);
	else OLED_ShowNum(16*2+8,32,food_space,2,16,1);
	OLED_ShowString(16*3+8,32,"m",16,1);
	
	OLED_ShowChinese(16*4,32,15,16,1);
	OLED_ShowChinese(16*5,32,16,16,1);
	OLED_ShowChar(16*6,32,':',16,1);
	if(option==3)OLED_ShowNum(16*6+8,32,food_num,2,16,0);
	else OLED_ShowNum(16*6+8,32,food_num,2,16,1);
	
	OLED_ShowChinese(16*0,48,22,16,1);
	OLED_ShowChinese(16*1,48,23,16,1);
	OLED_ShowChinese(16*2,48,29,16,1);
	OLED_ShowChinese(16*3,48,30,16,1);
	OLED_ShowChar(16*4,48,':',16,1);
	if(option==4)OLED_ShowNum(16*4+8,48,food_low,2,16,0);
	else OLED_ShowNum(16*4+8,48,food_low,2,16,1);
	OLED_ShowString(16*5+8,48,"-",16,1);
	if(option==5)OLED_ShowNum(16*6,48,food_high,2,16,0);
	else OLED_ShowNum(16*6,48,food_high,2,16,1);
	OLED_ShowString(16*7,48,"kg",16,1);
	
	OLED_Refresh();
	
}
void OLED_Show_ThirdPage(){
	
	OLED_ShowChinese(16*1,0,7,16,0);
	OLED_ShowChinese(16*2,0,8,16,0);
	OLED_ShowChinese(16*3,0,11,16,0);
	OLED_ShowChinese(16*4,0,12,16,0);
	OLED_ShowChinese(16*5,0,24,16,0);
	OLED_ShowChinese(16*6,0,25,16,0);
	
	OLED_ShowChinese(16*0+8,16,17,16,1);
	OLED_ShowChinese(16*1+8,16,18,16,1);
	OLED_ShowChar(16*2+8,16,':',16,1);
	if(option==1)OLED_ShowNum(16*3,16,water_time,3,16,0);
	else OLED_ShowNum(16*3,16,water_time,3,16,1);
	OLED_ShowString(16*4+8,16,"min",16,1);

	OLED_ShowChinese(16*0+8,32,26,16,1);
	OLED_ShowChinese(16*1+8,32,28,16,1);
	OLED_ShowChinese(16*2+8,32,5,16,1);
	OLED_ShowChinese(16*3+8,32,6,16,1);
	OLED_ShowChar(16*4+8,32,':',16,1);
	if(option==2)OLED_ShowNum(16*5,32,water_high,2,16,0);
	else OLED_ShowNum(16*5,32,water_high,2,16,1);	
	OLED_ShowString(16*6,32,"%",16,1);
	
	OLED_ShowChinese(16*0+8,48,26,16,1);
	OLED_ShowChinese(16*1+8,48,27,16,1);
	OLED_ShowChinese(16*2+8,48,5,16,1);
	OLED_ShowChinese(16*3+8,48,6,16,1);
	OLED_ShowChar(16*4+8,48,':',16,1);
	if(option==3)OLED_ShowNum(16*5,48,water_low,2,16,0);
	else OLED_ShowNum(16*5,48,water_low,2,16,1);		
	OLED_ShowString(16*6,48,"%",16,1);
	
	OLED_Refresh();
	
}

七、项目资料包内容

资料获取:查看主页介绍"充哥单片机设计"

相关推荐
国科安芯19 小时前
火箭传感器控制单元的抗辐照MCU选型与环境适应性验证
单片机·嵌入式硬件·架构·risc-v·安全性测试
-Springer-20 小时前
STM32 学习 —— 个人学习笔记5(EXTI 外部中断 & 对射式红外传感器及旋转编码器计数)
笔记·stm32·学习
LS_learner20 小时前
树莓派(ARM64 架构)Ubuntu 24.04 (Noble) 系统 `apt update` 报错解决方案
嵌入式硬件
来自晴朗的明天21 小时前
16、电压跟随器(缓冲器)电路
单片机·嵌入式硬件·硬件工程
钰珠AIOT21 小时前
在同一块电路板上同时存在 0805 0603 不同的封装有什么利弊?
嵌入式硬件
代码游侠21 小时前
复习——Linux设备驱动开发笔记
linux·arm开发·驱动开发·笔记·嵌入式硬件·架构
代码游侠1 天前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
xuxg20051 天前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT1 天前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件