CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ntc interfacing with pic microcontroller

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
varadharaj



Joined: 09 Apr 2012
Posts: 19
Location: Salem

View user's profile Send private message

ntc interfacing with pic microcontroller
PostPosted: Sat May 26, 2012 6:23 am     Reply with quote

Hi,

I am interfacing NTC 10k with pic microcontroller by voltage divider circuit.
The +5v supply is connected with 10k resistor (1/4 watts, 1%tolerance). The other end of 10k is connected to the ntc 10k. Other end of ntc is connected to ground.

The ntc and 10k interconnection point is connected to 100k resistor. The other end of 100k resistor is connected to the a0 of pic microcontroller 16f877a. 0.1uf is taken from the a0 pin to ground.

All the resistors, i have taken are 1% tolerance. The output will be in lcd. The problem is the value is jumping always.for example, it is showing 30.4 in the next second, it is showing 31.2 without changing anything. next it is changing to 30.4. Can we arrest the jumping. And also If i change the temperature by heating it, it is jumping. I expect it to increase by 0.1 step. I have given the code below. Please suggest me to eliminate this jumping problem.





Code:



#include <16f877a.h>
#device adc=10
#fuses XT,NOWDT,NOLVP

#use delay(clock=4000000)

#separate
void adc_calc()
{
    float step_value,volt_value,temp_value;
       
    set_adc_channel(0);   // water temp
    delay_ms(100);
    step_value = read_adc();

// this calculation is for linearizing the output of adc
   
    volt_value = (step_value * 5) / (float)1024;
    if(volt_value >= 2.759 && volt_value <= 5)
        temp_value = -(24.4688 * volt_value)  + 88.3155 ;   
    else if(volt_value <= 2.663 && volt_value >= 0.936)
        temp_value = (-27.536 * volt_value) + 91.516 ;
    else if(volt_value <= 0.894 && volt_value >= 0.462)
        temp_value = -(67.4352 * volt_value)+ 129.6397 ;
       
       
    lcd_gotoxy(1,1);
    if(step_value > 950 || step_value < 20)
    {
       printf(lcd_putc,"Sen Open  ");
       open_flag = 0;
       output_high(pin_b1);
       output_high(pin_b0);
       lcd_gotoxy(1,2);
       printf(lcd_putc,"Change");
    }
    else if(open_flag == 1)
    {
      if((temp_value - buffer ) >= 0.5 || (temp_value - buffer) <= -0.5)
         temp_value = temp_value;
      else
         temp_value = buffer;
      printf(lcd_putc,"T:%3.1fC    ",temp_value);
         
    }
   
    lcd_gotoxy(1,2);
    if(temp_value > inlet_set_temp_max && open_flag == 1)
    {
      printf(lcd_putc,"T:Hi");
    }
    if(temp_value < inlet_set_temp_min  && open_flag == 1)
    {
      printf(lcd_putc,"S:ON");
      output_low(pin_b0);                                         // solenoid on
      output_high(pin_b1);                                       // fan off
      output_high(pin_a1);
      output_low(pin_a3);
      flag_sol = 1;
    }
    if(temp_value < inlet_set_temp_max && temp_value > inlet_set_temp_min && flag_sol == 0 && open_flag == 1)
    {
        printf(lcd_putc,"F:ON");
        output_low(pin_b1);                                     // fan on
        output_high(pin_b0);                                   // solenoid off
        output_low(pin_a1);
        output_high(pin_a3);
    }
    if(flag_sol == 1)
    {
        if(temp_value > (inlet_set_temp_min + Diff_inlet))
            flag_sol = 0;
        else if(temp_value > inlet_set_temp_min)
            printf(lcd_putc,"S:ON");
       
    }
    delay_ms(300);
    buffer = temp_value;
   
}

void main()
{

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);

   while(1)
   {
       adc_calc();
    }

}

_________________
Embedding Innovation
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sat May 26, 2012 7:01 am     Reply with quote

The ADC can make a lot of readings in a short time relative to your need to report it via your LCD. Why not use a moving average. It is fast if you use 16 for this. Avg value=last_avg_value-last_avg_value/16 +this value/16.
Init last_avg_value to the initial read of the ADC. You can improve upon it by casting out anomalies relative to the average..Ex a 2 degree jump is cast out.
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat May 26, 2012 7:37 am     Reply with quote

In your adc_calc() function you're delaying 100ms which is a HUGE amount of time, so the RTC can change dramatically from reading to reading.
It is best to take several readings and average them (8 or 16 works well). This is software averaging.
You may need a 1mfd cap or more to smooth out the RTC voltage to ADC input. This is hardware averaging.
Also if the +5 supply is NOT tightly regulated to say 1%, the readings will never be stable or accurate. Any extra current demands by your circuit will 'dip' the Vdd( +5) and affect the ADC.
Your program refers to a solenoid...it must have a diode across it to reduce EMI and be sure the power supply can handle the high current demand for it as well.
Any noise or spikes will show up as 'bad' RTC/ADC readings.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat May 26, 2012 1:10 pm     Reply with quote

What happens if you replace the 10k & ntc with a multi-turn pot. then SLOWLY rotate the adjuster?

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat May 26, 2012 2:40 pm     Reply with quote

You can also just replace the RTC with a fixed resistor (say 2.49K) and just loop forever....to see how stable the system is. Display both raw data(ADC bits), computed voltage and temperature.
If the reading varies say 3-4 bits that not too bad for overall noise.
Then you can say add filter caps, here and there, to tweak the performance to reduce the noise down to say 1-2 bits. Pretty good really 1/512-1/1024.

Once you're satisfied with this 'base level' test, then replace the fixed resistor with the RTC. All things considered it should be OK. If the reading is not 'solid', you probably have noise coming in through the RTC.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Sat May 26, 2012 4:34 pm     Reply with quote

Print out the raw A/D counts instead of calculating the temperature. If the count is only jumping 1 count that is the best you can do without a higher resolution A/D. If it is jumping several counts you may have a noise problem in your circuit.

Search the forum for "Olympic average" to find a very simple fast effective way to smooth A/D readings. Here is some code:

Code:

int16 olympic_ten(void) {
    int16 imax=0;
    int16 imin=1023;
    int16 isum=0;
    int16 itemp;
    int8 ctr;

    for (ctr=0;ctr<10;ctr++) {
        itemp=read_adc();
        if (itemp<imin) imin=itemp;
        if (itemp>imax) imax=itemp;
        isum+=itemp;
        delay_us(250);
    }
    //Now have the sum of ten readings, and the max/min readings
    isum-=imin;
    isum-=imax; //subtract the min and max from the sum leaving 8 readings

    itemp=isum/8; //compiler will automatically optimise this to a shift
    return itemp;
}

_________________
The search for better is endless. Instead simply find very good and get the job done.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group