51单片机项目设计:智能宠物小屋(自动喂食喂水、自动通风换气、自动清洁)制作教程

智能宠物小屋

资料链接:https://download.csdn.net/download/mbs520/20365056


QQ交流群1:981140834
QQ交流群2:473982062
QQ交流群3:718245727
QQ交流群4:598455837

一、项目设计要求

以单片机为控制核心设计一个智能宠物小屋控制系统,设计基本要求如下:
1)具有自动喂食喂水、自动通风换气、自动清洁等功能;
2) 完成智能宠物小屋控制系统硬件电路设计;
3) 完成智能宠物小屋控制系统软件设计。

二、硬件框架搭建

(一)硬件框架
在这里插入图片描述
(二)设计功能

(1)实时时间、温度显示以及调控温度;
控制时钟芯片将当前时间显示在液晶屏上,设加、减、功能切换、参数切换四个按键,用于调节时间、调节功能闹钟及手动开启或关闭某功能设置;温度采集电路完成温度值的检测及数值的转换和线性化处理,处理后发送给单片机,由单片机控制温度值显示;
将采集的温度与标准温度值进行比对,若比设定值大的话就开启风扇至设定温度停止;
(2)定时喂食喂水。能够定时地为宠物提供食物和水;
通过时钟电路设定喂食时间,带扇叶的步进电机正转打开喂食口,让食物从料仓落到食盘,然后电机反转关闭喂食口;
通过时钟电路设定喂水时间,由单片机控制在水仓的水泵抽水通过塑料软管流入宠物水盆,水盆内有水位传感器测水位,达到标准水位停止抽水。
(3)定时清洁宠物生活区域。根据电机正反转循环清扫笼子底部;
设定清洁时间,控制带有清洁电刷的步进电机正反转清洁,利用红外检测宠物是否在屋内,若在屋内在下个清洁时间清洁,反之即时开启清洁;

三、硬件材料选型

(一)单片机选型
使用STC89C52单片机,其内部有2 bytes 片内RAM数据存储器。由于要随时要对程序进行修改和新增一些程序的功能,与AT89S52相比,STC89C52无需编程器和安装驱动就可以下载,而且片内带2 K bytes EEPROM 存储空间,因此选择STC89C52单片机作为主控系统。
在这里插入图片描述
(二)显示模块
采用LCD液晶屏显示,不但耗能少,而且可显示汉字与英文。在显示内容方面也变得更加灵活,修改程序编写就可完成,无需对硬件进行修改,也更便于扩展其他电路。此外,该模块硬件连接也比较简单易操作。与方案一较之,方案二耗能更少、显示更灵活、电路的扩展更方便,而且软硬件设计简单,因此选用LCD液晶屏为显示模块。
在这里插入图片描述
(三)水位传感器
Water Sensor水位传感器体积小巧、简单易用,可靠性高,易清洁,安装方便,价格低廉。输出信号为模拟信号,连接电路后可基本测出水位情况,满足水位检测要求。相比浮球式水位传感器,Water Sensor水位传感器简单易用。
在这里插入图片描述

(四)红外传感器
本文选用的红外感应模块为红外对管模块,主要是通过两个红外元件进行发射与接受进行感应。当发射载波频率与接收头固定频率处于一致的情况下,就可以接收红外感应。发射管先发送红外信号,红外信号会随着传送距离的加大慢慢减弱,当信号接触到检测体时,就形成红外反射。当反射的信号弱时,光敏二极管 L2 接收的红外光较弱,比较器LM393 的3脚电压大于2脚电压,接收检测引脚处于高电平状态,此时宠物较远;当反射信号较强,接收检测引脚处于低电平状态,此时宠物较近。
在这里插入图片描述

(五)时钟芯片模块
使用DS1302芯片实现时钟控制,DS1302 芯片是一款专门用于时钟控制的芯片,工作电压在2.0V-5.5V之间,可为实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,也可选择使用 24 或12 小时计时法,还可对每月的天数和闰年进行调整[7]。另外,它可以同步串行的方式完成与单片机之间的通信,因此,选用DS1302芯片作为时钟芯片。
在这里插入图片描述
(六)温度采集模块
采用数字式传感器DS18B20,具有测量范围广,测量精度高的特点。DS18B20只需要一条数据线就可以直接把数字温度值输出,无需外接AD电路,有利于电路简单化。因此,本系统选用DS18B20为温度传感器。在这里插入图片描述
(七)电机驱动模块
使用H桥电路的L298N驱动器作为电机驱动模块。H桥电路可控制电机转速和方向,而且稳定性高。一片L298N驱动芯片可同时控制两个直流电机,过程并不复杂,通过主控芯片的I/O输入对输入端的逻辑电平状态进行改变,就可完成电机的正转反转控制,同时还具有过热自断和反馈检测的特性。另外,当电机出现卡死的情况时,芯片会启动过电流功能保护设备,所以选用L298N作为电机驱动模块。
在这里插入图片描述

(八)风扇,清理电机,水泵
直接选最便宜的直流电机
在这里插入图片描述
(九)其它
电阻、电容、晶振、二极管、三极管、蜂鸣器等…

四、元件清单

Description Comment Designator Quantity
电容 30pF C1、C2 2
电容 10μF C3 1
晶振 12M X1 1
电机驱动 L298N LN1,LN2 2
温度传感器 DS18B20 IC1 1
红外传感器 HW IC2 1
单片机 STC89C52 IC3 1
时钟芯片 DS1302 IC4 1
电阻 10K R1~R5 5
电阻 4.7K R6 1
排阻 1K Rp1 1
电位器 10K WR1,WR2 1
蜂鸣器 有源 BEEP 1
液晶显示器 LCD1602 J4 1
按键 轻触 Key1,Key2,Key3, Key4, Key5 5
发光二极管 红色 LED1 1
风扇、水泵、电机 3-6V直流 M1,M2,M3,M4 4
三极管 2N3906 Q1,Q2,Q3,Q4 4
开关 拨动 SW1 1
纽扣电池 3v BAT1 1
晶振 32.768KHz X2 1
二极管 IN 4148 D1,D2,D3 3
水位传感器 模拟 T1 1
排针 4脚、多脚 Header 1
洞洞板 玻纤 9*15cm 1

五、原理图设计

看不清,需要下载资料,用DXP或者AD软件打开
在这里插入图片描述

六、电路主板焊接

(一)先画布局图再进行焊接
在这里插入图片描述
(二)焊接好,并按照原理图连接好外围电路
在这里插入图片描述

七、程序框架设计

(一)主程序框架
在这里插入图片描述
其他具体框架参考论文

八、程序设计

篇幅有限、只贴出部分程序

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#include "ds1302.h"
#include "temp.h"
#include "lcd.h"
#include "eeprom.h"
#include <string.h>

sbit K1 = P1^0;	  			//按键
sbit K2 = P1^1;			 
sbit K3 = P1^2;
sbit K4 = P1^3;

sbit LCD_LED = P2^4;	 	//lcd背光
sbit BEEP = P1^4;			//蜂鸣器
sbit IR = P1^5;				//红外
sbit WIT_0 = P1^6;			//水位检测
sbit WIT_1 = P1^7;



sbit WATER_EN = P2^0;		//水泵	 	
sbit FAN_EN = P2^1;			//风扇

sbit CLR_EN_A = P2^2;	  		//清理电机
sbit CLR_EN_B = P2^3;	  		//清理电机

sbit FEED_EN_A = P3^2;		//喂食
sbit FEED_EN_B = P3^3;		//喂食


typedef  unsigned int u16;
typedef  unsigned char u8;


//风扇启动时间
//8小时一次
u8 fan_time8[3] = {
    
    0x01,0x09,0x17};
//5小时一次
u8 fan_time5[5] = {
    
    0x00,0x05,0x10,0x15,0x20};
//3小时一次
u8 fan_time3[8] = {
    
    0x02,0x05,0x08,0x11,0x14,0x17,0x20,0x23};



//时间结构体
typedef struct
{
    
    
	u8 hour;
	u8 min;
	u8 sec;
}type_time;


//系统信息结构体
typedef struct
{
    
    
	type_time 	feed_time[5];//定时5个喂食时间
	u8 				feed_time_sw[5]; 		//5个喂食闹钟开关 0关 1开
	type_time 	clr_time[5];//定时5个清理时间
	u8 				clr_time_sw[5]; 		//5个清理闹钟开关 0关 1开
}type_Sysinfo;



const u8 MENU_MAX = 6;//5个界面
u8 menu_val=1;//当前显示的界面页数


float curr_temp;//当前温度
volatile u8 state=0;   //系统工作状态
			//bit0 :进水状态
			//bit1 :风扇状态
			//bit2 :清理状态 正传
			//bit3 :清理状态 反转
			//bit4: 喂食状态 正传
			//bit5: 喂食状态 反转
			
type_time curr_time;//当前时间
u8 fan_time = 5; //风扇每隔多长时间吹一次 hour
u8 fan_len_time = 5;//风扇转一次多少分钟 min


unsigned int ti=0;       //修改第几个时间参数 、修改第几个闹钟参数



//日期
typedef struct
{
    
    
	u8 year;
	u8 month;
	u8 day;
	u8 hour;
	u8 min;
	u8 sec;
}type_date;



type_Sysinfo sysinfo;



void delay(unsigned int t );
void delay_ms(unsigned int t );

void dis_sys_start(void );
void dis_menu1_date(u8  sel);
void dis_menu2_mdf_date(void);
void dis_menu3_mdf_fdtime(void );
void dis_menu4_mdf_clrtime(void );
void dis_menu5_state(void );
void ctrl_motor(void);
void dis_menu6_motor_ctrl(void );

void key_scan(void );
u8 get_key_val(void);

void save_sysinfo(void );
void read_sysinfo(void );


/*******************************************************************************
* 函 数 名         : Timer0Init
* 函数功能		   : 定时器0初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0Init()
{
    
    
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

	TH0=0XFC;	//给定时器赋初值,定时1ms
	TL0=0X18;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//开启定时器			
}


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main(void)
{
    
    
	u16 ucount=0;

	//只执行一次
	if(byte_read(0x2200) != 0x56)//如果是第一次执行
	{
    
    
		memset(&sysinfo,0,sizeof(sysinfo));
		save_sysinfo();//清除数据
		
		
		SectorErase(0x2200);
		byte_write(0x2200,0x56);
	}
	
	
	
	//关闭所有电机
	WATER_EN = 1;		//水泵	 	
	FAN_EN = 1;			//风扇
	CLR_EN_A = 1;	  		//清理电机
	CLR_EN_B = 1;	  		//清理电机
	FEED_EN_A = 1;		//喂食
	FEED_EN_B = 1;		//喂食

	LcdInit();	 		//lcd初始化
	//Ds1302Init();		  //时钟初始化
	Ds18b20Init();		  //温度传感器初始化
	Timer0Init();      //定时器初始化
	
	read_sysinfo();//读取系统信息
	LcdClean();     //LCD清屏
	dis_sys_start();//显示初始界面
	LcdClean();     //LCD清屏
	while(1)		
	{
    
    
		switch(menu_val)	//界面选择
		{
    
    
			case 1:		//时间显示界面
				if(ucount %80 == 0)dis_menu1_date(1);
				ctrl_motor();//电机控制
				break;
			case 2:			  //时间修改模式
				dis_menu2_mdf_date();
				break;
			case 3:			   //设置喂食闹钟界面
				dis_menu3_mdf_fdtime();
				break;
			case 4:			   //设置清理闹钟界面
				dis_menu4_mdf_clrtime();
				break;
			case 5:
				if(ucount %100 == 0)dis_menu5_state(); //显示系统状态
				break;
			case 6:
				if(ucount %100 == 0)dis_menu6_motor_ctrl();//电机控制
				break;
		}
		
		key_scan();//按键烧苗
		ucount++;
		delay_ms(10);
		
	}				
}


/*******************************************************************************
* 函 数 名         : void Timer0() interrupt 1
* 函数功能		   : 定时器0中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void Timer0() interrupt 1
{
    
    
	static u16 i,speed;
	TH0=0XFC;	//给定时器赋初值,定时1ms
	TL0=0X18;
	i++;
	if(state & 0x01)speed=5;
	else speed = 10;
	
	if(state != 0)//有电机需要转动
	{
    
    
		if(i%speed == 0)//开启
		{
    
    
			if(state & 0x01)//水泵
			{
    
    
					WATER_EN = 0;		//水泵	 	
			}
			else if(state & 0x02)
			{
    
    
					FAN_EN = 0;		//风扇 	
			}
			else if(state & 0x04)
			{
    
    
				CLR_EN_A = 0;	  		//清理电机 正传
				CLR_EN_B = 1;	  		//清理电机
			}
			else if(state & 0x08)
			{
    
    
				CLR_EN_A = 1;	  		//清理电机 反传
				CLR_EN_B = 0;	  		//清理电机
			}
			else if(state & 0x10)
			{
    
    
				FEED_EN_A = 1;	  		//喂食电机 正传
				FEED_EN_B = 0;	  		//喂食电机
			}
			else if(state & 0x20)
			{
    
    
				FEED_EN_A = 0;	  		//喂食电机 反传
				FEED_EN_B = 1;	  		//喂食电机
			}
		}
		else  //关闭
		{
    
    
			WATER_EN = 1;		//水泵	6
			FAN_EN = 1;			//风扇		10
			CLR_EN_A = 1;	  		//清理电机 10
			CLR_EN_B = 1;	  		//清理电机  10
			FEED_EN_B = 1;
			FEED_EN_A = 1;
		}
	}
}



/*********延时函数***********/		  
void delay_ms(unsigned int t)	//毫秒延时
{
    
    
	unsigned int a,b;
	for(a=0;a<t;a++)
	for(b=0;b<120;b++);
}




void dis_sys_start(void)
{
    
    
	LcdWriteCom(0x80);
	LcdWritestr("Welcome!");
	LcdWriteCom(0xc0);
	LcdWritestr("Pet Feed System");
	delay_ms(2000);
}
/*******************************************************************************
* 函 数 名         : dis_menu1_date
* 函数功能		   : 显示时间日期温度
*******************************************************************************/
	
void dis_menu1_date(u8 sel)
{
    
    
	float tp;
	int temp;
	
	if(menu_val == 1)
	{
    
    
		Ds1302ReadTime();//读取时间
	}
	
	//显示日期
	LcdWriteCom(0x80);
	LcdWritestr("20");	
	LcdWriteData(TIME[6]/16+0x30);	  //年
	LcdWriteData(TIME[6]%16+0x30);
	LcdWriteData('-');
	LcdWriteData(TIME[4]/16+0x30);	  //月
	LcdWriteData(TIME[4]%16+0x30);
	LcdWriteData('-');
	LcdWriteData(TIME[3]/16+0x30);	  //日
	LcdWriteData(TIME[3]%16+0x30);

	LcdWritestr("  ");
	switch(TIME[5])					   //显示星期
	{
    
    		
		case 0:LcdWritestr("Mon"); break;
		case 1:LcdWritestr("Tue"); break;
		case 2:LcdWritestr("Wed"); break;
		case 3:LcdWritestr("Thu"); break;
		case 4:LcdWritestr("Fri"); break;
		case 5:LcdWritestr("Sat"); break;
		case 6:LcdWritestr("Sun"); break;
	}
	
	LcdWriteCom(0xC0);
	LcdWriteData(' ');
	LcdWriteData(TIME[2]/16+0x30);	  //时
	LcdWriteData(TIME[2]%16+0x30);
	LcdWriteData(':');
	LcdWriteData(TIME[1]/16+0x30);	  //分
	LcdWriteData(TIME[1]%16+0x30);
	LcdWriteData(':');
	LcdWriteData(TIME[0]/16+0x30);	  //秒
	LcdWriteData(TIME[0]%16+0x30);
	LcdWritestr(" ");
	
	curr_time.hour = TIME[2];
	curr_time.min = TIME[1];
	curr_time.sec = TIME[0];
	
	
	if(sel)
	{
    
    
		EA = 0;//关中断
		temp = Ds18b20ReadTemp();//获取温度
		EA = 1;//开中断
		//显示温度
		if(temp< 0)			
		{
    
    
			LcdWriteCom(0xca);
			LcdWriteData('-'); 
			temp=temp-1;
			temp=~temp;
			tp=temp;
			temp=tp*0.0625*100+0.5;	
	 
		}
		else
		{
    
    			
			LcdWriteCom(0xca);
			LcdWriteData('+'); 
			tp=temp;
			temp=tp*0.0625*100+0.5;	
		}
		LcdWriteData(temp % 10000 / 1000 + 0x30);
		LcdWriteData(temp % 1000 / 100  + 0x30);
		LcdWriteData('.');
		LcdWriteData(temp % 100 / 10 + 0x30);
		LcdWriteData(temp % 10 + 0x30);
		
		curr_temp = (float) temp/100.0;
	}
	
	
	
}





/*************修改时间************/
void dis_menu2_mdf_date(void)
{
    
    
	static u16 ucount=0;
	ucount++;
	
	if(ucount ==30)
	{
    
    
		dis_menu1_date(0);//显示静止时间
		if(ti == 7)  //闪烁OK
		{
    
    
			LcdWriteCom(0xca);
			LcdWritestr(" ->OK ");
		}
			
	}
	else if(ucount == 60)//闪烁
			{
    
    
				ucount = 0;
				switch(ti)
				{
    
    
					case 0:LcdWriteCom(0xc7);
									LcdWritestr("  ");break;
					case 1:LcdWriteCom(0xc4);
									LcdWritestr("  ");break;
					case 2:LcdWriteCom(0xc1);
									LcdWritestr("  ");break;
					case 3:LcdWriteCom(0x88);
									LcdWritestr("  ");break;
					case 4:LcdWriteCom(0x85);
									LcdWritestr("  ");break;
					case 5:	LcdWriteCom(0x8c);
									LcdWritestr("   ");break;
					case 6:LcdWriteCom(0x80);
									LcdWritestr("    ");break;
					case 7:LcdWriteCom(0xca);
									LcdWritestr("      ");break;
				}
			}
}






/*******************************************************************************
* 函 数 名         : dis_menu3_mdf_fdtime
* 函数功能		   : 修改喂食时间界面
*******************************************************************************/
u8 feed_cnt=0;  //当前修改的第几个时间
void dis_menu3_mdf_fdtime(void )
{
    
    
	
	static u16 ucount = 0;
	
	ucount++;
	if(ucount == 30)
	{
    
    
		LcdWriteCom(0x80);			 //显示
		LcdWritestr("feed time ");
		LcdWriteCom(0x8a);
		LcdWriteData(feed_cnt+0x30);
		LcdWritestr("    ");
		LcdWriteCom(0xca); 
		if(sysinfo.feed_time_sw[feed_cnt] == 0)LcdWritestr("  OFF ");
		else LcdWritestr("  ON  ");
		
		LcdWriteCom(0xc1); 
		LcdWriteData(sysinfo.feed_time[feed_cnt].hour/16+0x30);
		LcdWriteData(sysinfo.feed_time[feed_cnt].hour%16+0x30);
		LcdWriteData(':'); 
		LcdWriteData(sysinfo.feed_time[feed_cnt].min/16+0x30);
		LcdWriteData(sysinfo.feed_time[feed_cnt].min%16+0x30);
		LcdWriteData(':'); 
		LcdWriteData(sysinfo.feed_time[feed_cnt].sec/16+0x30);
		LcdWriteData(sysinfo.feed_time[feed_cnt].sec%16+0x30);
	}
	
	else if(ucount == 60 )
	{
    
    
		ucount =0;
		
		switch(ti)
		{
    
    
			case 0:LcdWriteCom(0x8a);
							LcdWritestr(" ");break;
			case 1:LcdWriteCom(0xc7);
							LcdWritestr("  ");break;
			case 2:LcdWriteCom(0xc4);
							LcdWritestr("  ");break;
			case 3:LcdWriteCom(0xc1);
							LcdWritestr("  ");break;
			case 4:LcdWriteCom(0xcc);
							LcdWritestr("   ");break;
		}
			
	}
	
}

/*******************************************************************************
* 函 数 名         : dis_menu3_mdf_fdtime
* 函数功能		   : 修改清理时间界面
*******************************************************************************/
void dis_menu4_mdf_clrtime(void )
{
    
    
	static u16 ucount = 0;
	
	ucount++;
	if(ucount == 30)
	{
    
    
		LcdWriteCom(0x80);			 //显示
		LcdWritestr("clear time ");
		LcdWriteCom(0x8b);
		LcdWriteData(feed_cnt+0x30);
		LcdWritestr("   ");
		LcdWriteCom(0xca); 
		if(sysinfo.clr_time_sw[feed_cnt] == 0)LcdWritestr("  OFF ");
		else LcdWritestr("  ON  ");
		
		LcdWriteCom(0xc1); 
		LcdWriteData(sysinfo.clr_time[feed_cnt].hour/16+0x30);
		LcdWriteData(sysinfo.clr_time[feed_cnt].hour%16+0x30);
		LcdWriteData(':'); 
		LcdWriteData(sysinfo.clr_time[feed_cnt].min/16+0x30);
		LcdWriteData(sysinfo.clr_time[feed_cnt].min%16+0x30);
		LcdWriteData(':'); 
		LcdWriteData(sysinfo.clr_time[feed_cnt].sec/16+0x30);
		LcdWriteData(sysinfo.clr_time[feed_cnt].sec%16+0x30);
	}
	
	else if(ucount == 60 )
	{
    
    
		ucount =0;
		
		switch(ti)
		{
    
    
			case 0:LcdWriteCom(0x8b);
							LcdWritestr(" ");break;
			case 1:LcdWriteCom(0xc7);
							LcdWritestr("  ");break;
			case 2:LcdWriteCom(0xc4);
							LcdWritestr("  ");break;
			case 3:LcdWriteCom(0xc1);
							LcdWritestr("  ");break;
			case 4:LcdWriteCom(0xcc);
							LcdWritestr("   ");break;
		}
			
	}
}


/*******************************************************************************
* 函 数 名         : dis_menu4_state
* 函数功能		   : 显示系统状态
*******************************************************************************/
void dis_menu5_state(void )
{
    
    
	LcdWriteCom(0x80);			 //显示
	LcdWritestr("Pet:    ");
	if(IR == 0)
		LcdWritestr("whthin  ");
	else
		LcdWritestr("absent  ");
	
	LcdWriteCom(0xc0); 
	LcdWritestr("water line:  ");
	if(WIT_0==1 && WIT_1==1)
		LcdWritestr("0cm");
	else if(WIT_0==0 && WIT_1==1)
		LcdWritestr("1cm");
	else if(WIT_0==0 && WIT_1==0)
		LcdWritestr("3cm");
	
}



/*******************************************************************************
* 函 数 名         : dis_menu6_motor_ctrl
* 函数功能		   : 电机控制
*******************************************************************************/
void dis_menu6_motor_ctrl(void )
{
    
    
	
	LcdWriteCom(0x80);
	LcdWritestr("motor:"); 
	switch(state)
	{
    
    
		case 0x01:
			LcdWritestr("water     "); 
			break;
		case 0x02:
			LcdWritestr("fan       "); 
			break;
		case 0x04:
			LcdWritestr("clear    +"); 
			break;
		case 0x08:
			LcdWritestr("clear    -"); 
			break;
		case 0x10:
			LcdWritestr("feed     +"); 
			break;
		case 0x20:
			LcdWritestr("feed     -"); 
			break;
		default:
			LcdWritestr("none      "); 
	}
}
/*******************************************************************************
* 函 数 名         : ctrl_motor
* 函数功能		   : 外设电机控制
*******************************************************************************/

void ctrl_motor(void)
{
    
    
	u8 i;
	static u8 clr_z_flag=0,clr_f_flag=0,code_flag=0,water_flag=0;
	static u8 feed_z_flag=0,feed_f_flag=0,feed_t_flag=0;
	static u8 ucount=0;
	//static u8 fan_flag=0;
	static u16 clr_cnt=0,water_cnt=0;//fan_cnt=0,
	static u16 feed_cnt=0,code_cnt=0;
	ucount++;

九、下载验证

根据实现的功能对宠物智能小屋主要功能进行验证。
宠物智能小屋系统上电后,系统显示初始化界面,
在这里插入图片描述
初始化后液晶第一行显示当前的日期与星期,第二行显示实时时间与温度。
在这里插入图片描述
可通过按键设定喂食、清洁闹钟时间
在这里插入图片描述在这里插入图片描述

红外检测与水位检测验证。宠物检测到在小屋内显示“within”,未在小屋内显示“absent”。水位检测则在第二行显示water line: 具体水位厘米数。本系统也可以通过手动按键开启、关闭喂水功能。下图5.6为宠物未在小屋内,水位检测到为0cm,下图5.7为宠物在小屋内,水位检测到为3cm。
在这里插入图片描述
在这里插入图片描述

喂食定时时间到后,电机正转打开喂食口,喂食完成后,电机反转关闭喂食口。本系统也可以通过手动按键对电机进行正转、反转功能。

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/mbs520/article/details/118892343