A PIC-Based Temperature Alarm

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

Prototype Temperature Alarm 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.

Schematic

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.

Temperature Controller Insides Of The Temperature Controller


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.