单片机毕业设计|基于stm32单片机的智能宠物投喂系统设计

作者主页:编程千纸鹤

作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,有较为丰富的相关经验。期待与各位高校教师、企业讲师以及同行交流合作

主要内容:Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能与大数据、单片机开发、物联网设计与开发设计、简历模板、学习资料、面试题库、技术互助、就业指导等

业务范围:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文降重、长期答辩答疑辅导、腾讯会议一对一专业讲解辅导答辩、模拟答辩演练、和理解代码逻辑思路等

收藏点赞不迷路  关注作者有好处

文末获取源码 

项目编号:BS-DPJ-021

一,环境介绍

语言环境:C语言嵌入式

技术实现:STM32

硬件构成:单片机+液晶显示+按键+蓝牙+重量检测+水位检测+水泵加水+步进电机喂食+语音播报

二,项目简介

随着社会生活水平提高,人们对精神生活的需求日益增长,宠物在日常生活中扮演着越来越重要的角色。然而,宠物饲养也带来了一系列繁琐的责任和挑战。为解决这些问题,本文提出了智能宠物投喂系统的设计框架,结合硬件和软件两个方面,实现了对宠物的智能化管理和远程控制。硬件包括单片机主控单元、传感器、执行部件等,而软件实现了时钟管理、传感器检测、手动控制和蓝牙通信等功能。该系统通过协同工作,为宠物主人提供了便利和可靠的喂食解决方案,充分满足了现代人对精神生活的需求,促进了人与宠物之间的和谐互动。

日常生活中宠物的饲养,闲暇时间可以带着宠物一起散散步,锻炼一下身体,给工作后的闲暇时间增添一些乐趣和放松,人们日常中对宠物的饲养诸如宠物狗的饲养,需要喂食,需要喂水,需要根据气温的变化对宠物进行冷热补偿,需要对宠物的居所通风换气,需要对宠物的居所进行光照强度的调节等,这些事情大多数都需要人为的操作,这样一方面会占据人们的时间和精力,另一方面由于人的惰性和其他事情的干扰导致有时候会遗忘,导致对宠物的照料不及时,这些都是宠物饲养中的遇到的问题,也是令许多宠物饲养者较为纠结的事情。随着科技的进步,智能化逐渐走进人们的日常生活,这也就为宠物的智能化饲养提供了方向。能够实现对宠物的智能化管理,这将会极大的节省人们的工作量,对于宠物饲养的智能化主要体现在如下几个方面,可以根据宠物的生活习性定时喂水,根据宠物居的光线强度动态的补光,能够定时的对宠物居进行的通风换气等,以上也是本次课题的意义和目的所在。

主程序流程图:

三,系统展示

显示功能测试图

手动投喂功能测试图

自动投喂设置功能测试图

定时自动投喂功能测试图

手机APP功能测试图

四,核心代码展示

#include "common.h"
#include "eeprom52.h"
#include "lcd1602.h"
#include "DS1302.h"
#include "hx711.h"
#include "uart.h"
#include "WT588D.h"

#define  UART_RX_BUF          RX1_Buffer 
#define  UART_RX_Count        RxCounter
#define  UART_BUF_SIZE        COM_RX1_Lenth

#define ON   1
#define OFF  0

sbit key1 = P1^0;//设置
sbit key2 = P1^1;//加
sbit key3 = P1^2;//减
sbit key4 = P1^3;//手动喂食
sbit key5 = P1^4;//手动关闭

sbit A1 = P2^0;
sbit B1 = P2^1;
sbit C1 = P2^2;
sbit D1 = P2^3;

sbit WATER = P3^4;
sbit MOTOR = P2^4;

typedef struct {
	unsigned char  shi;	  //时
	unsigned char	 fen;		//分
	unsigned char	 state; //状态
	unsigned char  temporary;
}user;

user  Remtime1={7 ,0,1,0};   //提醒时间1
user  Remtime2={10,0,1,0};   //提醒时间2
user  Remtime3={14,0,1,0};   //提醒时间3
user  Remtime4={17,0,1,0};   //提醒时间4
user  Remtime5={20,0,1,0};   //提醒时间5

#define Coil_4B_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
#define Coil_4B_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
#define Coil_4B_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
#define Coil_4B_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电

#define 	angle	 360

unsigned char  sec, min, hour, day, month, week, year;
unsigned char  setn = 0;     //记录设置按键按下的次数
unsigned char xdata display[16];
unsigned char play_mode = 1; //播放模式
bit shanshuo = 0; 
bit SendFlag = 0;
bit open_flag=0;
bit feeding_time = 0;
bit SendSwitchState = 0;
bit play_flag=0;
bit p_r = 0;	                  //平年/润年  =0表示平年,=1表示润年
unsigned long xdata weight;            //重量值
unsigned int xdata food_weight=500;            //重量值

unsigned char code STR_BUF1[]={0x1f,0x1b,0x13,0x1b,0x1b,0x1b,0x11,0x1f};  //1
unsigned char code STR_BUF2[]={0x1f,0x11,0x1d,0x1d,0x11,0x17,0x11,0x1f};  //2
unsigned char code STR_BUF3[]={0x1f,0x11,0x1d,0x1d,0x11,0x1d,0x11,0x1f};  //3

void time_init(void)	  //定时器初始化
{
	TMOD |= 0x01;	  //定时器0工作方式1
  TL0 = 0x00;		
	TH0 = 0xDC;  //定时器定时10ms
 	TR0 = 1;
	ET0 = 1;		  //开定时器0中断 
	EA  = 1;	 	  //开总中断
}

void display_mode(void)
{
	  if(play_mode==1){Lcd_Custom_Char(1,15,0,STR_BUF1);}
	  if(play_mode==2){Lcd_Custom_Char(1,15,1,STR_BUF2);}
	  if(play_mode==3){Lcd_Custom_Char(1,15,2,STR_BUF3);}
}

void display_state(void)
{
	  if(open_flag)lcd_write_str(9,1,"OPEN ");
	  else         lcd_write_str(9,1,"CLOSE");
}

void displayInitChar(void)   //显示初始界面
{
		lcd_write_str(0,0,"  /  /         g");//显示字符串
		lcd_write_str(0,1,"  :  :          ");
	  display_mode();
}

void write_eeprom(void)//数据保存
{
	  char i=0;
	
    SectorErase(0x4200);//扇区擦除
	
	  byte_write(0x4200, 0xAA);
		
		byte_write(0x4201, Remtime1.shi);  
		byte_write(0x4202, Remtime1.fen);   
		byte_write(0x4203, Remtime1.state); 

    byte_write(0x4204, Remtime2.shi);  
		byte_write(0x4205, Remtime2.fen);   
		byte_write(0x4206, Remtime2.state); 

    byte_write(0x4207, Remtime3.shi);  
		byte_write(0x4208, Remtime3.fen);   
		byte_write(0x4209, Remtime3.state); 
 
    byte_write(0x420A, Remtime4.shi);  
		byte_write(0x420B, Remtime4.fen);   
		byte_write(0x420C, Remtime4.state); 	
		
    byte_write(0x420D, Remtime5.shi);  
		byte_write(0x420E, Remtime5.fen);   
		byte_write(0x420F, Remtime5.state); 

    byte_write(0x4210, (food_weight>>8)&0xFF);
    byte_write(0x4211, (food_weight>>0)&0xFF);

    byte_write(0x4212, play_mode);
}

void init_eeprom(void)//eeprom初始化
{
	  char i=0;
	
		if(byte_read(0x4200)!=0xAA)//校验是不是新的单片机
		{
				write_eeprom();
			  delay_ms(100);
		}
		
		Remtime1.shi = byte_read(0x4201);
		Remtime1.fen = byte_read(0x4202);
		Remtime1.state = byte_read(0x4203);
		
		Remtime2.shi = byte_read(0x4204);
		Remtime2.fen = byte_read(0x4205);
		Remtime2.state = byte_read(0x4206);
		
		Remtime3.shi = byte_read(0x4207);
		Remtime3.fen = byte_read(0x4208);
		Remtime3.state = byte_read(0x4209);
		
		Remtime4.shi = byte_read(0x420A);
		Remtime4.fen = byte_read(0x420B);
		Remtime4.state = byte_read(0x420C);
		
		Remtime5.shi = byte_read(0x420D);
		Remtime5.fen = byte_read(0x420E);
		Remtime5.state = byte_read(0x420F);
		
		food_weight = byte_read(0x4210)<<8|byte_read(0x4211);
		play_mode = byte_read(0x4212);
}

void write_week(uchar week)//写星期函数
{
    lcd_write_com(0x80+9);//星期字符的显示位置
    switch(week)
    {
    case 1:
        lcd_write_data('M');//星期数为1时,显示
        lcd_write_data('O');
        break;

    case 2:
        lcd_write_data('T');//星期数据为2时显示
        lcd_write_data('U');
        break;

    case 3:
        lcd_write_data('W');//星期数据为3时显示
        lcd_write_data('E');
        break;

    case 4:
        lcd_write_data('T');//星期数据为4是显示
        lcd_write_data('H');
        break;

    case 5:
        lcd_write_data('F');//星期数据为5时显示
        lcd_write_data('R');
        break;

    case 6:
        lcd_write_data('S');//星期数据为6时显示
        lcd_write_data('A');
        break;

    case 0:
        lcd_write_data('S');//星期数据为7时显示
        lcd_write_data('U');
        break;
    }
}

void displayTime(void) //显示时间
{
	 //显示时间
	 lcd_write_com(0x80);
	 lcd_write_data(year/10+0x30);
	 lcd_write_data(year%10+0x30);
	 lcd_write_data('/');
	 lcd_write_data(month/10+0x30);
	 lcd_write_data(month%10+0x30);
	 lcd_write_data('/');
	 lcd_write_data(day/10+0x30);
	 lcd_write_data(day%10+0x30);

	 week=Conver_week(year,month,day);
	 write_week(week);

	 lcd_write_com(0x80+0x40);
	 lcd_write_data(hour/10+0x30);
	 lcd_write_data(hour%10+0x30);
	 lcd_write_data(':');
	 lcd_write_data(min/10+0x30);
	 lcd_write_data(min%10+0x30);
	 lcd_write_data(':');
	 lcd_write_data(sec/10+0x30);
	 lcd_write_data(sec%10+0x30);
}

void Run_DS1302(void)//DS1302运行
{
	  //获取时间:年月日时分秒
		v_W1302(0x8f, 0);
		sec = bcdtodec(uc_R1302(0x81));	  
		v_W1302(0x8f, 0);
		min = bcdtodec(uc_R1302(0x83));	  
		v_W1302(0x8f, 0);
		hour = bcdtodec(uc_R1302(0x85)); 
		v_W1302(0x8f, 0);
		day = bcdtodec(uc_R1302(0x87));	 
		v_W1302(0x8f, 0);
		month = bcdtodec(uc_R1302(0x89)); 
//		v_W1302(0x8f, 0);
//		week = bcdtodec(uc_R1302(0x8b)); 
		v_W1302(0x8f, 0);
		year = bcdtodec(uc_R1302(0x8d)); 
}

void Get_Ds1302_Time(void)//获取DS1302时间
{
		Run_DS1302();//读时间
	  if(setn == 0){
			displayTime();
		}
}

void displaySetTime(const user * const time)   //显示提醒时间
{
	  if(time->state == 1)lcd_write_str(6,1," ON");else lcd_write_str(6,1,"OFF");
	
		lcd_write_char(11,1,time->shi/10+'0');
		lcd_write_char(12,1,time->shi%10+'0');
	
	  lcd_write_char(14,1,time->fen/10+'0');
		lcd_write_char(15,1,time->fen%10+'0');
}

void SetReminderTime(bit mode,uchar index ,user * const time)  //设置提醒时间
{
	 if(mode == 0)
	 {
			switch(index)
			{
				 case(1):
									time->state = ON; lcd_write_str(6,1," ON");
									lcd_write_com(0x80+0x40+8);
									lcd_write_com(0x0f);//开启光标     
									break;
				 case(2):  
									time->shi ++;
				          if(time->shi == 24)time->shi = 0;
				          lcd_write_char(11,1,time->shi/10+'0');
									lcd_write_char(12,1,time->shi%10+'0');
									lcd_write_com(0x80+0x40+12);
									lcd_write_com(0x0f);//开启光标     
									break;
				 case(3): 
									time->fen ++;
				          if(time->fen == 60)time->fen = 0;
				          lcd_write_char(14,1,time->fen/10+'0');
									lcd_write_char(15,1,time->fen%10+'0');
									lcd_write_com(0x80+0x40+15);
									lcd_write_com(0x0f);//开启光标     
									break;
				
				default:break;
			}
	 }
	 else
	 {
			switch(index)
			{
				 case(1): 
									time->state = OFF; lcd_write_str(6,1,"OFF");
									lcd_write_com(0x80+0x40+8);
									lcd_write_com(0x0f);//开启光标     
									break;
				 case(2):
				          if(time->shi == 0)time->shi = 24;
				          time->shi --;
				          lcd_write_char(11,1,time->shi/10+'0');
									lcd_write_char(12,1,time->shi%10+'0');
									lcd_write_com(0x80+0x40+12);
									lcd_write_com(0x0f);//开启光标     
									break;
				 case(3): 
				          if(time->fen == 0)time->fen = 60;
				          time->fen --;
				          lcd_write_char(14,1,time->fen/10+'0');
									lcd_write_char(15,1,time->fen%10+'0');
									lcd_write_com(0x80+0x40+15);
									lcd_write_com(0x0f);//开启光标     
									break;
				
				default:break;
			}
	 }
}

五,相关作品展示

基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目

基于Nodejs、Vue等前端技术开发的前端实战项目

基于微信小程序和安卓APP应用开发的相关作品

基于51单片机等嵌入式物联网开发应用

基于各类算法实现的AI智能应用

基于大数据实现的各类数据管理和推荐系统

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程千纸鹤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值