Abstract
Presented is a simple temperature alarm which uses a PIC16C84 microcontroller
and a 2-line LCD display. The alarm displays current temperature in both Celsius
and Fahrenheit degrees and features a 3-key keypad which allows the user to set independent
high and low termperature alarm points. The alarm also records the minimum
and maximum temperatures encountered.
System Specifications:
The unit is designed to function (user configurable) either as a temperature
alarm or a thermostat - the only difference being that with an alarm an intermittent
beep is produced when a limit is exceeded.
The system samples temperature readings continually and displays the current temperature
on the LCD display in both Celsius and Fahrenheit degrees. The LCD shall also
display the current configuration and user parameters. User parameters include
the high termperature limit, low temperature limit, and alarm mode (whether the
beeper is on or off). As well, the system shall keep track of the maximum and
minimum temperatures reached and display them, too, on the LCD.
The user shall have the option of setting both the high termperature limit and the
low temperature limit. These limits shall be displayed in both F and C degrees
and shall be set using two pushbuttons labelled UP (+) and DOWN (-). As well as
limits, the user shall be able to clear the Min/Max temperatures and set the
alarm mode (whether the beeper is audible or not). A red alarm LED shall light
regardless of beeper status when a limit is exceeded.
All parameters including limits, min/max temperatures, and alarm (on/off) status
shall be stored in non-volatile memory and shall be reloaded upon power-up.
Hardware
The basic system consists of a PIC16C84 MCU, a two-line 16-character LCD display,
three pushbuttons to set user-configurable parameters, and an ADC0831 serial
analog-to-digital converter. The LCD is an intelligent unit which displays
ASCII characters. It may be used in eight-bit mode but this requires ten I/O lines
on the MCU (eight for data plus register select and enable). A less-demanding
four-bit interface was chosen which requires six I/O lines (four lines for data
plus register select and enable). As well, to conserve I/O lines on the MCU the
three pushbuttons were scanned using three of the four data lines already used for
the LCD (See the schematic for details).
The ADC0831 uses a three-line SPI/Microwire interface. It is synchronous serial
meaning that the MCU generates the clock and the ADC will send back the appropriate
data bit (a logic high or low). This serial bitstream must be assembled by the
MCU into a byte.
The thermistor used is a Philips 2322-640-63103 NTC Thermistor with an R/r ratio
of 9.0 and a nominal resistance of 10K@25C. Radio Shack sells a similar unit which
may be used. The thermistor is wired as one leg in a voltage divider along with
a fixed 10K resistor. The voltage output of the divider is proportional to ambient
temperature (although it is not a linear relationship which creates some problems
for the firmware when converting to real temperatures).
The MCU is also used to drive an alarm LED (which may also be an opto-driver block
if the alarm were used as a thermostat) as well as a piezo beeper to warn of
over/under temperature conditions.
Download the complete schematic in DXF format
Please do not ask if I can convert these drawings into some other format. I use ACAD which is limited to it's own DWG format as well as a more universal DXF format. Many decent graphics packages (like PaintShop) will read DXF files.
Firmware
The first function performed is reading the ADC0831. This ADC uses a standard 3-wire SPI/Microwire protocol. Since the 16C84 device used for the temperature alarm lacks a synchronous UART, bits are clocked-into the PIC individually and shifted until a byte is formed.
Next, the ADC reading (a binary number) is converted into a temperature reading
(in degrees C). Since the thermistor has a non-linear resistance to temperature
relationship it was decided that a lookup table would be the best way to accomplish
this conversion. The lookup table has 248 entries corresponding to temperatures
between -50C and +125C. Numerically, numbers are not stored as true two's
complement but rather a whole 7-bit number (range 0 to 127) with the MSB bit being
set to signify a negative number. This format was chosen because originally the
system only operated in units of degrees C and it was convenient to simply display
a negative sign if the upper-bit was set then clear that bit and continue with binary
to BCD conversion.
In order to display the temperature in Fahrenheit degrees as well as celsius it
was decided to mathematically convert degrees C to degrees F instead of using a
second table. The standard formula for conversion is:
Degrees_F = 9/5 * Degrees_C + 32
This does not lend itself well to binary, fixed-point arithmetic so an alternate
formula was chosen as follows:
Degrees_F = 29/16 * Degrees_C + 32
The multiplication was accomplished by a standard unsigned 8*8 multiply routine
(from Microchip's application note AN544)
which results in a 16-bit number stored across two registers. The divide was
accomplished by simply shifting bits to the right four times in a simple loop as
follows:
;Divide by 16 (29/16 is almost = 9/5)
movlw 4
movwf count
NextShift
bcf STATUS,C
rrf H_Byte,f
rrf L_Byte,f
decfsz count,f
goto NextShift
This simple choice made the conversion to Fahrenheit degrees an easy task. Both reagings are displayed by converting the binary number into BCD digits using the standard B2_BCD routine (from Microchip's application note AN544) and adding 0x30 to make each BCD digit an ASCII character suitable for upload to the LCD.
Other significant portions of the code include a menu system for allowing the user to set the High Alarm Limit, Low Alarm Limit, Clear the Min/Max readings, and Turn the beeper on or off. Each of these parameters is stored in the on-chip EEPROM allowing the system to be restored to desired state after power failure.
Download Version 1.0 Code in MPASM format. This
is a prototype version which displays temperature in degrees C only. It
is an early project of mine, is by no means 'clean' and should not be taken
as an example of 'good' programming practice.
Download Version 2.1 Code in MPASM format. This is
a much more 'finished' version of the code and includes all the 'bells and whistles'.
Download Version 2.1 HEX File as compiled on an older version of MPASM.
NOTE: The code was written for an OLD version of MPASM and may require
modifications in order to assemble on a newer version. I will NOT be updating this in the near future. Please do not ask me to update this code for a particular assembler.
System Performance and Usage:
A prototype system was constructed earlier which features display in degrees C
only. It has operated for over one year successfully under a variety of operating
conditions. The upgrade was recently put into operation and has thus far been
correctly functioning.
In normal operation the top line of the LCD displays the current temperature in
both C and F degrees (e.g. 'TEMP = 20C/68F'). Messages on the lower line of the
LCD cycle every two seconds between the Minimum temp (e.g. 'Min T = 0C/32F'),
Maximum temp (e.g. 'Max T = 28C/82F'), the user-programmed High temperature
limit (e.g. 'Hi Lim = 1C/33F'), and the user-programmed low temperature limit
(e.g. 'Lo Lim = 30C/86F). If the beeper alarm is disabled a fifth message also appears in
the cycle 'Alarm Disabled'.
When the user desires to change a parameter the 'SET' button is pressed at
which point the system enters a mode to allow the user to change each parameter.
The high limit is set first. The top line of the LCD displays the message
'Set High Limit' and the lower line the current limit in degrees C and F. By
pressing the UP and DOWN keys the limits are changed as displayed on the LCD.
When the change is done and the value is acceptable the SET key is pressed
once again to cycle to the next parameter, the low limit, which is changed in a similar
manner. The third option to be set is whether to clear the min and max temperatures
in the system. The message 'Press + To Clr' reminds the user. If no clear is
desired, the SET key is pressed again. Finally the user has the option to turn the
beeper alarm on or off by pressing the UP(+) key to toggle it on or off. When all
changes are complete the SET key is pressed, the system updates the parameters
in the on-chip EEPROM and the system returns to displayind the current temperature
and parameters.
When using this device as a thermostat, the alarm is disabled via the menu function. The red LED is still active though lighting when a limit is exceeded. If the thermostat is used to control an AC load the output which normally drived the red LED is also used to drive an opto-isolated solid state relay (SSR) which switches AC current to the load. The photos below show the final version of the temperature alarm packaged with an internal power supply and an SSR. This unit is currently in use to regulate the temperature of a wine-making carboy which muct be kept at 22C while fermenting.

I get a large volume of mail on various projects. These are presented for experimental purposes only and I will not make modifications to the code nor provide lessons in microcontroller programming.
Professor Mark Csele's Home Page
Projects Page
E-Mail the Author