ECE 5760: Final Project (Fall 2010)

PID Controller on FPGA for Temperature Control


Anandram Sundar (as2454)
 Muneeb Akram (ma638)
Chandrashekar Anand (ca325)


The objective of this project was to implement a digital PID controller on an FPGA for a control application. We designed a controller to track and maintain a set point temperature of a water tank with lowest possible overshoot while maintaining maximum possible rise time. Multiple controllers and heaters were used to efficiently control the temperature. We used MATLAB to design our controller and develop a model of our system from experimental data. The heaters were driven using a PWM signal from the FPGA that was amplified using BUZ 73 transistors.

The motivation behind using FPGA to implement a PID controller rather than microcontrollers or DSPs is because it provides a good balance between performance and cost. Using microcontrollers, although they may be cheaper do not provide enough processing power to effectively perform complex calculations in real-time. Digital signal processors can implement complex algorithms quickly but are expensive.


High Level Design

The figure below shows the top-level block diagram of the system. Our controller and water heater are connected in a closed loop configuration where the temperature reading from the sensors are fed back to the controller that adjusts the output to accommodate for the error.


PID Controller

The PID controller was implemented on the FPGA using NIOS. A PID controller provides compensation to an existing system by trying to minimize the error between the desired output and actual output. It does this by adjusting the process inputs. A PID controller consists of three forms of compensation, namely, Proportional, Integral and Derivative.
The advantages of using a PID controller are many fold. Combining the three forms of compensations we are able to stabilize a potentially unstable system, minimize steady state error and increase system speed respectively.

Below is a block diagram of a PID controller:

To implement this on an FPGA, we had to perform the calculations in discrete time. We read the temperatures at regular time intervals and compared them with the set point. The error value was then fed to the controller that responded accordingly to try to eliminate the error.


Water Heating System

Heating a water tank to a desired temperature and maintaining that temperature within strict tolerance levels is difficult. This is largely due to a large overshoot. When a desired temperature is reached, the heater is turned off but continues to dissipate heat to the water tank. This raises the temperature beyond the desired point. There are a number of ways we can deal with this problem. One ways is through the use of a predictive controller. Another option would be to have multiple heat sources and multiple temperature sensors, controlling each heater separately based on the minor adjustments required.

Below is a diagram of our water tank:




In order to design an optimum controller we needed an accurate system model. We developed our model based on experimental data and using MATLAB curve fitting tool. We gave the heaters a step input of 5V and monitored the temperature of water over time. We quickly noticed that our system was too slow and we observed approximately one degree rise in temperature every 4 minutes. This was mainly because of our power supply limitation and inadequate power from the resistive heaters. To worsen the situation our water tank was of a large capacity.
Nonetheless, we took readings for approximately 1 hour and left the system running for another hour and a half in the hope of reaching steady state. Our system still had not reached steady state and therefore we decided to model the system based on whatever data we had already accumulated. We made the assumption that we had enough data to model the system accurately for our operating region.

Below is a plot of our data using excel:

Below is a best fit curve obtained from MATLAB from our experimental data:

Due to the slow dynamics of the system and its inability to reach steady state, we weren’t able to model the system as an exponential function but rather modeled it as a sum of exponentials in the following form:

Plant Model:

G(t) = a*exp(-b*t)+c*exp(-d*t)

G(s) = a/(s+b)+c/(s+d)


a = 2.899, b = 0.00002311, c = -2.219, d = 0.00005388


K(s) = Kp + (Ki/s) + (Kd*s)

where the following values gave the best response,

Kp = 10, Ki = 4, Kd = 2

From our MATLAB simulation we obtained the following specifications:

1. Steady State Error = 0%
2. Percent Overshoot = 0%
3. Phase Margin = 138º




We had the option of doing the PID controller on either hardware or on Nios. We chose to do it on Nios because there weren’t any complex calculations involved and the system had a slow response.

The block diagram of the system we built looks like this:

We present details about how each of these blocks works in this section:

Temperature sensor:
We used two LM-34 temperature sensors. These sensors show a 10 mV increase or decrease for 1° F change in temperature. The two sensors are placed close to the two heaters which are on opposite walls of the water tank. We have assumed that each sensor reads the temperature of the heater that is close to it and the effect of mixing of water is neglected.

Analog to Digital Converter:
We used AD7574 which is an 8 bit ADC. We used this IC in its slow memory mode. In this mode, the Chip Select (CS) and Read (RD) pins are tied together. They are both active low inputs. The IC starts conversion on a high-to-low transition on these pins and the data is available when the BUSY output of the ADC goes high. The conversion is completed by a low-to-high transition on CS and RD pins. We chose to give these signals externally from a signal generator at a frequency of 2.4 Hz. For a time sensitive application, the BUSY output has to be monitored and the data has to be latched when it goes high. However, in our case, the temperature did not change for several seconds and hence we did not poll the BUSY pin.

The ADC has a reference input, VREF, which lets us set the resolution of the converter. The resolution is given by |Vref|/256. The ADC we used could take a minimum Vref of -5 V. hence, it could give a one bit change for every 20 mV or 2°F. So, we would suggest to anyone building a PID controller which takes inputs from an ADC, to make use of an ADC with a lower Vref and also to use a 16 bit digital output which will improve the precision of calculations.
The output of the ADC was fed to the Altera DE II board through the GPIO_0 port. The DE II board recognizes a voltage level of 3.4 V to be high. Hence, we stepped down the output of the ADC using potentiometers before feeding it to the Altera board.

Nios II:
The Nios II performs these functions:

  • Gets the reference temperature from the user
  • Reads temperature input from ADC
  • Computes the actuating quantity using the PID controller equations
  • Outputs the 10 bit value to the TimerSDRAM module which converts it into an equivalent PWM signal.

The Nios II gets the reference temperature from the user from the Nios console when SW[0] on the DE II board is activated. The heater has to heat up to this temperature. The Nios also reads the input from the GPIO port and compares it with the reference temperature. It takes one of the following decisions when both the values are available:

  • If the reference temperature is greater than the tank temperature by 1° F, the actuating quantity has to be determined and the PID calculation is performed.
  • If the reference temperature is lesser than the tank temperature, the output from the Nios is made zero and the system waits for the tank to cool down to the reference temperature.
  • If the tank temperature does not change over time, maintain the output from the Nios. Computation of the actuating quantity is not required.

We used float for computing the output for the PID controller. This gives better precision. We took a 10 bit output value from the Nios and fed it to the TimerSDRAM module.

Generation of PWM signals:
The 10 bit output code is used for generation of PWM signals. The PWM performs the function of Digital to Analog conversion. The 10 bit output value gives a minimum duty cycle of (1/1024). The output from the PWM is used to turn ON and OFF, a MOSFET (BUZ73). The flowchart for generating PWM signals is shown below:

We don’t check for the terminating condition of the counter and simply let it overflow when it reaches 1024.

VGA monitor:
We display the status of the heaters (whether they are ON or OFF) on the VGA monitor. We also had a progress bar which shows the extent to which the heating is complete. We wrote to SRAM and used Prof. Bruce Land’s VGA control module.

Implementation of the progress bar:
We implemented a progress bar which was 80 pixels wide. Start is the first value from the ADC that is stored the instant the PID controller is turned ON. The computation for the progress bar is given as:
((Out – start)/ (ref –start)) * 80
This computation is done on Nios II.

We used a 2 ohm, 20 W resistor as the heating element in our project.

Some of the other components used in the hardware:

We used two BUZ73 MOSFET’s as switching elements. These transistors got their Gate inputs from the PWM signal generated by the Nios. The Source terminal was grounded and the heating element was connected between the Drain and the positive supply rail (+5 V).

Operational amplifiers:
While testing our system we found that the voltage across the resistors needed to be at least 3.5 V for them to heat up. So, we had to step up the output of the Nios to about 9 V. For this, we used an operational amplifier. We used LM-358. We had to account for the slew rate of the operational amplifier and had to considerably reduce the frequency of the PWM signal. We set this to 6 KHz.



Testing and Development:

Since our project had a large external circuitry component. So, we had a lot of testing to do in the early stages.

  • First and foremost, we had to determine the extent to which the resistor was getting heated. Once we did this, we built the model of our tank and tested the response with water in the tank. The presence of water slowed the heating process and we found that for a 1° F rise in temperature, it took up to 4 minutes.
  • We tested our PID controller implementation on the Nios by taking an arbitrary system model and sending the plant response as user inputs.
  • We tested the PWM by observing the output waveform on the oscilloscope.
  • We tested the ADC by giving known analog inputs and observing the digital output on LED’s.




To test the performance of our system, we filled the tank with cold water and gave a desired set point temperature to the FPGA. Due to the slow dynamics of our system we only gave a reference voltage that was two to four degrees higher than the initial temperature. This allowed us to analyze the full performance of our design.
Neglecting the limitations of external hardware such as the power supply and heaters, our controller performed well and as expected. We were able to maintain the temperature of the water tank at a desired set point temperature. We also introduced a disturbance by adding cold water to lower the temperature to see how it responds. The system reacted appropriately and the heaters turned on again to adjust the error.

Below are some links to images of the completed project:

  1. Progress bar with heaters on
  2. Heaters off
  3. PWM waveform 1,2,3
  4. Water Tank
  5. External Circuit 1,2




We were able to successfully complete what we intended to. The heater was able to heat the water to the temperature desired. We were pleased that all the hardware that we had assembled worked quite well.

However, the response from the setup was slower than we expected it to be. This was primarily because of the water in the tank, cooling the heater. This slowed down the response considerably and we could achieve a rise of 1° F in close to three minutes. The main reasons for this were the low power rating of the heater and the size of the tank that we chose.

We would suggest a few other applications to anyone who wishes to work on an FPGA based PID controller in the future. A very interesting and challenging problem would be to build a system that balances an inverted pendulum. Another idea would be to build a system that can keep an object suspended in mid-air by blowing air against it. This would be cooler if the system is synced up with music and the object stays at different heights. This idea was suggested to us by Bruce Land and we found it quite interesting.




We thank Prof. Bruce Land for his ideas and inputs during the course of the project. We wouldn’t have completed this without his help. We also thank him for the hardware parts that we used in this project.
We also thank Analog Devices for the Analog to Digital Converters that they provided us free of cost. We also thank Altera for the DE2 boards.





Verilog and C Files

Circuit Diagrams

Division of Labor

Specific task

Done by

Implementation of PID controller on FPGA


Building the water tank setup


Testing and Integration


Modeling on MATLAB


Implementation of progress bar


Analog Circuitry


Testing the ADC