PIC Projects

Digital thermometer with analog temp sensor

In this project we build a living room digital thermometer that can measure temperatures in the range 0 - 50°C (32 - 124°F). The scale (Celsius of Fahrenheit is toggled by a button). The temperature is displayed with a 0.5°C resolution on a 4-digit LED. In the Fahrenheit mode the resolution is 1°F.

Schematic Temp in °C Temp in °F

The Math

The temp sensor I used is LM60, which provides a voltage at its output that is linearly depending on the temperature in the range -40°C - 120°C. The voltage in millivolts is the following function of the temperature

V(mV) = 424 + 6.25·T

We, however, are given a voltage to be converted into temp. Inverting the above equation results in

T = 4·(V - 424) / 25

For our target temp range [0 - 52°C] the sensor output voltage is in the range [424mV - 749mV]. This voltage needs to be converted into a digital representation for further processing. For this purpose we use a built-in DAC into PIC16F684 with a reference voltage of 5V. Hence, we need to convert the range of voltages [424 - 749mV] into [0 - 5000mV]. If we denote by Y the voltage at the input of DAC, the formula becomes

Y(mV) = (V(mV) - 424)· 5000 / 325

Although PIC's DAC provides a 10-bit resolution, we ignore its two lowest digits to get rid of digital noise. Since there are 255 voltage levels distinguished by DAC, its reading Z is related to Y as follows

Y = 5000·Z / 255

From the last two equations we derive

5000·Z / 255 = (V - 424)· 5000 / 325

Solving it for V provides

V = 325·Z / 255 + 424

Finally, substituting this V into the second equation gives the following dependency between the DAC reading Z and the temp T

T = 0.2·Z

This is a really nice equation because it can be rewritten as 10·T = 2·V. In other words, if we are going to measure temp with one decimal digit accuracy, then multiplying T by 10 will result in an integer. It follows from the equation that this integer value is twice the DAC reading, which can be easily computed in PIC by using the left shift operation.

Analog part

In order to convert the voltage range [424mV - 749mV] into the range [0 - 5000mV] from where the digital processing starts, we should use analog circuits. The conversion is established by two op amps. The first one just inverts the voltage V coming out of the sensor, so its output is -V. The second op amp implements the conversion formula Y(mV) = (V - 424)· 5000 / 325 = V· 5000 / 325 - 424· 5000 / 325. The first term in this equation is implemented by choosing the ratio R3 / R1 (see schematics) to be 5000 / 325. The values R1 = 3K3 and R3 = 51K has approximately the required ratio. The second term in the equation is implemented by R2 and R3. Since R2 is attached to +5V, its resistance satisfies the equation R3· 5000(mV) / R2 = 424· 5000 / 325, from where R2 = 39K follows.

Using op amps requires to have a bipolar voltage on board. This voltage must exceed 5V in order the op amp could output the fill 0 - 5V range of voltages. For this purpose the circuit is powered from a +7.5V supply, while the negative -7.5V voltage is generated by a DC/DC converter on TC7660. All the other ICs and the LED display are powered from a 5V stabilizer on 7805.

Digital part

The used PIC16F684 has insufficient number of outputs to control the LED directly. To resolve this problem I used a multiplexor on 74HC138. The multiplexor is used to select which LED digit is turned on. Since the selection in this IC is done by the logic 0 values, I used two transistors for each digit to interface my LED display whose segment LEDs have a common cathode. This part of the circuit can be simplified by choosing appropriate demux and/or LED with a common anode, but I do not have them at the moment.

The entire PORTC and two PORTA pins are used to control the segment LEDs and the decimal point. Pins RA1 and RA2 select a digit ho highlight, RA3 listens for the button click, and RA0 is an analog input.

Software

Download the complete source code here.

The temp is measured every (approx.) 2 seconds which is provided by TMR1 timer events. As soon as the timer overflows, it generates an interrupt request, whose purpose is to get a new temp reading from the DAC. Actually, TMR1 is overflows every 0.5 sec and we count 4 such events to get a new temp reading. After a new temp value is read, it is used in averaging with 3 preceeding values to reduce a possible flipping of digits. The averaging procedure also performes rounding off the average to the closest integer value.

The main loop of the code is intended to display the digits. Each digit is highlighted for 4 msec to reduce flickering of the display. The digits are displayed from left to right and the leading zeros are dimmed. If the decimal digit in the Celsius mode is 0, it is not shown along with the preceeding decimal point. The displayed value is rounded off to the nearest half of degree. Since the Fahrenheit scale is about twice sensible as the Celsius one, this eliminated the need in a decimal point and makes the temp display accuracy in the C and F modes uniform.

The main loop starts with checking the button status. Ones it is pressed, it becomes invalid (in software) until the user releases it. This is needed to prevent fast changing between the C and F modes at each loop cycle and also provides the button debouncing.

The 7-segment codes are setup at the initialization time and are taken from a read-only table. The conversion from Celsius to Fahrenheit is implemented in a table stored in EEPROM part of memory.


Last modified:Mon, Jan 23, 2023.

07046