温控自动烘焙系统的研究与实现

温控自动烘焙系统的研究与实现

茶叶自动烘焙系统的研究与实现,研究了茶叶自动烘焙系统的基本原理和系统框图,通过温度检测模块,能实时检测三个不同温度数据,并将数据通过蓝牙模块传输到电脑。利用温度控制电路,采用PID算法、51单片机进行控制及数据处理,能精确实时控制温度。系统主要51单片机最小系统、蓝牙模块、温度传感模块、驱动显示电路、输出控制电路、电源电路、储存电路、报警电路和按键电路输出等组成。利用所设计出的茶叶自动烘焙系统,对烘焙中的茶叶采集温度,当时温度过高时能自动控制停止加温。此系统具有易控制、工作可靠、测量精度高的优点,可实时检测、控制。
关键词:温度检测,温度控制,PID算法,数据传输

Research and implementation of automatic tea baking system

Automatic tea baking system research and implementation introduces the automatic tea baking system basic principle and system block diagram.The system can real-time monitoring three different temperature data and transmits the data to a computer thought by Bluetooth module.The system is use the temperature control circuit and PID algorithm and 51 single-chip microcomputer control and data processing to accurately control the temperature. The system is mainly composed of 51 single chip microcomputer system, Bluetooth module, temperature sensor module, driver display circuit, output control circuit, power circuit, storage circuit, alarm circuit and key circuit output. The tea automatic baking system is used to collect the temperature of the tea in the baking process. This system has the advantages of easy control, reliable operation, high measurement accuracy, real-time detection and control.
Key Words: Temperature measurement, temperature control, PID algorithm, data transmission

代码+论文下载地址下载地址
目录
温控自动烘焙系统的研究与实现_第1张图片
第1章 绪论 1
1.1 研究背景 1
1.2 研究意义 1
1.3 研究内容 2
第2章 系统硬件电路设计 3
2.1 电路总体方案 3
2.2 单片机最小系统 3
2.2.1 STC89C51芯片 3
2.2.2 复位电路 3
2.2.3 晶振电路 4
2.3 驱动显示电路及报警电路 4
2.3.1 LCD液晶屏显示电路 4
2.3.2 蜂鸣器和LED指示 6
2.4 DS18B20温度传感器 7
2.5 AT24C01存储芯片 8
2.6 G5LA-14 继电器 8
2.7 HC-05蓝牙模块 9
第3章 系统程序设计 11
3.1 主程序 11
3.2 状态显示子程序 13
3.3 温度设定子程序 14
3.4 温度比较子程序 15
3.5 PID控制器 16
3.6 串口数据传输部分程序 1
第4章 系统测试 1
4.1 模块测试 1
4.2 系统功能 1
结论 2
参考文献 3
致谢 4
附录1 部分关键源码及解释 5
附录2 系统原理图 23
附录3 英文文献翻译 28

电路总体方案
电路总体框图。在设计时我发现蓝牙模块适合传输小数据,相对Wifi来说,使用蓝牙不需要使用网络,因此采用蓝牙模块设计。与电脑和手机的连接都很方便。

温控自动烘焙系统的研究与实现_第2张图片
主程序
主程序的主要功能是负责读出温度值、处理温度值、在LCD液晶屏上显示温度值和并控制子程序输出。按键设定温度,当温度传感器故障时,蜂鸣器发声报警,如果没有故障则正常显示,控制继电器开关。如图3.1主程序流程图。

温控自动烘焙系统的研究与实现_第3张图片
温控自动烘焙系统的研究与实现_第4张图片
温度设定子程序
温度设定子程序用于处理按键,用于设定想要设置的温度值

温控自动烘焙系统的研究与实现_第5张图片
系统测试
4.1 模块测试

温度采集模块的测试:当实际温度值变化时,LCD同步显示实际温度,采集模块正常工作。
LCD显示测试:首先观察LCD有无外部损坏,接着上电,LCD液晶屏会显示温度1、温度2、温度3的温度,按下按键,观察显示屏上显示出的设置set1是否变换set2、set3。经测试可LCD显示屏正常工作。
按键测试:按键长按时,数据变动一次,按键短按时数据根据按按键的次数改变,经检测按键正常工作。
蜂鸣器发声测试:将温度传感模块拔掉模拟温度传感器故障,蜂鸣器发出报警的声音,蜂鸣器正常工作。
温度控制模块的测试:设置好设定温度,当茶叶实际温度低于设定温度,继电器打开,模拟开始加热茶叶温度,当茶叶实际温度等于或高于设定温度,继电器关闭,结果说明温度控制模块工作正常。
蓝牙模块测试:通过串口能将数据传输到电脑和手机上,蓝牙模块正常工作。
4.2 系统功能
开机后再液晶屏上显示当前的状态,包括实际温度与状态。通过独立按键设置需要达到的温度值,s3是加键,s4是减键,s5是确定键,s6是设置键,按确定键后,当实际温度小于设置温度时,屏幕显示加热与实际温度,并打开加热管控制继电器,当实际温度高于设置温度时,显示恒温与实际温度,并关闭加热管。当温度传感器故障时,在屏幕上显示液位异常,并蜂鸣器报警。不管在任何时候都可以对温度值进行设置,设置后马上更新状态。该毕业设计是一个硬件,里面有包括了单片机最小系统、蓝牙模块、温度传感模块、驱动显示电路、输出控制电路、电源电路、储存电路、报警电路和按键电路输出等各个系统和电路。因此,系统功能还包括复位功能,储存功能,报警功能,显示功能等各项。外部继电器控制好连接了一个加热管,实际上是由热得快做出来的,把热得快剪成两份,一份带着插头,另一份带着加热管,分开装进输出控制电路里,加热管由继电器控制开关,插头插在220V电源上,给加热管提供能量,由于安全原因,并没有直接测试加热功能。

部分代码

#include "LCD1602.h"
#include "UART.H"
#include
#include
#include
#include 

struct PID {
     
unsigned int SetPoint; // 设定目标 Desired Value
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
unsigned int Derivative; // 微分常数 Derivative Const
unsigned int LastError; // Error[-1]
unsigned int PrevError; // Error[-2]
unsigned int SumError; // Sums of Errors
};

struct PID spid; // PID Control Structure
unsigned int rout; // PID Response (Output)
unsigned int rin; // PID Feedback (Input)

unsigned char high_time,low_time,count=0;//占空比调节参数
unsigned char high_time1,low_time1,count1=0;//占空比调节参数
unsigned char high_time2,low_time2,count2=0;//占空比调节参数

sbit bell=P3^6;		     //蜂鸣器
sbit temper_relay=P2^3;	 //加热电磁阀
sbit temper_relay1=P2^4; //加热电磁阀
sbit temper_relay2=P2^5; //加热电磁阀


uint real_temper=0;		 //实际温度值
uint real_temper1=0;     //实际温度值
uint real_temper2=0;	 //实际温度值
uchar eeprom_value=0,set_temper=0;//eeprom值与设置温度值
uchar eeprom_value1=0,set_temper1=0;//eeprom值与设置温度值
uchar eeprom_value2=0,set_temper2=0;//eeprom值与设置温度值

uchar Temper_Flag=0,keep_temp_flag=0; //温度检测与恒温标志
uchar Temper_Flag1=0,keep_temp_flag1=0; //温度检测与恒温标志
uchar Temper_Flag2=0,keep_temp_flag2=0; //温度检测与恒温标志

uchar select_set=0;
uchar set_flag=0;	//设置温度标志
uchar bell_count;	//蜂鸣器报警数
uchar time_flag=0;

//定时器初始化 50ms
void Time_Init(void)
{
     
   TMOD=0X01;
   TH0=(65536-1000)/256;
   TL0=(65536-1000)/256;
   ET0=1;
   EA=1;
   TR0=1;
}

void PIDInit (struct PID *pp)
{
     
 memset ( pp,0,sizeof(struct PID));
}

//PID计算部分
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
     
unsigned int dError,Error;
Error = pp->SetPoint - NextPoint; // 偏差
pp->SumError += Error; // 积分
dError = pp->LastError - pp->PrevError; // 当前微分
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error // 比例项
+ pp->Integral*pp->SumError // 积分项
+ pp->Derivative*dError); // 微分项
}

//温度比较处理子程序
void compare_temper1(void)
{
     
  unsigned char i;
     if((set_temper)>(real_temper/10))
     {
     
      if((set_temper)-(real_temper/10)>1) //相差1度是开始PID调节  
         {
     
          high_time=100;  //实际温度与设置温度低一度以上时一直开启加热
          low_time=0;
         }
      else
         {
     
           for(i=0;i<10;i++) //计算10次
             {
      
			    EA=0; //关中断,防止影响读取数据
			    real_temper=DS18B20_Read_Tempereture(1);
				EA=1;
                rin = real_temper; // Read Input
                rout = PIDCalc ( &spid,rin ); // Perform PID Interation
             }
           if (high_time<=100)	 //换算调整值
             high_time=(unsigned char)(rout/800);
           else
             high_time=100;
           low_time= (100-high_time);
         }
     }
      else if((set_temper)<=(real_temper/10)) //实际温度比设置温度高时关闭加热
             {
     
               if((set_temper)-(real_temper/10)>0)//来回调整
                 {
     
                   high_time=0;
                   low_time=100;
                 }
               else
               {
     
                 for(i=0;i<10;i++)
                 {
       
				    EA=0;
				    real_temper=DS18B20_Read_Tempereture(1);
					EA=1;
                    rin = real_temper; // Read Input
                    rout = PIDCalc ( &spid,rin ); // Perform PID Interation
                 }
                 if (high_time<100)
                   high_time=(unsigned char)(rout/10000);
                 else
                   high_time=0;
                 low_time= (100-high_time);
               }
             }
 }

//温度比较处理子程序
//void compare_temper1(void)
//{
     
//  unsigned char i;
//     if((set_temper1)>(real_temper1/10))
//     {
     
//      if((set_temper1)-(real_temper1/10)>1) //相差1度是开始PID调节  
//         {
     
//          high_time1=100;  //实际温度与设置温度低一度以上时一直开启加热
//          low_time1=0;
//         }
//      else
//         {
     
//           for(i=0;i<10;i++) //计算10次
//             { 
//			    EA=0; //关中断,防止影响读取数据
//			    real_temper1=DS18B20_Read_Tempereture(2);
//				EA=1;
//                rin = real_temper1; // Read Input
//                rout = PIDCalc ( &spid,rin ); // Perform PID Interation
//             }
//           if (high_time1<=100)	 //换算调整值
//             high_time1=(unsigned char)(rout/800);
//           else
//             high_time1=100;
//           low_time1= (100-high_time1);
//         }
//     }
//      else if((set_temper1)<=(real_temper1/10)) //实际温度比设置温度高时关闭加热
//             {
     
//               if((set_temper1)-(real_temper1/10)>0)//来回调整
//                 {
     
//                   high_time1=0;
//                   low_time1=100;
//                 }
//               else
//               {
     
//                 for(i=0;i<10;i++)
//                 {  
//				    EA=0;
//				    real_temper1=DS18B20_Read_Tempereture(2);
//					EA=1;
//                    rin = real_temper1; // Read Input
//                    rout = PIDCalc ( &spid,rin ); // Perform PID Interation
//                 }
//                 if (high_time1<100)
//                   high_time1=(unsigned char)(rout/10000);
//                 else
//                   high_time1=0;
//                 low_time1= (100-high_time1);
//               }
//             }
// }
//
//温度比较处理子程序
//void compare_temper1(void)
//{
     
//  unsigned char i;
//     if((set_temper2)>(real_temper2/10))
//     {
     
//      if((set_temper2)-(real_temper2/10)>1) //相差1度是开始PID调节  
//         {
     
//          high_time2=100;  //实际温度与设置温度低一度以上时一直开启加热
//          low_time2=0;
//         }
//      else
//         {
     
//           for(i=0;i<10;i++) //计算10次
//             { 
//			    EA=0; //关中断,防止影响读取数据
//			    real_temper2=DS18B20_Read_Tempereture(3);
//				EA=1;
//                rin = real_temper2; // Read Input
//                rout = PIDCalc ( &spid,rin ); // Perform PID Interation
//             }
//           if (high_time2<=100)	 //换算调整值
//             high_time2=(unsigned char)(rout/800);
//           else
//             high_time2=100;
//           low_time2= (100-high_time2);
//         }
//     }
//      else if((set_temper2)<=(real_temper2/10)) //实际温度比设置温度高时关闭加热
//             {
     
//               if((set_temper2)-(real_temper2/10)>0)//来回调整
//                 {
     
//                   high_time2=0;
//                   low_time2=100;
//                 }
//               else
//               {
     
//                 for(i=0;i<10;i++)
//                 {  
//				    EA=0;
//				    real_temper2=DS18B20_Read_Tempereture(3);
//					EA=1;
//                    rin = real_temper2; // Read Input
//                    rout = PIDCalc ( &spid,rin ); // Perform PID Interation
//                 }
//                 if (high_time2<100)
//                   high_time2=(unsigned char)(rout/10000);
//                 else
//                   high_time2=0;
//                 low_time2= (100-high_time2);
//               }
//             }
// }
//

//从EEPROM中读取温度设置值
void Read_Set_EEPROM_Value(void)
{
     
   	set_temper=X24C02_Read(10);
	set_temper1=X24C02_Read(11);
	set_temper2=X24C02_Read(12);
}

//按键处理 温度值设定
void Set_Temper_Value(void)
{
     
    uchar value_temp;
	value_temp=P3&0x3C;	   //根据按键连接口获取是否有按键按下
	if(value_temp!=0x3c)
	{
     
	   _delay_ms(5);	  //消抖
	   if(value_temp!=0x3c)	 //再次确认是否有键按下
	   {
     
		    switch(value_temp)
			{
     
			   case 0x38: //加键
			        if(set_flag==1)	   //只有在设置按键按下后有效
					{
     
					   if(select_set==1)
					   {
     
					      if(eeprom_value<99) //温度值上限99度
						  eeprom_value++;	  //设置温度值加
						  LCD_write_Num_1(13,1,eeprom_value,2); //显示设置温度值
					   }
					   else if(select_set==2)
					   {
     
					      if(eeprom_value1<99) //温度值上限99度
						  eeprom_value1++;	  //设置温度值加
						  LCD_write_Num_1(13,1,eeprom_value1,2); //显示设置温度值
					   }
					   else if(select_set==3)
					   {
     
					      if(eeprom_value2<99) //温度值上限99度
						  eeprom_value2++;	  //设置温度值加
						  LCD_write_Num_1(13,1,eeprom_value2,2); //显示设置温度值
					   }
					}
			   break;
			   case 0x34: //减键
			        if(set_flag==1)	  //只有在设置按键按下后有效
					{
     
					   if(select_set==1)
					   {
     
					      if(eeprom_value>0)//小于下限时	
						  eeprom_value--;	//设置温度值减
						  LCD_write_Num_1(13,1,eeprom_value,2); //显示设置温度值
					   }
					   else	 if(select_set==2)
					   {
     
					      if(eeprom_value1>0)//小于下限时	
						  eeprom_value1--;	//设置温度值减
						  LCD_write_Num_1(13,1,eeprom_value1,2); //显示设置温度值
					   }
					   else	 if(select_set==3)
					   {
     
					      if(eeprom_value2>0)//小于下限时	
						  eeprom_value2--;	//设置温度值减
						  LCD_write_Num_1(13,1,eeprom_value2,2); //显示设置温度值
					   }
					}
			   break;
			   case 0x2c: //确定
			        if(set_flag==1)	 //只有在设置按键按下后有效
			        {
     
				        set_flag=0;	 //退出设置
					    LCD_write_str(8,1,"S:        ");
						if(select_set==1)
					    {
     
							X24C02_Write(10,eeprom_value); //将设置值写入EEPROM
							_delay_ms(5);	   //延迟EEPROM在写入后不能马上读,需要等待一定时间
							Read_Set_EEPROM_Value(); //读取EEPROM 重新赋值设置比较值
					    }
						else if(select_set==2)
					    {
     
							X24C02_Write(11,eeprom_value1); //将设置值写入EEPROM
							_delay_ms(5);	   //延迟EEPROM在写入后不能马上读,需要等待一定时间
							Read_Set_EEPROM_Value(); //读取EEPROM 重新赋值设置比较值
					    }
						else if(select_set==3)
					    {
     
							X24C02_Write(12,eeprom_value2); //将设置值写入EEPROM
							_delay_ms(5);	   //延迟EEPROM在写入后不能马上读,需要等待一定时间
							Read_Set_EEPROM_Value(); //读取EEPROM 重新赋值设置比较值
					    }
						select_set=0;
					}
			   break;
			   case 0x1c: //设置
			        select_set++;
					if(select_set==4)select_set=1;			        
					set_flag=1;	 //进度设置
					if(select_set==1)
					{
     
						LCD_write_str(8,1,"Set1:   ");
						eeprom_value=X24C02_Read(10);	//读取EEPROM中的值进行设置
						LCD_write_Num_1(13,1,eeprom_value,2);  //显示设置初始值
					}
					else if(select_set==2)
					{
     
						LCD_write_str(8,1,"Set2:   ");
						eeprom_value1=X24C02_Read(11);	//读取EEPROM中的值进行设置
						LCD_write_Num_1(13,1,eeprom_value1,2);  //显示设置初始值
					}
					else if(select_set==3)
					{
     
						LCD_write_str(8,1,"Set3:   ");
						eeprom_value2=X24C02_Read(12);	//读取EEPROM中的值进行设置
						LCD_write_Num_1(13,1,eeprom_value2,2);  //显示设置初始值
					}												

			   break;
			}
	   }
	   while(value_temp!=0x3c)value_temp=P3&0x3C; //松手检测
	} 	
}

//故障检测
void InDetect(void)
{
     
   if(DS18B20_Init(1)!=0) //温度传感器故障
   {
     
	   Temper_Flag=1;	//置标志
   }
   else 
   {
     
       Temper_Flag=0;
   }
   if(DS18B20_Init(2)!=0) //温度传感器故障
   {
     
	   Temper_Flag1=1;	//置标志
   }
   else 
   {
     
       Temper_Flag1=0;
   }
   if(DS18B20_Init(3)!=0) //温度传感器故障
   {
     
	   Temper_Flag2=1;	//置标志
   }
   else 
   {
     
       Temper_Flag2=0;
   }

   if((real_temper/10)<set_temper) //实际温度与设置温度比较
   {
     
       keep_temp_flag=0;
   }
   else
   {
     
       keep_temp_flag=1;
   }
   if((real_temper1/10)<set_temper1) //实际温度与设置温度比较
   {
     
       keep_temp_flag1=0;
   }
   else
   {
     
       keep_temp_flag1=1;
   }
   if((real_temper2/10)<set_temper2) //实际温度与设置温度比较
   {
     
       keep_temp_flag2=0;
   }
   else
   {
     
       keep_temp_flag2=1;
   }
}

//状态显示
void State_Display(void)
{
     
   InDetect(); //故障检测
   if(set_flag==0)//没有设置时显示
   {
     
	   if((Temper_Flag==1)||(Temper_Flag1==1)||(Temper_Flag2==1))
	   {
     
	      LCD_write_str(10,1,"Error ");	 //温度异常
	   }
	   else
	   {
     
		 if((keep_temp_flag==0)||(keep_temp_flag1==0)||(keep_temp_flag2==0))
		 {
     
		   	LCD_write_str(10,1,"Hot   ");//加热
		 }
		 else
		 {
     
		    LCD_write_str(10,1,"Normal");	//正常
		 }
	   }
   }
}

//输出蜂鸣器与继电器控制
void Output_Control(void)
{
     
   	if((Temper_Flag==1)||(Temper_Flag1==1)||(Temper_Flag2==1))//温度故障时报警
	{
     
	   	bell_count=4;
	}
	else  bell_count=0;
}

//设备初始化函数
void Device_Init(void)
{
     
    Time_Init();
	Init_uart();
  	LCD_init();
	DS18B20_Init(1);
	DS18B20_Init(2);
	DS18B20_Init(3);
    LCD_write_str(0,0,"T1:");
	LCD_write_str(9,0,"T2:");
	LCD_write_str(0,1,"T3:");
	LCD_write_str(8,1,"S:        ");
	Read_Set_EEPROM_Value();
}

//主函数
int main(void)
{
        
    Device_Init(); //设备初始化
	PIDInit ( &spid ); // 初始化PID
	spid.Proportion = 10; // Set PID Coefficients
	spid.Integral = 8;
	spid.Derivative =6;
	spid.SetPoint = 100; // Set PID Setpoint
    while(1)
    {
     
	   if(time_flag==1)
	   {
     
	       time_flag=0;
		   if((Temper_Flag==0))  //温度传感器无故障时
		   {
     
		       EA=0;
			   real_temper=DS18B20_Read_Tempereture(1); //读取温度值
			   EA=1;
		       LCD_write_Num(3,0,real_temper,4);  //显示温度值
			   printf("Temper1_Value=%f\r\n",real_temper/10.0);		  
		   }
		   else
		   {
     
		     LCD_write_str(3,0,"Eor "); //温度传感器有故障时
			 printf("Temper1_Value=Error!\r\n");
		   }
	
		   if((Temper_Flag1==0))  //温度传感器无故障时
		   {
     
		       EA=0;
			   real_temper1=DS18B20_Read_Tempereture(2); //读取温度值
			   EA=1;
		       LCD_write_Num(12,0,real_temper1,4);  //显示温度值
			   printf("Temper2_Value=%f\r\n",real_temper1/10.0);	
		   }
		   else 
		   {
     
		       LCD_write_str(12,0,"Eor "); //温度传感器有故障时
			   printf("Temper2_Value=Error!\r\n");
		   }
	
		   if((Temper_Flag2==0))  //温度传感器无故障时
		   {
     
			   EA=0;
			   real_temper2=DS18B20_Read_Tempereture(3); //读取温度值
			   EA=1;
		       LCD_write_Num(3,1,real_temper2,4);  //显示温度值
			   printf("Temper3_Value=%f\r\n",real_temper2/10.0);	
		   }
		   else 
		   {
     
		       LCD_write_str(3,1,"Eor "); //温度传感器有故障时
			   printf("Temper3_Value=Error!\r\n");
		   }
		   printf("==================================\r\n");
	   }
	   State_Display();
	   Set_Temper_Value();
	   compare_temper1();
	   //compare_temper2();
	   //compare_temper3();
	   Output_Control(); 
    }
}

//定时器中断
void Time0(void) interrupt 1
{
     
   static uchar count=0;
   static uint m=0;
   TH0=(65536-1000)/256;
   TL0=(65536-1000)/256;

   m++;
   count++;
   //count1++;
   //count2++;
   if(m==1000) //1S计时
   {
     
     m=0;
	 time_flag=1;
	 if(bell_count>0)
    {
     
       bell=~bell;//蜂鸣器标志取反
       bell_count--;//次数减少      
    }
    else bell=1;//次数到达时关闭蜂鸣器
   }
   if(count<=(high_time))
     temper_relay=0;
   else if(count<=100)
     {
     
      temper_relay=1;
      }
   else
      count=0;
   
//   if(count1<=(high_time1))
//     temper_relay1=0;
//   else if(count<=100)
//     {
     
//      temper_relay1=1;
//      }
//   else
//      count1=0;
//
//   if(count2<=(high_time2))
//     temper_relay2=0;
//   else if(count2<=100)
//     {
     
//      temper_relay2=1;
//      }
//   else
//      count2=0;

电路图
系统设计图和电源模块:
温控自动烘焙系统的研究与实现_第6张图片
温度控制模块
温控自动烘焙系统的研究与实现_第7张图片
温控自动烘焙系统的研究与实现_第8张图片

你可能感兴趣的:(论文相关,温控电路)