Bukit Mertajam, Penang

SK28A – Temperature Sensor with Fixed Voltage Reference


As seen in some tutorials online, LM35 are commonly used due to its simplicity and linearity which is 10mV per Celsius. The output of the LM35 is connected to an ADC input in a microcontroller, and the result is processed inside.

An ADC needs a voltage reference, and as usual this will be connected to +5V. In common PIC microcontrollers, the ADC has 10-bit resolution. That means, it has 1024 steps or parts. So we divide the +5V voltage reference to the 1024 (because 2^10 = 1024 steps). We get 4.8828125mV per step. (And in our favorite C compiler, we put 4.88mV here for simplification purposes)

Afterwards, we assume that the voltage obtained by the LM35 is 330mV (33 degrees Celsius), which is 33 degrees Celsius. The 10-bit ADC value is acquired which is 330mV/4.8828125mV = 67.584. As it is a fixed number, it becomes 67 when you read the register.

To get back the Celsius value from the ADC value, we just multiply the 67 by the 4.88125mV, and then multiply it by a hundred. We get 32.70 Celsius. It is not 33.00! What has happened there? Is the PIC microcontroller broken? Fortunately no, it is not broken. The ADC results were already rounded/truncated/approximated before you even obtain them. If accuracy isn’t that important, you can simply round the results again, but you will lose the tenth information. Another thing is, the +5V from our casual 7805 voltage and breadboard never guarantees a +5.0000V operation, so it slightly affects the reading as well. And, floating point operations in 8-bit microcontrollers are tedious and can slow down the system if the design is complex.

One way to minimize such problem is to use a Fixed Voltage Reference (FVR) which is found in the later PIC16F microcontrollers. You can tie the Fixed Voltage Reference to the ADC’s voltage reference. The ADPREF switches, when set to ‘11’, connects the ADC voltage reference to the FVR.

Afterwards, we are switching the FVR module on.

Since we are turning it on, the bit 7 (FVREN) must be set. As in this tutorial, the bits 1-0 (ADFVR<1:0>) is changed to ‘01’, which is “A/D Converter Fixed Voltage Reference Peripheral output is 1x (1.024V)”.

All these are in the function. Should you need to change the ADC channel pin, feel free to do so inside the function. The function must be called before performing A/D conversion.

You will ask, “How does it improves results?”. The answer is, it simplify calculations and to minimize rounding and truncation errors, if they exist. And the voltage reference is fixed – so it doesn’t drift or it doesn’t do anything funny if there is a power supply spike or problem (unless if you subject the microcontroller below 1.024V, of course). That’s all.

Back to the calculation: We now have a +1.024V reference now, so 1.024V/1024 gives exactly 1mV per step. That’s so cool, exactly 1mV. Taking the example 330mV from the LM35’s output, we have 330mV/1mV = 330 as an ADC result.

You then proceed to divide 330 by 10. The answer is very clear: 33. If it’s 33.6 degrees Celsius, it’s 336 in your ADC result. That’s easy! Division by 10 isn’t much stressful to calculate in an 8-bit microcontroller, unlike multiplying it by 4.88125mV and then by 100.

What you will need is an SK28A w/ PIC16F1933 microcontroller, an LM35 temperature sensor, a breadboard, an 8×2 LCD, plus an AC Adaptor and three pieces of wires.

The source code project is attached. Compiler used: MPLAB X 1.10 and Hi-tech C v.9.83

The schematic is as follows:


1.)    Using Fixed Voltage Reference (FVR) for A/D conversion in enhanced mid-range PIC microcontrollers, http://embedded-lab.com/blog/?p=3045 by Rajendra Bhatt.

2.)    di Jasio, L. (2008) Programming 32-bit Microcontrollers in C – Exploring the PIC32, Elsevier

3.)    Mazidi, M.A., Mckinlay, R.D., Causey, D. (2008) PIC Microcontroller and Embedded Systems – Using Assembly and C for PIC18, Pearson International Edition

4.)    PIC16F1933 datasheet

5.)    LM35 datasheet: www.national.com/ds/LM/LM35.pdf

Important Note: If the UIC00B/PICKit 2 cannot recognize the PIC16F1933 in the SK28A, you may need to upgrade the device file in PICKit 2 before you upload the program into the SK28A. Grab the latest device file from this link: http://ww1.microchip.com/downloads/en/DeviceDoc/PK2DFUpdate-1-62-14.zip

When you have it, unzip it to “C:\Program Files\Microchip\PICkit 2 v2\” and overwrite the file. Then try uploading it again.

On MPLAB X, project files are not used anymore – it is referred to the folder instead. The MPLAB X, with that project does not support PICKit 2 for some strange reason but you still can automatically upload your program after you compile it. Here’s how to do it:

1.)    In the PICKit 2 program, click on the “Auto Import Hex + Write Device”. You will be directed to a browse window.

2.)    Afterwards, find the sk28a-thermometer.X folder you have just downloaded it. It is called “sk28a-thermometer.X”.

3.)    Then click on the “dist”, and then “default” and “production”.

4.)    You will find “sk28a-thermometer.X.production.hex” inside. Select it and click “open”.

5.)    Go back to the MPLAB X, (modify and) compile the project. The program will auto-upload every time you compile. The program will not be uploaded if you have a compilation error.


1. SK28A Tutorial – sk28a-thermometer.X.zip


Leave a comment