Download a Free VPN Appliance for your home network!

Dual Thermometer with serial output

by Radu Constantinescu

I think that every 3 months a new thermometer project is published – is clear that to many of them are around….

This one is using a 16F876 PIC, MCP1047A temperature sensor ( X2 ), MCP1541 voltage reference and MCP6022A opamp. The display is a 2 row HD74780 based 2X16 char, SII L1652BIJ2 but any other display based on HD74780 can be used.

The initial purpose of this project was a contest but because it was to common it was replaced with something more special.

Meantime the thermometer is the favorite of my wife and is showing the outside/inside temperature and was working in the last two months….so it can be considered a good design.

The Hardware is quite simple but some important points must be checked in order to keep the noise to a minimum and do not influence the A/D readings. Each IC is using a 0.1UF capacitor mounted as close as possible to the Vcc/GND pins of the IC. The ground circuit should have the shape of a star with a central point. The Vcc circuit should follow the same pattern where possible. Any kind of loops in the power circuit must be avoided.

The temperature sensor used has an analog output, with 500mV at 0C ( zero degree Celsius or centigrade ) and a sensitivity of 10mV/Centigrade. The output of the sensor is filtered in order to eliminate the noise and applied to the A/D inputs of the integrated 10Bits A/D contained in PIC 16F876. As voltage reference a MCP1541 is used . The typical output voltage is 4.096V – this is buffered with a MCP6022 Rail-to-Rail AO and used to power the temperature sensors. Also a resistive divider is used to obtain 2.56V as reference voltage for the A/D. For the 2.56V reference voltage used and 10Bit A/D the temperature in centigrade is simple to compute as T=Reading-200/4.

Two sensors are used - one for Outside temperature and one for Inside temperature. MCP1047A sensor is a small SMD device so it was a little bit difficult to handle it…the solution was to mount the sensor on a small piece of PCB, connect a shielded wire to it and seal everything in a piece of heat shrink tube and some silicon. Like this I have obtained two water proof sensors. For the outside sensor I hare replaced a piece of the shielded cable with three thin wires (30AWG) in order to make this wires pass thru the window.

On pin RC0 a "heart beat" LED is mounted – this will blink in order to confirm that the CPU is executing the main program loop.

Pins RC6 is the serial output – the thermometer will send the temperature readings every second using 9600/N/8/1 format. A MAX232 level converter is necessary in order to feed this info to a RS232 port and any terminal program can be used to display it. Please see the example with HyperTerminal in the picture. The format is:



where FF is the temp reading in Fahrenheit and CC in Celsius.

The circuit has also a ICD connector used to program the PIC CPU in circuit, without removing it each time.

The power supply is simple - a 78L05 regulator and a 9V wall wart + a protection diode.

The circuit was realized on a piece of perfboard and I will attach some pictures showing step by step construction.

The first picture show the "development" version….

Once I have decided to build a more decent version I started with another piece of perfboard and some connectors:

In this stage the CPU/LCD combination could be tested using the "disptest" supplied assembler file. The display connects directly to the PCB using a header connector.

This is a view of the "sandwich" PCB+LCD, the orange wire goes to the sensors, the white connector is the wall wart and the red connector is for the ICD and serial.

The Software is written is assembly language and contain a lot of comments (thermo.asm).

Two directives are used – if simulate is defined the init routine is skipped - this is useful in order to run the code step by step in MPLAB and debug the conversion routines.

If debug is defined then the display will show the A/D readings beside the converted values – this is useful to check the sensors and compute the calibration values.

The startup code initialize the used ports an read the two correction values from EEPROM. These values can be used to correct the sensor "shift" – once the thermometer is working both sensors can be placed in the same room and some correction values <>0 programmed in the EEPROM in order to get the same readings from both sensors.

The main loop read the sensors, convert the values in Fahrenheit and Centigrade, write the values to the LCD and the serial port, flip the LED and the repeat itself.

The A/D is used in sleep mode to minimize the conversion noise and make the last bit stable, then the temperature in Fahrenheit is computed as TF=Reading*0.45-58 in order to use only positive numbers in the multiplication routine and the temperature in Centigrade is computed as TC=Reading-200/4.








; Dual Thermometer

; (c) 2002 Radu Constantinescu


; PIC16F876/20Mhz

; PORTA0 = Out A/D Input

; PORTA1 = In A/D Input

; PORTA3 = Vref 2.56V

; PORTC0 = Led Exit/HeartBeat

; PORTC6 = Serial TX OUT


; Uses TC1047A temperature sensors. 10mV/C, 20C=280mV

; In order to calibrate the sensors use COR1H:L, COR2H:L EEPROM Values


; LCD 2*16 display / SII L1652BIJ2 with HD74780A00

; <OUT:> (Temp in Fahrenheit)F | (Temp in Centigrade)C | <A/D converter value>

; <IN :> (Temp in Fahrenheit)F | (Temp in Centigrade)C | <A/D converter value>








; Start 10/30/02 / END 12/28/02




#include <>

; if debug then display A/D Converter Value / Hide In/out indicators

; #define debug 1

; if simulate then skip init routines and use test values

; #define simulate 1



;User Variables




temp1l: 1 ; temp 1 lo

temp1h: 1 ; temp 1 hi

temp1C: 1 ; temp 1 Celsius

temp1F0:1 ; temp 1 Fahrenheit lo

temp1F1:1 ; temp 1 Fahrenheit hi

tcor1l: 1 ; temp correction1 lo

tcor1h: 1 ; temp correction1 hi

temp2l: 1 ; temp 2 lo

temp2h: 1 ; temp 2 hi

temp2C: 1 ; temp 2 Celsius

temp2F0:1 ; temp 2 Fahrenheit lo

temp2F1:1 ; temp 2 Fahrenheit hi

tcor2l: 1 ; temp correction2 lo

tcor2h: 1 ; temp correction2 lo