/* Fuzzy logic example showing the use of linguistic variables (c) 1995, 2001 Byte Craft Limited Waterloo, Canada N2J 4E4 Walter Banks */ #include <16c74.h> ; // Use the Microchip PIC16c74 #include ; // Use 16C74's AD converter routines #include ; #pragma portrw portb @ 6; // external control port. #define C_const 122 #define F_const 220 #define C_offset -11662 /* -45.5C * 256 */ #define F_offset -12800 /* -50F * 256 */ /* define the control bits that drive the relays */ #define Heat_On PORTB.0 #define AC_On PORTB.1 #define Fan_On PORTB.2 #define Humid_On PORTB.3 #define fifty // powerline frequency #ifdef fifty #define rollover 100 #else #define rollover 120 #endif /* This home environment control system bases its control on the following parameters. OutsideTemp InsideTemp Time InsideHumidity TemperatureSP HumiditySp */ char ticks; // 1/60 sec tics roll over at 120 // 1/50 sec tics roll over at 100 char seconds; // actually two seconds 180 = 6 min // hours; .1 hour 0 .. 240 for a day // The crisp value hours resolves the day into // 6 minute intervals which fits nicely into // a sigle byte. // // CRISP variable hours has the the following // Linguistic definitions. // // day starts at 5:30 am is truly day at 6:30 am and // begins to end at 5:30 pm (17:30) and is no // long day at 6:30PM (18:30) . // // night is not day // // morning starts at 5:00am is morning by 6:00am // begins to end at 8:00am over by 9:00am // // evening starts at 4:00PM (1600) goes to 8:00pm // // nightsb Night set back: The time of the night // that is not evening. // LINGUISTIC hours TYPE char MIN 0 MAX 240 { MEMBER day { 55 , 65 , 175 , 185 } MEMBER night {FUZZY { hours IS NOT day }} MEMBER morning {50, 60 , 80 , 90 } MEMBER evening { 160 ,170 ,190 , 200 } MEMBER nightsb {FUZZY { hours IS night AND hours IS NOT evening }} } void time (void) /* called each 1/60 or (1/50) of a second */ { if (++ticks >= rollover) { ticks = 0; if (++seconds >= 180) { seconds = 0; if (++hours >= 240) { // new day hours = 0; } } } } LINGUISTIC OutsideTemp TYPE char MIN -40 MAX 150 { MEMBER cold { -40, -40, 40, 60 } MEMBER cool { -40, -40, 55, 70 } MEMBER warm { 55 , 68 , 78, 82 } MEMBER hot { 68 , 85, 150, 150 } } LINGUISTIC room TYPE char MIN -40 MAX +150 { MEMBER cold { -40, -40, -8, -5 } MEMBER normal { -3, 0, 3 } MEMBER hot { 0 , 8, 150 , 150 } } CONSEQUENCE heat TYPE char MIN 0 MAX 255 DEFUZZ cg ACTION { Heat_On = (heat >= 128); } { MEMBER OFF { 0 } MEMBER ON { 255 } } CONSEQUENCE ac TYPE char MIN 0 MAX 255 DEFUZZ cg ACTION { AC_On = (ac >= 128); } { MEMBER OFF { 0 } MEMBER ON { 255 } } FUZZY room_control { IF room IS cold THEN ac IS OFF heat IS ON IF room IS normal THEN ac IS OFF heat IS OFF IF room IS hot THEN ac IS ON heat IS OFF IF room IS cold AND hours IS morning THEN heat IS OFF IF room IS cold AND OutsideTemp IS hot THEN heat IS OFF IF room IS hot AND OutsideTemp IS cold THEN ac IS OFF } // DOMtoCRISP // This function takes a Degree of Membership value and // a full scale CRISP value and returns the CRISP // equivalent char DOMtoCRISP(char DOM, char CRISP) { unsigned long result; result = ( DOM * CRISP ) / (F_ONE - F_ZERO); return result; } // convert the reading from an A/D to // the temerature in degres F char convert_temp (char temp) { return ((((long)temp * F_const) + F_offset) >> 8); } char room_temp,SPtemp,SBtemp; void main (void) { SPtemp = 71; // This is the nominal room set point // It can (should) be set interactively // with a keypad and LCD display SBtemp = 3; // Night setback temperature. Init_A2D(); while(1) { /* room_temp is the current room temperature room is the error in the room temperature from the desired setting. The room set point is the thermostat setting less the night setback if needed. The night setback is a linguistic variable that varies between fuzzy zero and fuzzy one. The transistion between day time temperature and night time temperature is linear and smooth at the end of the evening. */ room_temp = convert_temp(ReadAD(0));; room = DOMtoCRISP(hours_nightsb(hours),SBtemp); room = room_temp - SPtemp - room; /* room_control call a fuzzy function that that evaluates all the control statements and then activates two consequences either airconditioning or furnace. */ room_control(); } }