You are on page 1of 12

Objective Our objective in this post to create such a system which measures ambient temperature and sends it to PC using

Serial Port. To fulfill this we need the following major components ;


PIC16F876 PIC Microcontroller Main Microcontroller LM35 Precision Centigrade Temperature Sensor For measuring temperature MAX232 Level Conversion RS232 TTL For interfacing MCUs USART with PCs Serial Port

Analog Digital Conversion in PIC Microcontrollers Generally PIC Microcontrollers offer 10 Bit of Analog to Digital Conversion. This means that when they measure an incoming voltage, they compare that voltage to a reference voltage, and give you the comparison represented as a 10-bit number (0-1023). You can wire as many analog inputs to the PIC as there are analog ports to accept them. However, you will notice some strange effects when you do so. The ADC circuits will affect each others readings, because all the circuits are pulling off the same +5V source. One thing you can do to minimize this is by using decoupling capacitors by each analog input, to smooth out dips and surges in the current caused by the other ADCs. Typically 0.1F to 1F will do the job. Place the capacitors between power and ground, as physically close to the ADC input as you can get. It also helps if you increase the sampling time and the delay between conversion and reading commands. Too much delay and you sacrifice interactivity; too little delay and you get random numbers. Start with the numbers in the sample code above, and vary them until you get readings youre happy with. Finally, it helps to sample at a lower resolution. Sampling at 8 bits instead of 10 will improve the speed and stability of a multiple ADC program. Since the ADC registers provide you with 10 bit number converted from the analog input, you can use the following formula to have input voltage; LM35 Precision Centigrade Temperature Sensor LM35 is an integrated circuit sensor that can be used to measure temperature with an electrical output proportional to the temperature in cenitgrade. The main reason behind using LM35 is that it doesnt need amplification like thermocouples. The conversion ratio of LM35 is 10mV/C . For e.g at temperature of 35 degrees LM35 will output 350 mV. MAX232 RS232 Transceiver MAX232 is used for level translation between TTL and RS232. It is very common and integral component while communication between Microcontrollers and PC using RS232. The USART

of PIC works on0-5V levels while RS232 works over -15 to +15 level. The MAX232 acts as a bridge between these two standards. Project By combining the above three major components along with the power of CCS C Compiler we achieve our objectives. Hardware Following is the schematic of whole project;

The output of LM35 is attached to PIN A0 which is a analog input. Pin C6 & C7 are dedicated for USART as Tx and RX respectively. MAX232 sits between RS232 and Controller to translate their voltages. A DB9 connector is used to connect PC with Controller. Software Following are the steps from the software we will design for the project; 1. Define ADC Resolution. 2. Configure USART with RS232 settings. 3. Initialize ADC.

4. Reading ADC Value. 5. Conversion into Centigrade. 6. Send temperature reading to PC over USART. Steps 4 to 6 will be performed under an infinite loop. But a delay will be added explained later. 1.Define ADC Resolution
#DEVICE ADC=10

The above statement is used to define the resolution of ADC in bits. The maximum resolution for PIC16F876 is 10-Bit. But you can define it to any number less than the maximum resolution. 2. Initialize and configure USART with RS232 settings. The following line is used to initialize and configure USART to start communication. #use rs232 (baud=57600,rcv=PIN_C7, xmit=PIN_C6) This line is used just after the oscillator clock declaration.Usually you have to give it Baudrate and the pins used for communication. If you want to use the builtin hardware USART then you use the above declared pins. But if you like more than one serial communication ports, you can declare communication on any pins. But note that using pins other than C6 and C7 will involve software serial data handling. And it can compromise speed as compared to hardware USART. 3.Initialize and Configure ADC
setup_adc_ports( ALL_ANALOG ); setup_adc(ADC_CLOCK_INTERNAL ); set_adc_channel( 0 );

These three lines setup the ADC and initializes it. setup_adc_ports is used to define which pins are to be used as analog inputs. Most suitable is ALL_ANALOG as it makes all AN pins as analog. The next statement defines the clock source for ADC. As PIC also has external clock feature for ADC conversion. The best is internal clock. To select the pin from which to read the analog voltages we use set_adc_channel . In our case LM35 is connected to Pin AN0, so we select Channel 0. 4.Reading ADC Value
value = read_adc();

The function read_adc() is used to read the value from ADC Register. It contains the digital equivalent value of analog input. For e.g. if we input 2.5 volts and the resolution defined for ADC is 10-Bit, we will get a value of 512 from read_adc(). 5. Conversion into Centigrade As we know that we get a digital value equivalent to in out analog voltage. So first we convert it into voltage value;

Please note that by default the reference voltage for ADC in PIC is 5V. For e.g if we get a value of 512 from ADC of 10-Bit resolution, the formula will have following values ;

We have got the voltage value which is coming from ADC, now we convert it into Temperature with help of formula provided by LM35;

If voltage of 0.375 are read from ADC, the above formula will return Temperature of 37.5C. Implementing both the equations in C ; volt = (value / 1023) * 5; temp = volt * 100; Read and conversion of voltages into digital and then temperature is done. In next we will send the data to PC using very simple command. 6.Send temperature reading to PC over USART.

The very reason of popularity of CCS C Compiler is its ease of use and powerful commands. Specially dealing with serial communication is very easy in this compiler. To send data to PC all you need to do is to use the following one line function; printf(Temperature: %.1f\n\r,temp); If you have used TurboC you maybe very well familiarized with printf. This function is the same olf function but the only difference is that when used in TurboC it displays on Monitor and when used in PIC it sends data over to serial port. The end result of this function at serial port would be; Temperature: 37.5 The Complete Code Combining all the parts together we have the following code; #include <16F876.h> #DEVICE ADC=10 #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #use rs232 (baud=57600,rcv=PIN_C7, xmit=PIN_C6) float value; float temp; float volt; void main() { //Initialize and Configure ADC setup_adc_ports( ALL_ANALOG ); setup_adc(ADC_CLOCK_INTERNAL ); set_adc_channel( 0 ); while(1) { //1 Sec Delay delay_ms(1000); //Read ADC Value value = read_adc();

//Convert Value into Volts volt = (value / 1023) * 5; //Convert Volts into Temperature temp = volt * 100; //Send data to PC printf(Temperature: %.1f\n\r,temp); } } You can use Hyper Terminal which comes with Windows XP. Or you can use many other serial port monitors easily available for download. Following is the screenshot of Hyper Terminal being sent the temperature data;

In our next post we will learn how to make temperature readings more accurate by using filters and different techniques. Also we will learn how to recieve the serial data in Visual Basic 6 for further programming and GUI. Happy InterfacING =)
Comment

Image

Showing 28 comments
Sort by

Subscribe by email

Subscribe by RSS

shb 1 year ago

Nice one !!! how abt we display the temperature on an Lcd.. creativeelectron and 1 more liked this

creativeelectron

1 year ago in reply to shb

That's a good idea, why don't you try it. Use http://creativeelectron.net/?p... for reference.

shb 1 year ago in reply to creativeelectron

i tried doing that...i am getting this Error " ADC conversion clock period is possibly invalid for device clock frequency" I'm using 16f877a and i've set the frequency to 20Mhz...

creativeelectron

1 year ago in reply to shb

Post your code so that I can review it

Krishan 6 months ago


Very useful details. Thanks

shb 1 year ago

One more thing... i'm a bit confused between Vs+,Vs-,Vcc and gnd.. i mean power is connected to Vs+...why is that...shouldn't that be grounded like Vs-.. Plus In the above circuit IC's (Vcc and gnd) r not shown connected..so that is an understood thing right....so whats with Vs+ and Vs

creativeelectron

1 year ago in reply to shb

MAX232 enhances voltage by charging and connecting capacitors in series.All is done internally by its logic controller and voltage comparator. There polarity for series connection determines the polarity of output voltage that is TX.

shb 1 year ago in reply to creativeelectron

hmmmm.... does that mean that Vs+ is to be connected to Vcc ??? and Vs- is to be connected to the common gnd ??? or are these two to be connected to a separate connector for communication purpose????

creativeelectron

1 year ago in reply to shb

no it doesn't mean that. it is just meant to be connected with capacitors.

shb 1 year ago in reply to creativeelectron

no after connecting them with capacitor then what....What abt that power and gnd which r connected with these two pins...

creativeelectron

1 year ago in reply to shb

What do you mean by "then what" and "what about" ? Sorry can't understand you.

creativeelectron 1 year ago in reply to creativeelectron

Check this http://creativeelectron.net/?p...

shb 1 year ago in reply to creativeelectron


Got it..Thanxx..

creativeelectron

1 year ago in reply to shb

VS are not the supply voltages, they are actually the capacitor voltages used for converting 0 volts to 9 volts and 5 volts to -9 volts. Vs + is for positive voltages for communication while Vs - is for negative. As you can see in VS- the capacitor is connected in inverse polarity, to have negative voltages from it.

kumail 1 year ago

Really interesting..... Is the PIC printf() function polling based or interrupt based?

creativeelectron

1 year ago in reply to kumail

As far as my knowledge is concerned it is neither polling nor interrupt. Because printf() sends the data, it doesn't receive. Polling and interrupts come into action when you are expecting input from any port.

Polling means reading data continuously until and unless you get one. In interrupts, you get an ISR called whenever the data is received. Well there are also interrupts for receiving serial data. Will cover them in next post.

Ameen 1 year ago

Hamza Nice post... Just one thing is unclear that is how to send the same data to LCD. You have posted LCD related thing earlier but it's still confusing about the LCD connections to the controller pins. Which pins of controller are for LCD?

creativeelectron

1 year ago in reply to Ameen

Thanks . in few days I will add the LCD in this post too. As far as pins are concerned you cal only use the pins which are declared in the header file. You can also change the pins but it is not advisable. The PIN to PIN connection is shown in this post in schematic http://creativeelectron.net/?p... All you need to do is to add 330Ohms Pull-Down resistors on Data and CS Pins.

shb 1 year ago in reply to creativeelectron

Wheres the CS pin ??

creativeelectron

1 year ago in reply to shb

By CS Pins I mean Control Signal Pins which are RS, RW and E Pins.

shb 1 year ago in reply to creativeelectron

ok.. And whats with ADCON0, ADCON1 registers and ADRESH, ADRESL... Do we need to incorporate these in some way...

creativeelectron

1 year ago in reply to shb

No you really don't need to worry about registers. Thats the beauty of CCS C Compiler that it has very easily understandable functions which take care of registers.

setup_adc_ports( ALL_ANALOG ); setup_adc(ADC_CLOCK_INTERNAL ); set_adc_channel( 0 ); These 3 commands are all you have to set-up.

shb 1 year ago in reply to creativeelectron

Pretty interesting.... i'll fidgit with my written code and try to display it on an lcd.. if i cant in a day or two then i'll post it here... Regards..

shb 1 year ago in reply to shb

One more thing... printf(lcd_putc,"Current Temperature: %.1f\n\r ",temp); Is the above line right....

creativeelectron

1 year ago in reply to shb

printf(lcd_putc,"Current Temperature: %.1f\r ",temp); Use only "\r" (return character). "\n" will take you to the next line which you don't need in LCD until and unless you want to display on new line.

shb 1 year ago in reply to creativeelectron

that is what i have used... printf(lcd_putc,"Current Temperature: %.1f\r ",temp); \n does not appear here....

Shahab Siddiqi 1 year ago in reply to shb

This works great on LCD as well, but only for positive values. I tried simulating this on Proteus and it showed 0 on the LCD when I tried negative temperatures. Am I doing something wrong?

creativeelectron 1 year ago in reply to Shahab Siddiqi

Actually for negative temperature LM35 creates negative output voltage. Since PIC's ADC can only read positive voltage that is why it is showing zero value. You can use an op-amp circuit to create offset in the reading if reading negative voltages are required.