返回列表 发新帖我要提问本帖赏金: 100.00元(功能说明)

【电子竞赛预热赛】+自动恒温控制系统的实现

[复制链接]
 楼主| jinglixixi 发表于 2017-11-7 13:07 | 显示全部楼层 |阅读模式
(一)方案的规划
面对该项目的实施,首先要有一个有效的规划并分析出设计的关键问题。
通过对基础功能的要求,可以看出这当中有3个关键点,即:
1)温度检测元件的选取及功能实现
温度检测元件有多种,如工业控制上所用的温度传感器PT100、供环境检测的温湿度传感器DHT11、单总线数字式温度检测元件DS18B20等。
相对来讲,PT100的温度检测范围比较宽,可达300度甚至更高,到它在使用时需进行相应的线性化处理;对于DHT11来讲,它既可以检测温度,又能检测湿度,用起来比较实惠,但其温度检测范围相对比较窄,基本在0~50度左右;经比较还是选取DS18B20为好,其温度检测范围和检测精度均能满足需要。
2)加热器件的选择及控制算法的选择
在温度检测元件可满足要求后,就是选取何种加热元件来提升温度,常规加热元件是电阻丝或加热棒,由于加热器件具有一定的滞后性,因此在控制时对控制元件和控制算法也产生相应的要求。最廉价的控制元件是继电器,但频繁的开关对其触点的寿命会有较大的损伤;使用固态继电器的话,将有利于使用PWM调节,但价格相对较高。因此需要在实际应用中去综合权衡,在控制精度有效的情况下,则需引入PID调节或模糊控制算法,这将导致复杂度的提升。
3)上位的开发工具选择及功能实现
由于涉及到上机的功能实现,所以通讯功能是必不可少的,其次就是对开发工具的选择。
从功能的要求看,宜采用VB或LABVIEW等软件来开发,这样易于进行温度变化曲线的绘制。
(二)下位机的功能实现
下位机的硬件构成,主要包括温度检测、数据处理、数值显示、温度控制等环节,其构成图如图1所示。
360截图16251123427348.jpg

相关元件的选取如下:
1. 液晶显示屏选取LCD5110
2. 单片机选STM32F030
3. 温度传感器选DS18B20,其中一个用于外部环境检测,另一个用于恒温器内部检测。
4. 串行通讯采用TTL转USB串行通讯模块 / 虚拟串口
5. 按键选取4键位软按键
6. 加热器选~220V电加热棒
7. 控制器视控制精度选取光隔继电器或固态继电器

打赏榜单

21ic小喇叭 打赏了 100.00 元 2017-12-18
理由:电子竞赛活动参与奖

21ic小喇叭 发表于 2017-11-7 13:10 | 显示全部楼层
顶你上热门,期待后续更新哦~
 楼主| jinglixixi 发表于 2017-11-7 13:59 | 显示全部楼层
21ic小喇叭 发表于 2017-11-7 13:10
顶你上热门,期待后续更新哦~

继续努力!!!
修一明 发表于 2017-11-7 14:53 | 显示全部楼层
加油,看好楼主
 楼主| jinglixixi 发表于 2017-11-7 17:38 | 显示全部楼层

多谢鼓励与支持!!!
 楼主| jinglixixi 发表于 2017-11-8 09:41 | 显示全部楼层
本帖最后由 jinglixixi 于 2017-11-19 14:01 编辑

自动恒温控制系统的实现 (2)
  
下位机的开发平台选取KEIL V4.0,并由C51编程来实现功能要求。

相关的功能程序如下:
1. 液晶屏显示程序
2. 参数设置程序
3. 温度检测与控制程序
4. 串行通讯程序

液晶屏的连接与显示程序
        LCD5110为3.3V的显示器件,并以SPI的通讯方式来进行控制,为节省管脚,直接将CS引脚以GND相连,其信号引脚的连接情况如下:
       SCLK--PC.3
       DIN --PC.2
       DC  --PC.1
       RST --PC.0
    此外,可以将用背光引脚与一个GPIO口相连以控制背光的亮灭。

    定义LCD5110信号引脚输出高低电平的语句如下:
       #define SetLCD_SCLK_High()         { GPIO_WriteBit(GPIOC, GPIO_Pin_3, Bit_SET);}
       #define SetLCD_SCLK_Low()          { GPIO_WriteBit(GPIOC, GPIO_Pin_3, Bit_RESET);}

       #define SetLCD_SDIN_High()          { GPIO_WriteBit(GPIOC, GPIO_Pin_2, Bit_SET);}
       #define SetLCD_SDIN_Low()          { GPIO_WriteBit(GPIOC, GPIO_Pin_2, Bit_RESET);}

       #define SetLCD_DC_High()            { GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_SET);}
       #define SetLCD_DC_Low()             { GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_RESET);}

       #define SetLCD_RST_High()           { GPIO_WriteBit(GPIOC, GPIO_Pin_0, Bit_SET);}
       #define SetLCD_RST_Low()           { GPIO_WriteBit(GPIOC, GPIO_Pin_0, Bit_RESET);}

        配置相应引脚的函数如下:
  1. void GPIO_Configuration(void)
  2. {
  3.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);  
  4.     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  5.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  6.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  7.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  8.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  
  9.     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  11.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  12.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  13. }
      对应的初始化程序为:
  1. void LCD_Init(void)
  2. {
  3.         SetLCD_RST_Low();   
  4.         delay_1us();
  5.         SetLCD_RST_High();   
  6.         delay_1us();
  7.         delay_1us();
  8.         LCD_write_CMD(0x21);
  9.         LCD_write_CMD(0xc0);
  10.         LCD_write_CMD(0x06);
  11.         LCD_write_CMD(0x13);
  12.         LCD_write_CMD(0x20);
  13.         LCD_Clear();           
  14.         LCD_write_CMD(0x0c);        
  15. }
         实现初始显示界面的语句如下:
  1.          GPIO_Configuration();        
  2.          GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
  3.          LCD_Init();
  4.          LCD_Clear();
  5.          LCD_write_english_string(0,0,"nokia5110 v1.0");
  6.          LCD_write_english_string(0,2,"x1= ");
  7.          LCD_write_english_string(0,3,"x2= ");
  8.          LCD_write_english_string(0,4,"temp= ");
  9.          LCD_set_XY(42,2);
  10.          LCD_write_char(i+0x30);

        其界面效果如图2所示,由于当前温度低于温度下限,故加热器应开启以蓝色LED指示。
图片1.png
2 界面显示效果

参数设置及程序
       参数设置在温控系统中是十分重要的,否则温控器只能对某个固定温度区域进行控制。
为简化设计,这里是采用软按键来进行参数设置,它共有4个键,分别对应+1、-1、移位和确认处理。
       4个键位分别与PB2、PB10、PB11、PB12相连,其引脚配置函数如下:
  1. void Key_IN(void)
  2. {
  3.      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  
  4.      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
  5.      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;
  6.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  7.      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  8.      GPIO_Init(GPIOB, &GPIO_InitStructure);
  9. }
          实现上下限设置的程序如下:
  1.       f==2;
  2.       while(f)
  3.           {
  4.                         if(f==2) LCD_set_XY(42,2);
  5.                         if(f==1) LCD_set_XY(42,3);
  6.                         if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==0)
  7.                         {
  8.                                 i--;
  9.                         }
  10.                                 
  11.                         if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0)  //  确认键
  12.                         {
  13.                                         if(f==1)  
  14.                                         {
  15.                                                 x2=i;
  16.                                                 f=0;
  17.                                         }
  18.                                        
  19.                                         if(f==2)  
  20.                                         {
  21.                                                 x1=i;
  22.                                                 i=0;
  23.                                                 f=1;
  24.                                                 LCD_set_XY(42,3);
  25.                                         }
  26.                                 }
  27.                                 
  28.                                 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==0)
  29.                                 {
  30.                                         i++;
  31.                                 }
  32.                                 
  33.                                 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2)==0)
  34.                                 {
  35.                                        i=i*10;
  36.                                 }
  37.                                 LCD_write_char(i/1000+0x30);
  38.                                 LCD_write_char(i%1000/100+0x30);
  39.                                 LCD_write_char(i%100/10+0x30);
  40.                                 LCD_write_char('.');
  41.                                 LCD_write_char(i%10+0x30);
  42.                                 for(k=0;k<20;k++)
  43.                                 {
  44.                                    Delay(60000);
  45.                                 }
  46.                   }
温度检测与控制
      DS18B20是一种使用广泛的单总线器件,其实它还有一种防水型的封装形式,如图3所示。由于手头没有就暂时用塑料封装的吧。
图片2.png
3 防水型DS18B20

     与DS18B20相连的引脚是PC4,由于该温度传感器只有一条数据引脚,故分时进行输入和输出处理,其相应的引脚配置函数如下:
  1. void DS18B20_IO_IN(void)
  2. {
  3.      GPIO_InitTypeDef  GPIO_InitStructure;
  4.      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_4 ;
  5.      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;
  6.      GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  7.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  8.      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  9.      GPIO_Init(GPIOC, &GPIO_InitStructure);
  10. }
  11. void DS18B20_IO_OUT(void)
  12. {
  13.      GPIO_InitTypeDef  GPIO_InitStructure;  
  14.      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_4 ;//4
  15.      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  16.      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  17.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  18.      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  19.      GPIO_Init(GPIOC, &GPIO_InitStructure);
  20. }
         实现温度检测与控制的程序如下:
  1. while (1)  
  2.         {
  3.                    DS18B20_Convert();
  4.                    tempL = DS18B20_Read_Byte(); // LSB   
  5.                    tempH = DS18B20_Read_Byte(); // MSB  
  6.                    j=tempH*16+tempL/16;
  7.                    LCD_set_XY(42,4);
  8.                    LCD_write_char(j/100+0x30);
  9.                    LCD_write_char(j%100/10+0x30);
  10.                    LCD_write_char(j%10+0x30);
  11.                    LCD_write_char('.');
  12.                    LCD_write_char((tempL%16)*10/16+0x30);
  13.                    i=j*10+(tempL%16)*10/16;
  14.                    if(i>=x1) GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
  15.                    if(i<=x2) GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
  16.                   Delay(5000);        
  17.       }        
    由于手头的电加热棒还未找到,目前只以指示灯来模拟继电器的工作状态变化,后续再将继电器和加热棒接上验证一下控制效果。图4为温度超过上限,关闭加热器即关闭蓝色LED。通过模拟验证可发现,检测与反应的精度可达0.1度,要想达到控制的高精度就要看控制算法了。

       此外,为了上传数据来绘制波形图,还需提交串行通讯的功能,并为指令的发送提供支持。
图片3.png
4 温度模拟控制


caijie001 发表于 2017-11-15 15:47 | 显示全部楼层
不错啊,可以做完整点,包括加热降温的空间。然后在上位机看到温度信息。。。等等期待完成
 楼主| jinglixixi 发表于 2017-11-16 08:41 | 显示全部楼层
正在最温度的控制精度检测,上位机是用LABVIEW绘制曲线,发现没有串口驱动还在下载测试。。。
 楼主| jinglixixi 发表于 2017-11-19 13:47 | 显示全部楼层

自动恒温控制系统的实现 (3)

本帖最后由 jinglixixi 于 2017-11-19 14:02 编辑

前面已经实现了温度的模拟测控,这次又购置了些器件,做了进一步的完善,主要体现在以下几个方面:
1.实现温度的双通道采集
为了满足环境温度检测与恒温控制的需要,在原设计的基础上又增添了一个温度温度传感器,并对显示界面进行了相应的修改,其变化如图1所示。
新增的温度传感器占用PC6,功能函数可通过复制的方法来实现,然后更改名称即可。
1.jpg

2.以固态继电器控制加热器
为了便于加热控制和增强控制器件的使用寿命,特购置了固态继电器来控制加热器,其连接方式如图2所示。经测试,使用GPIO口即可触发其工作,其输出端则可以直接接入~220V电路。固态继电器所占用的GPIO口为PC7。
2.jpg

3.加热器的选取
本来已购置了电加热管,收到后才发现其功率太大了,如图3所示,做实验实在是不安全,所以只好改用电烙铁为加热器,其线路如图4所示。
图片1.png
图3 电加热管

3.jpg

经实际检测,在不添加PID调节算法的情况下可达到+/-1.5度的控制要求,在设置上、下限后其控制效果如图5所示。其中X1为上限温度值,X2为下限温度值,temp为当前的控制温度,temp’为环境温度。由于没有配置保温箱的缘故,再停止加热后温度跌落的较快,故控制温度的上限偏差小,而控制温度的下限偏差稍大。如果时间允许,加入PID调节后精度会有一定提高,有望达到+/-0.5度的控制指标。
4.jpg

4. 串行通讯功能
串行通讯功能是通过USB转TTL来实现的,它与MCU的引脚连接连接为:
PA9  --USB_RXD
PA10 --USB_TXD
具体连接如图6所示
图片2.png
6 通过虚拟串口进行串行通讯

实现串行通讯的程序如下:
  1. Uart_Init();
  2. While(1)
  3. {
  4. ...
  5. DS18B20_Convert();
  6.         tempL = DS18B20_Read_Byte(); // LSB   
  7.         tempH = DS18B20_Read_Byte(); // MSB  
  8.         j=tempH*16+tempL/16;
  9.         Uart_Put_Char(j/100+'0');
  10.         Uart_Put_Char(j%100/10+'0');        
  11.         Uart_Put_Char(j%10+'0');
  12.         Uart_Put_Char('.');
  13.         Uart_Put_Char((tempL%16)*10/16+'0');
  14.         Uart_Put_Char(0x0d);
  15.         Uart_Put_Char(0x0a);
  16. }

图片3.png
图7 串行通讯接收数据

由于LabVIEW的通讯驱动尚未搞定,因此暂时还没有绘制出温度曲线及进行上下限的设置处理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

518

主题

2933

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部

518

主题

2933

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部