Using Vishay NTCASCWE3102J or NTCASWE3xx NTC Thermistors with the PIC18F2550

This isn’t a magical cut and paste example. YOU need to do some work.  Why? There are a number of Vishay thermistors, all with different properties and I don’t know which one you have. The values included here are for the NTCASCWE3102J.

Also, I don’t know your port config, ADC or oscillator… Sorry. Your chips datasheet and Google are wonderful references.

Also, this was compiled with Microchip’s MPLAB X 3.45 IDE and the XC 1.38 compiler.

First you’ll need to get you’re thermistors resistance values from a Vishhay Excel sheet.
Go to Vishay and download the My Vishay NTC curve excel sheet.
Open the sheet, READ IT.
Enter your model number, steps, etc.
Save the results.
Open the results. These are the low and high values you’ll be replacing in ntc_resistance_low and ntc_resistance_high const arrays below.

 

#define NTC_MIN_TEMP 50 
#define NTC_MAX_TEMP 257
#define NTC_ARRAY_MAX 163
const unsigned int ntc_resistance_low[] = {1739,1699,1660,1621,1584,1548,1513,1478,1445,1412,1381,1350,1320,1290,1262,1234,1207,1180,1154,1129,1105,1081,1058,1035,1013,991,970,950,929,909,890,871,853,835,818,801,784,768,752,737,721,707,692,678,665,651,638,625,613,601,589,577,566,555,544,533,523,513,503,493,483,474,465,456,448,439,431,423,415,407,399,392,385,377,370,364,357,350,344,338,332,326,320,314,308,303,297,292,287,282,277,272,267,262,258,253,249,244,240,236,232,228,224,220,216,213,209,205,202,199,195,192,189,186,182,179,176,173,171,168,165,162,160,157,154,152,149,147,145,142,140,138,135,133,131,129,127,125,123,121,119,117,115,113,112,110,108,107,105,103,102,100,98,97,95,94,93,91,90,88,87,86,84};
const unsigned int ntc_resistance_high[] = {1935,1890,1846,1803,1761,1720,1681,1642,1604,1568,1532,1498,1464,1431,1399,1368,1337,1308,1279,1251,1223,1196,1170,1145,1120,1096,1073,1050,1027,1006,985,964,944,924,905,887,868,851,833,816,800,784,768,752,737,723,708,694,681,667,654,641,629,617,605,593,581,570,559,549,538,528,518,508,499,489,480,471,462,454,446,437,429,421,414,406,399,391,384,377,371,364,357,351,345,339,333,327,321,315,310,304,299,294,289,284,279,274,269,265,260,256,251,247,243,239,235,231,227,223,219,216,212,209,205,202,198,195,192,189,186,183,180,177,174,171,168,166,163,160,158,155,153,150,148,146,143,141,139,137,134,132,130,128,126,124,122,120,119,117,115,113,111,110,108,106,105,103,102,100,99,97,96};

void main(void);
unsigned int ReadTemp(unsigned char adcChannel);
unsigned int ADCToResistance(int adcValue, unsigned int maxResistance, float voltage);
int GetChannelValue(unsigned char adcChannel);
void SetupADC(void);    //Tweak this
void SetupOscillator(void);  //All on you

void main (void)
{
     unsigned int temperature = 0;

     SetupOscillator();
     SetupADC();

     while (1)
     {
          //Read NTC temp from Channel 0
          temperature = ReadTemp(0);
     }
}

unsigned int ReadTemp(unsigned char adcChannel)
{
    //Read stepped value ADC
    unsigned int channelValue = GetChannelValue(adcChannel); 
    
    //Convert ADC stepped (0-1024) value to a resistance.
    //10000 is the 'max resistance' of the NTC thermisor - or potientiometer
    //4.9 is the voltage supplied by the power source - USE A DMM to measure the voltage!  "But it's an 7805, so it's 5VDC.", doesn't cut it.
    unsigned int resistance=ADCToResistance(channelValue,10000,4.9); 

    //If the resistance is too high, it's too cold for the thermistor to operate
    if (resistance > ntc_resistance_high[0]) return NTC_MIN_TEMP-1;

    //Run through array and find where the resistance falls
    for (int i=0; ntc_resistance_low[i]>=NTC_ARRAY_MAX;i++)
    {
        int l = ntc_resistance_low[i];
        int h = ntc_resistance_high[i];

        if (resistance >= l & & resistance < = h )  //**** remove space between amperstands
                return NTC_MIN_TEMP+i;
    }

    //If we get here, the resistance is so low it's too hot for the thermistor.
    return NTC_MAX_TEMP;
}

unsigned int ADCToResistance(int adcValue, unsigned int maxResistance, float voltage)
{
    float f = ((float) (adcValue)) * 0.0048828;
    return (unsigned int) ((f * maxResistance) / (voltage - f));
}

int GetChannelValue(unsigned char adcChannel)
{
    ADCON0 = (ADCON0 & 0x81)|(adcChannel < < 2); //Set channel  ****Remove space between less thans

    GODONE=1; //Start conversion
    
    while (GODONE); //Wait for conversion to complete
    
    return ADRES; //Return result
}

//From here on down, it's all you.
void SetupOscillator(void)
{
    OSCCONbits.IDLEN = 0; //Device enters Sleep Mode on SLEEP instruction
    OSCCONbits.IRCF2 = 1; //111=8MHz, 110=4MHz, 101=2MHz, 100=1MHz
    OSCCONbits.IRCF1 = 1;
    OSCCONbits.IRCF0 = 1;
    
    OSCCONbits.OSTS = 1; //Oscillator Start-up Time-out Status
    OSCCONbits.IOFS = 1; //Frequency is stable
    OSCCONbits.SCS1 = 0; //System Clock Select bits  0=Int, 01=Timer1, 00=Primary osc
    OSCCONbits.SCS0 = 0;
    
// Wait for the internal oscillator to stabilize
    while(!(OSCCON & 0b100));
}

//Check your datasheet for ADC Setup!! You WILL need to tweak this
void SetupADC(void)
{
    // Turn shit off, in case it's on
    PIE1bits.ADIE=0; //Disable ADC interrupts
    PIR1bits.ADIF=0; //Clear ADC interrupt flag
    ADON=0; //Turn ADC off
    
    //Configure AD module
    ADCON1 = 0x0B; //Set vref to VSS and gnd, enable analog inputs only on AN0-AN3
    ADFM=1; //result is right to left
    ACQT2=1; //Set acquisition time
    ACQT1=1;
    ACQT0=1;
    ADCS2=1; //48MHz internal OSC...
    ADCS1=1;
    ADCS0=0;
    ADON=1; //Enable ADC
}

Leave a Reply