A m -Controller Based Thermostat

A Final Project Report for Professor Land's
Spring 99 EE 476

Link to this document with resources in .zip format


The goal of our final project was to design a thermostat using an Atmel AT90S8535 microcontroller. The thermostat was to compute the current temperature once per second and then send an on/off signal to a heating device which would then regulate the temperature to a desired target temperature. In addition, the thermostat was required to keep a time of day clock, as well as record the maximum and minimum temperature values that have occurred.


We accomplished our goal by using an analog thermistor-based temperature sensitive circuit whose output voltage was inversely proportional to the temperature of the system. In order for the microcontroller to obtain the current temperature, the thermistor voltage was input to the ADC of the 8535 and then converted to a temperature using a simple linear equation involving fixed point mathematics.

In addition, the thermostat also required the use of both an LCD and a keyboard for the purpose of user interaction. Specifically, the LCD performed the following display functions:

  1. display the current temperature
  2. display the target temperature
  3. display the min and max temperatures
  4. display the time of day
  5. displaying keyboard input for verification
The keyboard was used for:
  1. setting the target temperature
  2. setting the time of day
  3. selecting the view min/max mode
  4. clearing the min/max values
As you can see, this project combined many if not all of the concepts taught over the course of the semester. These include timing, use of a keyboard (including debouncing it), use of an LCD, fixed point mathematics, analog circuit design and analog-to-digital conversion.

Thermistor Calibration

The first step in creating a thermistor based temperature controller is the calibration of the thermistor, that is figuring out how the amount of voltage drop across the thermistor corresponds to its temperature. To come up with this data we used the calibration setup circuit shown in Figure 1.

Figure 1. Thermistor Calibration Setup

We then heated the thermistor up from 30 to 90 degrees Celsius (since this setup did not have a safe method for cooling the thermistor to down below ambient temperature) and recorded both the voltage across the thermistor and its temperature. These values are plotted in Figure 2. We accurately knew the temperature of the thermistor because our calibration setup included a thermometer which was thermally coupled to the thermistor.  Find our experimental data in Appendex 1.

One complication which arose in this part of the project was that because the thermistor is not a perfect device per se, it requires on the order of ten or so seconds for its resistance to accurately respond to a change in temperature. Because of this effect, there was a thermal lag which existed between the thermistor and the thermometer used to know its temperature. Nonetheless, we found that the way to minimize this source of error was to take calibration data both during a heat up cycle a cool down cycle. This is effective in minimizing this source of error because the thermal lag is effectively canceled out by the fact that during the heat up cycle there is a positive thermal gradient between the thermometer and the thermistor while during the cool down cycle there is a negative thermal gradient.

Therefore we were able to accurately obtain values correlating the voltage drop across the thermistor to the thermistor’s temperature. We then converted these analog voltages (Vread) to 10-bit binary values such as would appear at the output of the ADC using the following equation:

(10-bit ADC value) = (Vread/Aref)*2^10 (1)

For a reference we use Aref = 4.5V. Appendix 1 shows how these 10-bit ADC values correspond to the temperature of the thermistor (in Celsius).

The Code

The code used in implementing a thermostat included many separate routines from timing to analog-to-digital conversion. A brief description of each follows.

Timing: any useful thermostat is programmable and at the very minimum should accept a target temperature. Optionally, it could apply this target temperature for a specified time interval (for example, as in a toaster), or it could have several target temperatures which change during the course of the day (as in a building thermostat). Since this requires accurate, programmable timing, a useful and practical step is to include a clock display on the LCD. We used Timer1 with a clock division of 64, a Compare/MatchA value of 62,500, and the Clear Timer1 Counter flag set, to yield precise timing intervals of 1 second. After implementing our conversion routines, we are able use this to accurately sample temperatures at one second intervals.

Recording: the thermostat was also desired to keep minimum and maximum temperatures. This was a simple comparison routine which looked at the current min and max temperatures in memory and replaced them if the new temperature exceeded either of the current min or max. We also included a button option which allowed us to reset the min and max temperatures at any time.

Control: In order to turn on or turn off a heater, a control segment was coded which applied either a logical 1 or 0 to PortB0 depending on whether the current temperature was above or below the user input target temperature. Because the microcontroller was not capable of driving the power transistor which was necessary for the application of running a heater, we used an LED to indicate the status of PortB0. If given another fifteen minutes we could have used two transistors in a Darlington configuration to increase the current gain of the transistor switch and in this manner control the heater.

Analog-to-Digital Conversion: Using the one second time base described above, we triggered the ADC (in single step mode). The 8535’s straightforward conversion routine converted the voltage at its input to a 10-bit binary value using equation 1 above. The temperature was then calculated using the obtained ADC value to a value in degrees celsius using equation 2 below. This value was then used in the record and control routines.

Temperature(C) = -0.1143x(10-bit ADC value) + 129 (2)
Display routines: Display routines were also triggered once every second in one of two states: the primary state and the display hi/lo temperature mode. The 16-character LCD display has enough room to output two temperatures and the time, with room to spare as follows:

48->59C P0 16:46      (LCD 1)

Here you see the current temperature heading to the target temperature (in Celsius), an extra indicator (P0) which will be later explained, and then the current time. The colon blinks at a rate of once per second- on for one second, off for the next.

In Hi/Lo Display mode, this LCD is formatted as follows:

22L 48H P0 16 46      (LCD2)

This indicates a low of 22 degrees and a high equal to our current temperature (48 degrees from LCD1 above). The extra indicator ‘P0’ is an optional advanced feature that indicates the current programmed setting which is running.

Two additional states also exist in our basic thermostat design, one each to set the clock and the other to set the target temperature. These routines are straightforward using a two digit entry and echo routine for input. The clock uses this routine twice, once for the hours and once for the minutes (the seconds are reset to zero when the time is set).

The code is designed for an Atmel ATS908535 Microcontroller, an 8-bit 32-register RISC microcontroller with A/D converter.  Find source code here.


Our goal of implementing a thermostat using an Atmel AT90S8535 microcontroller was successfully achieved. The implementation included pretty much every aspect of the course described previously as well as including some research outside of the scope of this course. However because we were forced to change projects with only two and a half weeks left until demo (due to the limitations of these microcontrollers- there were not enough ports and memory for our original choice of a project), we were not able to implement all of the options (such as programmable by time of day) that we had hoped to include. Nonetheless the project was a great success and was demoed on 5/3/99 without any hitches.

Stephen Shannon
Jason Pettiss
May 3rd, 1999