1. Abstract
2. Temperature/Light System for Fuzzy Controller
3. Fuzzy Controller Design
4. Implementation
4.1. Project Requirements
4.2. Power Subsystem
4.3. Software
4.3.1. Subroutines and Functions
4.3.2. Main Program
4.3.3 The Disaster
4.4. Interfacing
4.4.1. Input / Output Buffering
4.4.2. Signal Conditioning
5. Summary
6. Appendix
6.1. Fide Code
6.2. Main Program
6.3 C Code for Fuzzy Controller
With a climate control system it is difficult to determine the precise relationship of the many inputs and outputs. On the other hand, the rules of control do not appear complex to the human mind. If you want to increase the temperature, simply increase the power supplied to the heater. One of the major advantages of fuzzy logic is its ability to handle such situations. Thus for our project, we chose to apply fuzzy logic in a temperature control system.
Our climate control system is composed of two plywood boxes. The
boxes are open on one side. One box contains the heater element,
fan, and sensors. The other box contains the light bulb. The boxes
were then joined on their open sides to form a temperature and
light controlled environment. See Figure 1 below.

The keys to inspiration in the design of fuzzy logic rules for this project, have been to imagine we are the controller and ask ourselves, "What would we do?" We imagined we wanted to heat and cool a box as rapidly as possible with minimum overshoot, undershoot and oscillation for a given target temperature. To accomplish this we could adjust a dial on a heater and turn a fan on and off. Turning the dial on the heater adjusted the heater output up and down in temperature. The dial was not marked with temperature settings. This last fact is very important. We chose to look at the problem this way because we did not know the exact relationship of heater input current to box temperature as a function of time. This exercise of imagination lead to the following rules. Below, let DT be target temperature minus actual temperature, DTdt be the rate of change of temperature with respect to time, and DH be the amount of adjustment to the heater.
In TBL 1 the basic idea is as follows. If DT is LG and DTdt is SM then DH is TWO. The other rules are similarly read. The greater DT, the greater DH; hence, the cell values increase from right to left. When the desired temperature is much hotter than it is now, the heater must be turned up allot. The less DTdt, the greater DH; hence, the cell values increase from top to bottom. When the temperature is not changing and we wish to heat up the box, turn the heater up. Taking the product results in TBL 1.
So, we had the fuzzy rules. What we had to do next was relate the fuzzy rules to the crisp world. First, we tackled the fuzzification; that is, relate crisp values such as thirty-seven degrees to the labels such as LG. The degree to which one believes that thirty-seven degrees is large, may be quantified as a value between zero and one. For example, I do not believe thirty-seven degrees truly large, but it more than medium. So I could believe that thirty-seven degrees is seventy-percent , or 0.7 LG. The function that takes a crisp value and determines the degree of truth for a particular label, is called the membership function for that label. This is what we developed next.
The fuzzy logic tutorial gave us some rules for membership function (MFN) design.
We used the above rules to perform a cursory mathematical analysis. We assumed the MFN's were triangular as in Figure 2 above. We assumed the maximums were fixed. We then developed equations for the performance indices, Overlap Ratio and Overlap Robustness as functions of L and U. In order to have performance indices as large as possible L and U are best placed under the maximums of the adjacent MFN. This placement results in an Overlap Ratio of one-third and Overlap Robustness of one-half. So the method we used for developing the MFN's was first to decide where the center of the label was in the crisp domain, then extend the bottom corners of the triangle to almost underneath the maximums of the adjacent MFN's. The outer MFN's outer limbs do not go back to zero but remain at one from the maximum outward towards the outer limits.
We chose to develop the fuzzy logic in units of A/D output units. This has the advantage that no matter what the exact ranges were for temperature, the conditioning circuitry would be so designed that the A/D output range would always be the same. So, the DT and DTdt range is always from -128 to 127. We then chose the label maximums as follows.
Finally, to complete the initial fuzzy logic design we needed relate the fuzzy results, DH to the crisp world. To do this we decided to use singleton functions for MFN's for the labels N_SIX, N_FIVE, ..., FIVE, SIX. A singleton function is zero everywhere except at one value. The values where each fuzzy output label was not zero is as follows.
To understand how this fuzzy logic system works, lets run through
a simple example. Assume the temperature in the box is at steady
state. So DTdt is zero. So, Dtdt is NEGL with value 1. All other
values for all other labels of Dtdt are zero. Further, assume
the user requests a 12F increase. If we decide to make 127 correspond
to 50F, then 12F corresponds to 32. 32 is in the SM to MD region
of DT. In fact, SM for DT is approximately 0.2258 and MD for DT
is about 0.8065.
For each cell, take the minimum of its row and column. This results in all cells being zero except for two.
So,
The new heater setting is the old heater setting plus DH. So the
heater is adjusted up by 6.9036. Figure 3 below shows a graph
of DH as a function of DTdt and DT.

Simulation is one part of this project which remains to be completed. We initially began using the FIDE (Fuzzy Inference Development Environment) to simulate but found it to be too clumsy. We had to write so many files in C, that we decided to do the entire simulation in C. We did use FIDE to encode our rules into C for inclusion in the main controller program. There were two main simulations planned. First, requesting a temperature increase. Second, a temperature decrease. For these simulations, we would assume the temperature equations for the light and the heater are of the form
The fan would have the following effect.
The fan would be much smaller than the other 's. We would also
assume that the heater temperature was proportional to the square
of the heater setting and the resultant box temperature would
be a weighted average of the temperature inputs which were on
at the time (the fan, the heater, and the light).
Before starting the implementation, a few key questions had to
be answered in order to avoid dead-ends later on. A few of the
questions were:
Once these questions are answered the design can begin.
In order to design the software/interfacing, we decided that the
final system would have the following properties:
Out of these properties we derived the number and type of inputs
and outputs necessary to accomplish the goals.
Inputs:
Outputs:
For the inputs, first, we all agreed that temperature readings had to be analog. This enabled us to distinguish various temperatures. Two temperature readings are needed, one inside and one outside the box. Since the box does not have any cooling element other than the fan, the desired temperature is bounded by the room temperature and this must be available to distinguish unrealistic requests. The light sensor input had to be analog, because we decided to have several light levels.
The fan output was chosen to be digital to allow fast cooling,
and both the heater and the light were chosen to be analog in
order to accommodate the various levels and the degree of correction
to the current state of the box. See Figure 4 below.
The 68HC11 Microcontroller has many advantages as a controller such as on board 8-channel analog-to-digital converter, two 8-bit digital output ports, our familiarity with its operation and flexible instruction set. However, its main drawback is the lack of memory. We knew that the 68HC11 could implement simple controllers, but in order to implement fuzzy logic and control, more memory was needed. Since no versions of the microcontroller with more memory were available, we ruled out the possibility of using it as our controller.
The option we chose to pursue was to design and implement the
controller and interfacing using and IBM-PC compatible computer.
When equipped with Digital-to-Analog (DAC), Analog-to-Digital
(ADC), and Digital-to-Digital (DTD) interface cards it satisfied
all input/output needs.
In order to provide control of the temperature and light in the box it was necessary to control the power going to the light bulb, the heater coil, and the fan. For the control of the fan, we decided that only two states were necessary, on and off. This was accomplished using a BJT as a switch controlled by a digital output of the computer.
The control of the heater and light bulb proved to be much more complex. AC power control is something that none us had previous experience with. After doing some research on different methods of controlling AC power it became clear that a triac should be used for this task. A triac can be used for switching current, both AC and DC. After it is "turned on" or triggered with a gate current it will conduct in either direction. It will stop conducting, however, any time the voltage across it drops to zero. With DC systems this means that if you ever want to turn it off (a common requirement for a switch) you have to use a circuit, usually a RC network, which will force the voltage to zero at the desired time.
With AC systems, however, the operation of the triac results in it remaining on for, at most, one-half of a power cycle. Therefore if you want to provide continuos power the triac must be triggered at twice the frequency of the input voltage, which is 60 Hz in our case. To complicate matters the trigger signal must be precisely synchronized with the zero-crossing points of the input voltage.
By using a triac it is easy to vary the power being transmitted to the AC load. This is accomplished by delaying the triggering of the triac by from 0 to 8.3 milliseconds (one-half cycle at 60 Hz). This results in a power delivery of 100% to 0% respectively. This delay can be generated in conjunction with the zero-crossing trigger circuit.
We attempted to build a trigger circuit as found in the Motorola
Thyristor Device Data book. This circuit is shown in Figure
5. The circuit allows for the varying of the time delay of the
trigger signal by changing the value of potentiometer R2 which
changes the time constant of the RC network. This delays the activation
of the unijunction transistor Q1 which provides the trigger signal
through the transformer T to the gate of the triac Q2. This circuit
should be able to provide complete control of a resistive load
of up to 800 watts. It was necessary to change the value of the
Capacitor in the RC network from 0.1 F to 0.05 F. This full-wave
circuit is used to control the power going to the light bulb.

We decided to build a simpler circuit which would provide only
half-wave control and thereby only be able to supply a maximum
of 50% power. This reduced power capability proved to be beneficial
when using the heater. This is because the heater could easily
overheat the box used to contain our system when operated at full
power. The resulting heater control circuit is shown in Figure
6. In order to allow the computer to control the amount of power
to apply to the load, we had to be able to interface a DC voltage
input to the circuit. This was accomplished by replacing the pot
R2 in the Figure 6 with a simple photocell (light dependent resistor).
An LED was then placed with the photocell in a closed tube, thereby
creating a voltage controlled resistance. This provides for full
range control of the circuit using a varying input voltage. The
DAC on the computer was used to drive the LED. This LED/photocell
pair creates a somewhat nonlinear response from the heater control.
Due to the nature of our fuzzy logic software these nonlinearities
should be handled without difficulty.
To facilitate the coding and debugging of our software, certain
functions that would be commonly used were written as subroutines
and functions. This simplifies the code, since Qbasic keeps the
main code and the code from the subroutines and functions separate
(when saving the program, the main code, subroutines and functions
are saved in one file). The main difference between subroutines
and functions is that a function always returns a value whereas
the subroutine does not. This is relative since variables can
be declared as COMMON SHARED where the main program, all subroutines
and functions can read and/or modify them.
This subroutine is very simple and it is used to control the sampling
rate and delays. It is a FOR...NEXT loop adjusted to last one
second. Qbasic has a timer trap and subroutine that can be used
for timing purposes, but the compiler did not recognize the commands
even when the example code from the help files was executed.
In order for the ADC and DTD boards to work correctly, they must
be initialized. The code for this subroutine was extracted from
the manufacturer's calibration program. This is where the operation
mode (Unipolar/Bipolar, Vmax=5/Vmax=10) is set.
This function receives the channel number to be read as an integer,
starts the conversion, waits for the result, and converts the
reading to bipolar value (this is set through a jumper on the
ADC card. See manufacturer's manual for more details).
There are two WriteChannel subroutines: WriteChannel0 and WriteChannel1. Since there are only two digital to analog output channels, we chose to write two separate subroutines. If there were more output channels, an implementation similar to the ReadAnalog would be more suitable.
The output is done by converting the desired value into two 8-bit
numbers, Hibyte and Lowbyte. These two numbers are sent to the
appropriate addresses using the OUT command, which accepts two
parameters: an address and a value.
The digital-to-digital card has three 8-bit ports called A, B,
and C that can be configured as either input or output. All 8-bits
of each port have the same direction, i.e. individual bits cannot
be configured as input or output. The fan is controlled with this
subroutine. Since we chose to implement it as either on or off,
the least significant bit (LSB) of port A was chosen as the control
signal for the fan. Writing an even number to port A turns the
fan OFF (LSB = 0)and writing an odd number to port A turns it
ON (LSB = 1). The other seven digital signals have no functionality
in this implementation.
This subroutine was provided by the manufacturer and it can be loaded by Qbasic at startup with the /l c:\ad08\cio8 option. The following batch file (q.bat) was created to automatically load the library at startup:
qb /l c:\ad08\cio8 %1 %2 %3
where:
qb - Qbasic
/l c:\ad08\cio8 - Loads manufacturer's library
%1 %2 %3 - Passes the arguments Qb
so, by typing:
q fuzzy.bas
it will actually execute:
qb /l c:\ad08\cio8 fuzzy.bas
and load the necessary library
This function was created by Fide 2.0 in C and it applies fuzzy logic to control the heater. We compiled the function using TurboC into an object file. This file will be later linked to our Qbasic program to create a stand alone executable.
The main purpose of this subroutine is to track the changes in
input and output. There are six UpdateWindow functions that are
independent of each other and have self-adjusting range. When
the data exceeds the current range the sample will be displayed
at the maximum value in red, and after a fixed number of "overflows"
the range is adjusted to accommodate the new range. If the largest
data value is below a certain threshold, the range is scaled so
that the user can better visualize the data. Each window can have
its own scale and can be updated independent of each other.
At first we tried to use Qbasic's TIMER function to control the
sampling rate, but for some unknown reason, Qbasic would not recognize
it as explained in the Delay Function mentioned earlier. Therefore,
all timing was using the Delay routine, which uses a FOR...NEXT
loop to realize the necessary delay.
Unfortunately, we were unable to get the Qbasic main program to interface properly with the fuzzy routine which was written in C. We were unsuccessful in our attempt to link the C object code. When we attempted to use the C function in Qbasic the compiler complained that the subroutine was undefined. Time did not permit us to track down the source of this complaint. Therefore, we implemented a simple proportional control algorithm within the main Qbasic program.
The Analog-to-Digital converter card provides eight multiplexed analog input channels and three 8-bit input/output digital ports. The Digital-to-Analog converter card provides two digital-to-analog outputs. These cards can be easily interfaced with Qbasic because it resides in the address space &H300 and &H330. All ports have addresses in the I/O space and input/output is accomplished through statements that write to these addresses.
It is unfortunate, however, that analog-to-digital cards proved
to be unreliable when reading an input voltage. There was a variation
of 5% that were sometimes as high as 30%. Even when two channels
were tied to the same input voltage, the readings were rarely
the same. We also noticed that one channel voltage has an effect
on the others especially when the sampling rate increases.
All input and output to and from the boards were buffered to isolate
both systems. Operational Amplifiers (OpAmps) with unity gain
were employed since the sensors have their own conditioning circuitry.
Since the operating range of the temperature sensor far exceeded our required range, only a portion of the range was used. This resulted in that the lowest temperature would correspond to 1.74 volts and the highest temperature would correspond to 2.74 volts. The conditioning circuitry adds a negative bias and amplifies the signal by a factor of five. That way, the lowest temperature for our range would correspond to 0 volts and the highest to 5 volts.
All temperature sensor signal conditioning was done with OpAmps and potentiometers to account for component value deviations and to make calibration easier.
We were surprised by how quickly the system reacted to requests for temperature change. The temperature could be changed by 25 degrees Fahrenheit in less than 60 seconds. Of course the thermal mass of our system is very small. The circuitry turned out to be more complicated and time consuming than we originally bargained for. In fact, the majority of our time was spent on the circuits, not on the fuzzy logic control.
In addition to this, we found that the ADC board installed in PC was not up to our performance expectations. The converted values from a steady input voltage fluctuated by approximately 30%. We were able to partially compensate for this by including an averaging routine in the program, thereby reducing the fluctuations to less than 5%. For better protection for future students, we would recommend that the circuit breakers in the boxes be upgraded to ones which will actually trip before the whole building loses power. It is too bad Fide does not create Qbasic code. Because of this, it would be better to use C to implement the entire control system.
If time had permitted we would have liked to have tried a few things: