AUTO-FLOWERPOT
My mom loves household plants, but she always fails to cultivate a thriving plant. Gradually, I found out that there are lots of individuals having those similar problems. Then, I started wondering what is the most difficult part cultivating household plants. Obviously, the light is the most unpredictable condition for a healthy plant; thus I started with the light.
Pain Point
The majority Individuals who love household plants do not have enough professional knowledge about plants, especially the light condition and thus they can barely cultivate a plant successfully.
Techniques Involved
Thermal transfer printing / Welding / Injection mould making / Spraying assembly
Material
Laser pinter / Parchment paper / Thermal transfer printer / Corrosive liquid / Oil pen / CCL(copper-clad plate) / Perforator / Plastic / Electronic components
Software
Keil uvision5
Altium Designer Summer 09
Sketchup
Adobe Photoshop CC
Adobe Illustrator CC
Finish
09/2015
Automatic light-adjusting flowerpot aims at those who love household plants but have not enough professional knowledge about plant and time caring their plants. This equipment is designed to adjust the ambient light. Specifically, it would emit a stronger light to compensate deficient ambient light received by the sensor and stop emitting light if ambient light is high enough for plants’ photosynthesis, making sure that plants would in the perfect light condition which benefits its growth.
Cross-section Diagram
Additionally, this equipment provides two different light color, red and blue, which are the two most efficient light colors for enhancing photosynthesis. Individuals could set an illumination intensity and then automatic light-adjusting flowerpot would start working that ensure the total light intensity of the plant, including ambient light intensity and compensatory light intensity, would meet the set value.
In general, the automatic light-adjusting flowerpot is designed to deal with the household plants planting issue of ambient light’s fluctuation.
3D Display
The Dimming Effect
Control Principle
The system is based on PID control. PID control is prevalent in the industry, and in Auto-Lighting, the PID control actualizes the self-regulation of light.
In this closed-loop control system, the Photosensitive resistance would receive the ambient light intensity and compare the value with the preset value set by users. If the outcome is negative, which means the ambient light intensity is less than the preset light intensity, the system would increase the light intensity of LED; But in contrast, if the outcome is positive, the system would decrease the light intensity of LED.
In the debugging process, I found that the light adjusting system is too sensitive to be stable; thus I set a 500 Lx cushion. If the difference between the received value and preset value is less than 500 Lx, to ensure system’s stability, the system wouldn’t respond.
Circuit Diagram
LED Module Circuit
MCU Module Circuit
Power Supply, Switch, Buzzer Circuit
LCD, Indicator Light, A/D Circuit
Code
# ifndef _ADC083_2_H_ # define _ADC083_2_H_ #include<reg52.h> //包含单片机寄存器的头文件 #include<intrins.h> //包含_nop_()函数定义的头文件 sbit CS=P1^3; //将CS位定义为P3.4引脚 sbit CLK=P1^4; //将CLK位定义为P1.0引脚 sbit DIO=P1^5; //将DIO位定义为P1.1引脚 unsigned char A_D(unsigned char channel); #endif #include "ADC0832.h" unsigned char A_D(unsigned char channel) { unsigned char i,dat; CS=1; //一个转换周期开始 CLK=0; //为第一个脉冲作准备 CS=0; //CS置0,片选有效 DIO=1; //DIO置1,规定的起始信号 CLK=1; //第一个脉冲 CLK=0; //第一个脉冲的下降沿,此前DIO必须是高电平 DIO=1; //DIO置1, 通道选择信号 CLK=1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0 CLK=0; //第二个脉冲下降沿 DIO=channel; //DI置0,选择通道0 CLK=1; //第三个脉冲 CLK=0; //第三个脉冲下降沿 DIO=1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1 CLK=1; //第四个脉冲 for(i=0;i<8;i++) //高位在前 { CLK=1; //第四个脉冲 CLK=0; dat<<=1; //将下面储存的低位数据向右移 dat|=(unsigned char)DIO; //将输出数据DIO通过或运算储存在dat最低位 } CS=1; //片选无效 return dat; //将读书的数据返回 }
# ifndef _DHT11_H_ # define _DHT11_H_ #include <reg52.h> sbit DTH=P1^0; void RH(void) ; #endif #include "DHT11.h" #define uchar unsigned char #define uint unsigned int typedef uchar U8; /* 无符号8位整型变量 */ typedef uint U16; /* 无符号16位整型变量 */ uchar U8FLAG; uchar U8count,U8temp; uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata; uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp; uchar U8comdata; extern uint counti; void Delay_10us(void) { U8 i; i--; i--; i--; i--; i--; i--; } void Delay(U16 j) { U8 i; for(;j>0;j--) for(i=0;i<27;i++); } //*******一字节数据传送函数********* void COM(void) { U8 i; for(i=0;i<8;i++) { U8FLAG=2; while((!DTH)&&U8FLAG++); TR1=1; //Delay_10us(); //Delay_10us(); // Delay_10us(); TR1=0; U8temp=0; if(DTH) U8temp=1; U8FLAG=2; while((DTH)&&U8FLAG++);//超时则跳出for循环 if(U8FLAG==1)break; //判断数据位是0还是1 / 如果高电平高过预定0高电平值则数据位为 1 U8comdata<<=1; U8comdata|=U8temp; //0 }//rof } //-----湿度读取子程序 ------------ //-------------------------------- //----以下变量均为全局变量-------- //----温度高8位== U8T_data_H------ //----温度低8位== U8T_data_L------ //----湿度高8位== U8RH_data_H----- //----湿度低8位== U8RH_data_L----- //----校验 8位 == U8checkdata----- //----调用相关子程序如下---------- //---- Delay();, Delay_10us();,COM(); //-------------------------------- uchar flagi=0; void RH(void) { //主机拉低18ms DTH=0; flagi=1; TR1=1; while(flagi==1); //Delay(5); TR1=0; DTH=1; //总线由上拉电阻拉高 主机延时20us TR1=1; //_nop_(); //Delay_10us(); //Delay_10us(); //Delay_10us(); //Delay_10us(); TR1=0; //主机设为输入 判断从机响应信号 DTH=1; //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(!DTH) //T ! { U8FLAG=2; //判断从机是否发出 80us 的低电平响应信号是否结束 while((!DTH)&&U8FLAG++); U8FLAG=2; //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 while((DTH)&&U8FLAG++); //数据接收状态 COM(); U8RH_data_H_temp=U8comdata; COM(); U8RH_data_L_temp=U8comdata; COM(); U8T_data_H_temp=U8comdata; COM(); U8T_data_L_temp=U8comdata; COM(); U8checkdata_temp=U8comdata; DTH=1; //数据校验 U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp); if(U8temp==U8checkdata_temp) { U8RH_data_H=U8RH_data_H_temp; //湿度高位 U8RH_data_L=U8RH_data_L_temp; //湿度低位 U8T_data_H=U8T_data_H_temp; //温度高位 U8T_data_L=U8T_data_L_temp; //温度低位 U8checkdata=U8checkdata_temp; }// }// }
# ifndef _LCD1602_H_ # define _LCD1602_H_ #include "reg52.h" #include "intrins.h" #define nop _nop_() #define uchar unsigned char typedef unsigned char uint8; typedef signed char int8; typedef unsigned int uint16; typedef signed int int16; typedef unsigned long uint32; typedef signed long int32; #define LCD1602_DATA P0 //8位数据并行口 sbit LCD1602_RS=P2^5; //指令OR数据寄存器选择 sbit LCD1602_RW=P2^6; //读写控制 sbit LCD1602_EN=P2^7; //使能控制 #define LCD1602_CLR 0x01 //清屏 #define LCD1602_MODE 0x38 //8位数据,双列显示,5*7字形 #define LCD1602_ON 0x0c //开显示,关光标,光标不闪烁 #define LCD1602_ADDR_MODE 0x06 //地址递增 void LCD1602_init(); void LCD1602_write_cmd(uint8 cmd); void LCD1602_write_data(uint8 dat); void LCD1602_set_postion(unsigned char ,unsigned char ); //设置显示坐标 void LCD1602_write_char(uint8 x , uint8 y , uint8 chardata); //指定位置写字符 void LCD1602_write_string(uint8 x , uint8 y , uint8 *string) ; //在指定位置显示字符串 void LCD1602_write_num(uint8 x , uint8 y , uint8 chardata) ; //在指定位置显示一个数字 void LCD1602_write_num2(uint8 x , uint8 y , uint8 chardata); //在指定位置显示两个数字 void WriteAddress(unsigned char x); #endif #include "lcd1602.h" /*********************************************************** 忙检测 ************************************************************/ void LCD1602_check_busy() { LCD1602_DATA= 0xff; LCD1602_RS=0; LCD1602_RW = 1 ; LCD1602_EN = 1 ; while(LCD1602_DATA & 0x80) ; LCD1602_EN = 0 ; } /********************************************************** 写指令 ************************************************************/ void LCD1602_write_cmd(uint8 cmd) { LCD1602_check_busy(); LCD1602_RS = 0 ; LCD1602_RW = 0 ; LCD1602_DATA = cmd ; LCD1602_EN = 1 ; LCD1602_EN = 0 ; } /***************************************************** 函数功能:指定字符显示的实际地址 入口参数:x ***************************************************/ /*void WriteAddress(unsigned char x) { LCD1602_write_cmd(x | 0x80); //显示位置的确定方法规定为"80H+地址码x" }*/ /*********************************************************** 写数据 *************************************************************/ void LCD1602_write_data(uint8 dat) { LCD1602_check_busy(); LCD1602_RS = 1 ; LCD1602_RW = 0 ; LCD1602_DATA = dat ; LCD1602_EN = 1 ; LCD1602_EN = 0 ; } /*********************************************************** 1602初始化 ************************************************************/ void LCD1602_init(void) { LCD1602_write_cmd(LCD1602_MODE) ; LCD1602_write_cmd(LCD1602_ON) ; LCD1602_write_cmd(LCD1602_ADDR_MODE) ; LCD1602_write_cmd(LCD1602_CLR) ; } /************************************************************ 设置显示坐标 ************************************************************/ void LCD1602_set_postion(unsigned char x , unsigned char y) { if(y<2) { y &= 0x01 ; //y值限定在0~1之间 x &= 0x0f ; //x值限定在0~15之间 if(y == 0) x |= 0x40 ; //如果显示是在第二行,则x的值加0x40 x |= 0x80 ; //获得x的值 LCD1602_write_cmd(x) ;//写入坐标值到LCD } } /************************************************************ 指定位置写字符 *************************************************************/ void LCD1602_write_char(uint8 x , uint8 y , uint8 chardata) { LCD1602_set_postion(x,y) ; LCD1602_write_data(chardata) ; } /************************************************************ 指定位置写字符串 *************************************************************/ void LCD1602_write_string(uint8 x , uint8 y , uint8 *string) { LCD1602_set_postion(x,y) ; while((*string) != '\0') { LCD1602_write_data(*string) ; string++ ; } } void LCD1602_write_num(uint8 x , uint8 y , uint8 chardata) //在指定位置显示一个数字 { LCD1602_write_char(x , y , (0x30+chardata)) ; } void LCD1602_write_num2(uint8 x , uint8 y , uint8 chardata) //在指定位置显示两个数字 { uint8 data_ten,data_bits; data_ten=chardata/10; data_bits=chardata%10; LCD1602_write_num(x , y , data_ten); LCD1602_write_num(x+1 ,y , data_bits); }
# ifndef _LCD12864_H_ # define _LCD12864_H_ #include <reg52.h> #define LCD_Data P0 #define Busy 0x80 //用于检测LCD状态字中的Busy标识 //位定义 sbit LCD_RS = P2 ^ 5; // 寄存器选择位 sbit LCD_RW = P2 ^ 6; //读写选择位 sbit LCD_E = P2 ^ 7; //使能信号 //sbit LCD_RS = P2 ^ 0; // 寄存器选择位 //sbit LCD_RW = P2 ^ 1; //读写选择位 //sbit LCD_E = P2 ^ 2; //使能信号 //sbit LCD_BF = P0 ^ 7; //忙碌标志位 unsigned char ReadStatusLCD(void);//读状态 void WriteData(unsigned char WDLCD);//写数据 void Write_com(unsigned char WCLCD);//写指令 void LCDInit(void); //LCM初始化 void WriteAddress(unsigned char X, unsigned char Y); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//按指定位置显示一串字符 void PrintNum(unsigned char num); //显示两位数字 void print_num1(unsigned char X, unsigned char Y, unsigned char num); //按指定位置显示一位数字 void print_num2(unsigned char X, unsigned char Y, unsigned char num); //按指定位置显示两位数字 //写坐标 void WriteAddress(unsigned char X, unsigned char Y); //写数据 void WriteData(unsigned char WDLCD); #endif #include "LCD12864.h" /***************************************************/ //读状态 unsigned char ReadStatusLCD(void) { LCD_Data = 0xFF; LCD_RS = 0; LCD_RW = 1; LCD_E = 1; while (LCD_Data & Busy); //检测忙信号 LCD_E = 0; return(LCD_Data); } //写数据 void WriteData(unsigned char WDLCD) { ReadStatusLCD(); //检测忙 LCD_RS = 1; LCD_RW = 0; LCD_Data = WDLCD; LCD_E = 1; LCD_E = 1; LCD_E = 1; LCD_E = 0; } //写指令 void Write_com(unsigned char WCLCD) { ReadStatusLCD(); //检测忙 LCD_RS = 0; LCD_RW = 0; LCD_Data = WCLCD; LCD_E = 1; LCD_E = 1; LCD_E = 1; LCD_E = 0; } void LCDInit(void) //LCM初始化 { Write_com(0x30); //显示模式设置,开始要求每次检测忙信号 Write_com(0x01); //显示清屏 Write_com(0x06); // 显示光标移动设置 Write_com(0x0C); // 显示开及光标设置 Write_com(0x02); //SR等于0,允许设置卷动地址 Write_com(0x30); //恢复为8位并行,基本指令集 Write_com(0x40);//将CGRAM空间号转换为相应存储地址 定位到该位址(用户空间位址范围0x40-0x7F共128字节) } //写坐标 void WriteAddress(unsigned char X, unsigned char Y) { switch(Y){ case 1:X|=0X80;break; //根据行数来选择相应地址 case 2:X|=0X90;break; case 3:X|=0X88;break; case 4:X|=0X98;break; } Write_com(X); //发送地址码 } //按指定位置显示一串字符 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) { unsigned char ListLength,X2; ListLength = 0; X2=X; if(Y<1) Y=1; if(Y>4) Y=4; X &= 0x0F; //限制X不能大于16,Y在1-4之内 switch(Y){ case 1:X2|=0X80;break; //根据行数来选择相应地址 case 2:X2|=0X90;break; case 3:X2|=0X88;break; case 4:X2|=0X98;break; } Write_com(X2); //发送地址码 while (DData[ListLength]>=0x20) //若到达字串尾则退出 { if (X <= 0x0F) //X坐标应小于0xF { WriteData(DData[ListLength]); // ListLength++; X++; //Delay5Ms(); } } } //按指定位置显示两位数字 void print_num2(unsigned char X, unsigned char Y, unsigned char num) { unsigned char ListLength,X2; ListLength = 0; X2=X; if(Y<1) Y=1; if(Y>4) Y=4; X &= 0x0F; //限制X不能大于16,Y在1-4之内 switch(Y){ case 1:X2|=0X80;break; //根据行数来选择相应地址 case 2:X2|=0X90;break; case 3:X2|=0X88;break; case 4:X2|=0X98;break; } Write_com(X2); //发送地址码 WriteData(0x30 + num % 100 / 10); WriteData(0x30 + num % 10); } //显示两位数字
#include <reg52.h> //包含的头文件 #include "ADC0832.h" #include "DHT11.h" #include "LCD12864.h" #define uchar unsigned char //宏定义 #define uint unsigned int #define V_TH1 0XFF #define V_TL1 0XF6 uchar code *t= "温度" ; uchar code *h= "湿度"; uchar code *l= "光照强度"; uchar code *ly= "光照阈值"; uchar code *s= "报警阈值设置"; uchar code *z= "状态"; sbit FMQ=P3^3; //蜂鸣器 sbit led1=P3^5; sbit led2=P3^7; sbit K5=P2^0; sbit K4=P2^1; sbit K3=P2^2; sbit K2=P2^3; sbit K1=P2^4; bit ledflag=0; extern uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L; extern uchar flagi; int V=0; //读出的模拟量 long lx=0; //光照强度 uint choose=0; //设置项选择 char Temp_H=35,Temp_L=15; //温度 上 下 限 初值 uchar Hum_H=50,Hum_L=10; //湿度 上 下 限 初值 uint light_H=200; //烟雾报警阈值 uint light_L=800; uchar num=0; //定时器计数 uint second=0; uchar ZKB; bit temp_h_flag=0; //温度超过上限标志位 bit temp_l_flag=0; //温度低于下限 bit hum_h_flag=0; //湿度高于上限 bit hum_l_flag=0; //湿度低于下限 bit light_h_flag=0; //光照报警 bit light_l_flag=0; //光照报警 bit FMQ_alarm1=0; //开启蜂鸣器标志位 bit FMQ_alarm2=0; bit close_alarm1=0; //关闭本次警报 bit close_alarm2=0; bit flag=0; typedef struct PID { uint Setpoint; //设定值 float P; //比例系数 float I; //积分系数 float D; //微分系数 long Error; //当前误差 long LastError; //上一次误差 long PreError; //上上一次误差 }PID; PID vPID; //定义结构体变量名称 //u(k)=Kp(e(k)-e(k-1))+Kie(k)+Kd(e(k)-2e(k-1)+e(k-2)) // 定义PID参数结构体 void init_PID() { vPID.P=0.00003; //0.005 vPID.I=0.2; vPID.D=0.000000; vPID.Error=0; vPID.LastError=0; vPID.PreError=0; vPID.Setpoint=(light_L+1400); } double speed=0; long add_error=0; void PID_count() { vPID.PreError=vPID.LastError; vPID.LastError=vPID.Error; vPID.Error=(vPID.Setpoint-lx)/10; add_error+=vPID.Error; speed+=(vPID.P*add_error+((vPID.I)*(vPID.Error))+vPID.D*(vPID.Error-2*vPID.LastError+vPID.PreError)); if(speed>1000) speed=1000; if(speed<0) speed=0; } /***************************************************** 函数功能:延时1ms (3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒 ***************************************************/ void delay1ms() { unsigned char i, j; for (i = 0; i<10; i++) for (j = 0; j<33; j++); } void delaynms(unsigned int n) { unsigned int i; for (i = 0; i<n; i++) delay1ms(); } void display_set() // 显示设置 { DisplayListChar(1, 1, s); //显示 DisplayListChar(0, 2, "温"); //显示温度 //写数据 WriteData('H'); WriteData(':'); WriteData(0X30+Temp_H/10); WriteData(0X30+Temp_H%10); WriteData(0xa1); //显示℃ WriteData(0xe6); WriteAddress(5, 2); //写坐标 WriteData('L'); WriteData(':'); WriteData(0X30+Temp_L/10); WriteData(0X30+Temp_L%10); WriteData(0xa1); //显示℃ WriteData(0xe6); DisplayListChar(0, 3, "湿"); //显示 湿度 //写数据 WriteData('H'); WriteData(':'); WriteData(0X30+Hum_H/10); WriteData(0X30+Hum_H%10); WriteData(0xa1); //显示℃ WriteData(0xe6); WriteAddress(5, 3); //写坐标 WriteData('L'); WriteData(':'); WriteData(0X30+Hum_L/10); WriteData(0X30+Hum_L%10); WriteData(0xa1); //显示℃ WriteData(0xe6); /********显示光照强度*****************/ DisplayListChar(0, 4, ly); //显示光照阈值 //写数据 WriteData(':'); WriteData(0X30+light_L/10000); //万 WriteData(0X30+light_L%10000/1000); //千 WriteData(0X30+light_L%1000/100); //百 WriteData(0X30+light_L%100/10); //十 WriteData(0X30+light_L%10); //个 WriteData('L'); WriteData('x'); } void Set() { uchar t=0; //调节设置时的闪烁频率 uchar SetTempFlag=1; if(!K1) { while(!K1); Write_com(0x01); //显示清屏 display_set(); flag=1; FMQ=1; EA=0; } while(flag==1) { if(!K4) { while(!K4); Write_com(0x01); //显示清屏 SetTempFlag = 0; choose=0; //退出设置将选则设置标志位清0 flag=0; EA=1; break; } if(t>65) { display_set(); // 显示设置 } if (!K1) { delaynms(15); if (!K1) { while (!K1); SetTempFlag++; if (SetTempFlag>5) { Write_com(0x01); //显示清屏 SetTempFlag = 0; choose=0; //退出设置将选则设置标志位清0 flag=0; EA=1; break; } } } if (!K2) { delaynms(15); if (!K2) { while (!K2); switch (SetTempFlag) { case 0: break; case 1: Temp_H++; if (Temp_H >= 50) Temp_H = 50; break; case 2: Temp_L++; if (Temp_L>=Temp_H) Temp_L = Temp_H; break; case 3: Hum_H++; if (Hum_H >= 90) Hum_H = 90; break; case 4: Hum_L++; if (Hum_L>=Hum_H) Hum_L = Hum_H; break; case 5: light_L+=10; if (light_L>65524) light_L = 65524; break; } } } if (!K3) { delaynms(15); if (!K3) { while (!K3); switch (SetTempFlag) { case 0: break; case 1: if (Temp_H <= Temp_L) Temp_H = Temp_L; else Temp_H--; break; case 2: if (Temp_L == 0) Temp_L = 0; else Temp_L--; break; case 3: if (Hum_H <= Hum_L) Temp_H = Hum_L; else Hum_H--; break; case 4: if (Hum_L == 0) Temp_L = 0; else Hum_L--; break; case 5: if (light_L == 0) light_L = 0; else light_L--; break; } } } delaynms(7); t++; if (t>=90) t=0; if (t == 0) { switch (SetTempFlag) { case 0: break; case 1: WriteAddress(2, 2); //写坐标 break;//写闪烁地址 case 2: WriteAddress(6, 2); //写坐标 break;//写闪烁地址 case 3: WriteAddress(2, 3); //写坐标 break;//写闪烁地址 case 4: WriteAddress(6, 3); //写坐标 break;//写闪烁地址 case 5: WriteAddress(4, 4); //写坐标 WriteData(':'); WriteData(' '); WriteData(' '); WriteData(' '); break;//写闪烁地址 } WriteData(' '); WriteData(' '); } } } void alarm() { if(U8T_data_H>Temp_H) //如果实际温度大于温度上限 { temp_h_flag=1; } else { temp_h_flag=0; } if(U8T_data_H<Temp_L) //温度低于下限 { temp_l_flag=1; } else { temp_l_flag=0; } if(U8RH_data_H>Hum_H) //湿度高于上限 { hum_h_flag=1; } else { hum_h_flag=0; } if(U8RH_data_H<Hum_L) //湿度低于下限 { hum_l_flag=1; } else { hum_l_flag=0; } if(light_L>lx) //超出报警阈值 { light_l_flag=1; } else { light_l_flag=0; } if((temp_h_flag==1)||(hum_h_flag==1)) { if(close_alarm1==0) FMQ_alarm1=1; } else { close_alarm1=0; FMQ_alarm1=0; } if((temp_l_flag==1)||(hum_l_flag==1)||(light_l_flag==1)) { if(close_alarm2==0) FMQ_alarm2=1; } else { FMQ_alarm2=0; close_alarm2=0; } if(!K4) { while(!K4); if(FMQ_alarm1==1) { close_alarm1=1; FMQ_alarm1=0; } if(FMQ_alarm2==1) { close_alarm2=1; FMQ_alarm2=0; } } if((FMQ_alarm2==1)||(FMQ_alarm1==1)) FMQ=0; else FMQ=1; } void display() { DisplayListChar(0, 1, t); //显示温度 DisplayListChar(0, 2, h); //显示湿度 DisplayListChar(0, 3, l); //显示光照强度 DisplayListChar(0, 4, z); //显示运行状态 /********显示温度******************/ WriteAddress(2, 1); //写坐标 //写数据 WriteData(':'); WriteData(0X30+U8T_data_H/10); WriteData(0X30+U8T_data_H%10); WriteData('.'); WriteData(0X30+U8T_data_L); WriteAddress(5, 1); //写坐标 WriteData(0xa1); //显示℃ WriteData(0xe6); /********显示湿度******************/ WriteAddress(2, 2); //写坐标 //写数据 WriteData(':'); WriteData(0X30+U8RH_data_H/10); WriteData(0X30+U8RH_data_H%10); WriteData('.'); WriteData(0X30+U8RH_data_L); WriteData('%'); //显示℃ /********显示光照强度*****************/ WriteAddress(4, 3); //写坐标 //写数据 WriteData(':'); WriteData(0X30+lx/10000); //万 WriteData(0X30+lx%10000/1000); //千 WriteData(0X30+lx%1000/100); //百 WriteData(0X30+lx%100/10); //十 WriteData(0X30+lx%10); //个 WriteData('l'); //显示℃ WriteData('x'); /********显示状态*****************/ WriteAddress(2, 4); //写坐标 //写数据 WriteData(':'); WriteData('T'); //wen du zhuang tai if(temp_h_flag==1) //chao chu shang xian WriteData(0x18); //xian shi 上箭头 else if(temp_l_flag==1) //chao chu xia xian WriteData(0x19); //xian shi xia箭头 else WriteData('-'); //zheng chang qing kuang xian shi - WriteData(' '); //xian shi kong ge WriteData('H'); //shi du zhuang tai if(hum_h_flag==1) //chao chu shang xian WriteData(0x18); //xian shi 上箭头 else if(hum_l_flag==1) //chao chu xia xian WriteData(0x19); //xian shi xia箭头 else WriteData('-'); //zheng chang qing kuang xian shi - WriteData(' '); WriteData('L'); //guang zhao zhuang tai if(light_l_flag==1) //chao chu xia xian WriteData(0x19); //xian shi xia箭头 else WriteData('-'); WriteData(' '); } uint a[5]={0}; void main() { LCDInit(); //LCM初始化 init_PID(); TMOD=0x21; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1=0xff; TL1=0xff; EA=1; //开放总中断 V=A_D(0); //读取光照强度 V=255-V; a[0]=V; //0 V=A_D(0); //读取光照强度 V=255-V; a[2]=V; //1 V=A_D(0); //读取光照强度 V=255-V; //2 a[2]=V; V=A_D(0); //读取光照强度 V=255-V; //3 a[3]=V; TR1=1; ET1=1; while(1) { TR1=0; RH(); V=A_D(0); //读取光照强度 TR1=1; V=255-V; a[4]=V; V=(a[0]+a[1]+a[2]+a[3]+a[4])/5; a[0]=a[1]; a[1]=a[2]; a[2]=a[3]; a[3]=a[4]; if((V<=150)&&(V!=0)) lx=0.1694*V*V-0.38791*V+77.045; else if(V==0) lx=0; else lx=3.119*V*V-757.19*V+46701; display(); PID_count(); ZKB=(speed/10); if(vPID.Setpoint==0) ZKB=0; Set(); alarm(); //警报判断 if(!K5) { while(!K5); ledflag=~ledflag; if(ledflag==1) led1=1; else led2=1; } } } uint count=0; uint counti=0; long count3=0; /*中断函数*/ void timer1(void) interrupt 3 { static uchar click=0; /*中断次数计数器变量*/ ++click; //count3++; /*if(count3>200000) { count3=0; PID_count(); ZKB=(speed/10); if(vPID.Setpoint==0) ZKB=0; }*/ if(flagi==1) { if(counti<1800) { counti++; } else { flagi=0; counti=0; } } if (click>=100) { click=0; } if (click<ZKB) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ { if(ledflag==0) led1=0; else led2=0; } else { if(ledflag==0) led1=1; else led2=1; } }