• AVR Freaks

Helpful ReplyHot!Temperature Indicator Module (TIM) PIC16F19176

Page: 12 > Showing page 1 of 2
Author
MarcelC
Starting Member
  • Total Posts : 37
  • Reward points : 0
  • Joined: 2018/08/31 05:01:52
  • Location: Germany
  • Status: offline
2019/03/14 05:21:56 (permalink)
0

Temperature Indicator Module (TIM) PIC16F19176

Hallo,
 
i have some porblems by using the TIM of the PIC16F19176, study the AppNote AN1333 and AN2092, and I think die ADC Value of the Temperature Module shoul rise when the temperature increse and fall whe the temperature is falling, but with my code it will be in the other way.
Some one an Idea ????
   // CDAFVR 2x; FVREN enabled; TSRNG Hi_range; ADFVR 2x; TSEN enabled; 
  FVRCON = 0xBA;
  
  ADC_MW = 0;
        ADPCH = channel_Temp_Sensor;
         __delay_ms(1);
        for(i=0; i<3; i++)
        {
        ADC_Value = ADCC_GetSingleConversion(channel_Temp_Sensor);
        ADC_MW = ADC_MW + ADC_Value;
        }
        ADC_Value = ADC_MW / i;

post edited by MarcelC - 2019/03/15 01:35:29
#1
davekw7x
Entropy++
  • Total Posts : 1766
  • Reward points : 0
  • Joined: 2012/01/16 12:01:07
  • Location: Left Coast, USA
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F1976 2019/03/14 10:14:38 (permalink)
+1 (1)
Edit...If anyone caught my response prior to this: Superfluous and spurious information is hereby retracted.  ( I had inadvertently clicked "Submit" before it was ready.  Had wrong info.)
 
Anyhow...
[Edit]
I agree that ADC voltage should go up as temperature goes up.
As coffee critic points out in post #8 below,  for temp sensor connection in this device, ADC voltage goes down as temperature goes up.  For a given current, voltage across diode goes down as temperature goes up.  Sorry I missed it.
 [/Edit]
 
I don't know whether the following will help you, but it might help me understand.  I went through the steps with another chip
  • How are you controlling ambient temperature?
  • Since the Temperature module shows chip temperature, the entire circuit should "soak" at a given temperature before performing a reading.  How long are you giving it at each temperature before measuring?
  • Are you making multiple ADC readings and computing the average at each temperature?  Have you tried letting the conversion take place sleep mode? [Edit] I see that you performing an average.  Sorry.
  • What ambient temperature range is covered by your observations?
  • You are apparently using high range.  What is Vdd?
  • Are you keeping TSEN equal to zero except when taking the measurement?  Self-heating of temperature sensors is always a concern.
 
Regards,
 
Dave
post edited by davekw7x - 2019/03/15 20:28:09

Sometimes I just can't help myself...
#2
coffee critic
Super Member
  • Total Posts : 360
  • Reward points : 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F1976 2019/03/14 11:34:22 (permalink)
+2 (2)
Please include the ADC code that is in the MCC folder so that we can review all the ADC settings.  I suspect the issue is that the acquisition delay is still the default 5us not the 200us that is needed for the temp indicator.  What code values are you getting?  They should be between 400 and 600 at 4x mode and 5V Vdd.    

n_*$
#3
MarcelC
Starting Member
  • Total Posts : 37
  • Reward points : 0
  • Joined: 2018/08/31 05:01:52
  • Location: Germany
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F1976 2019/03/14 23:28:24 (permalink)
0
Hello,
 
first the Code:
 
void ADCC_Initialize(void)
{
    // set the ADCC to the options selected in the User Interface
    // ADLTH 0;
    ADLTHL = 0x00;
    // ADLTH 0;
    ADLTHH = 0x00;
    // ADUTH 0;
    ADUTHL = 0x00;
    // ADUTH 0;
    ADUTHH = 0x00;
    // ADSTPT 0;
    ADSTPTL = 0x00;
    // ADSTPT 0;
    ADSTPTH = 0x00;
    // ADACC 0;
    ADACCU = 0x00;
    // ADRPT 0;
    ADRPT = 0x00;
    // ADPCH ANA0;
    ADPCH = 0x00;
    // ADACQ 160;
    ADACQL = 0xA0;
    // ADACQ 15;
    ADACQH = 0x0F;
    // ADCAP Additional uC disabled;
    ADCAP = 0x00;
    // ADPRE 0;
    ADPREL = 0x00;
    // ADPRE 0;
    ADPREH = 0x00;
    // ADDSEN disabled; ADGPOL digital_low; ADIPEN disabled; ADPPOL Vss;
    ADCON1 = 0x00;
    // ADCRS 0; ADMD Basic_mode; ADACLR disabled; ADPSIS RES;
    ADCON2 = 0x00;
    // ADCALC First derivative of Single measurement; ADTMD disabled; ADSOI ADGO not cleared;
    ADCON3 = 0x00;
    // ADMATH registers not updated;
    ADSTAT = 0x00;
    // ADPREF VDD;
    ADREF = 0x00;
    // ADACT disabled;
    ADACT = 0x00;
    // ADCS FOSC/20;
    ADCLK = 0x09;
    // ADGO stop; ADFM right; ADON enabled; ADCS FOSC/ADCLK; ADCONT disabled;
    ADCON0 = 0x84;
    

}

 
At roomtemperature i get a Value of 1100 after use some cooling spray it rises on 1170......
The Aquesition Time should be 250µS and Vdd is 4.75V.
#4
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F1976 2019/03/15 01:17:27 (permalink)
+1 (1)
I can't find any device named "PIC16F1976". Did you mean "PIC16F19176" ?
If the ADC clock is Fosc/20, (and I'm assuming Fosc is 16MHz), then ADCLK = 1.6MHz, so Tad = 625ns
ADACQ = 0x0FA0 = 4000 so ACQ time is 4000 * 625ns = 2.5ms
That's way more than the required 25us minimum.
 

Nearly there...
#5
MarcelC
Starting Member
  • Total Posts : 37
  • Reward points : 0
  • Joined: 2018/08/31 05:01:52
  • Location: Germany
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/15 01:44:19 (permalink)
0
You are right! I chenged the device number.....
Do I understand that correctly, you do not think that the Aquesition time is the problem?
 

Attached Image(s)

#6
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/15 02:24:20 (permalink)
+1 (1)
ok, so I guessed correctly that you are running at 16MHz.
That is a crucial detail that you left out of your first post.
I then miscalculated Fosc/20, which is really 800 kHz, so Tad = 1.25us.
 
Now the acquisition calculation in MCC looks wrong.
The datasheet clearly states that the ADACQ register contains the number of "ADC clocks" to wait.
So, 4000 x 1.25us = 5ms.
Yet the MCC screen shows that 4000 giving 250us.
That would only be correct if it was counting 16MHz oscillator cycles.
Either MCC is wrong, or the datasheet is wrong.
 
 

Nearly there...
#7
coffee critic
Super Member
  • Total Posts : 360
  • Reward points : 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/15 08:52:51 (permalink)
+1 (1)
AN2798 is the correct ap note for the 16F19176.  The temp sensor is grounded in this part so the slope is negative.  This part does have the DIA calibration value that might eliminate the need for a production calibration step.

n_*$
#8
MarcelC
Starting Member
  • Total Posts : 37
  • Reward points : 0
  • Joined: 2018/08/31 05:01:52
  • Location: Germany
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/21 00:23:58 (permalink)
0
Now the TIM read out will partially work but the calculated Temperatur is always + 20°C from the actual temperature. When I use another Device it will be +15°C.
I Think the Temperature accurancy should be +-5°C according to AN2798.
But now is the Question, is there something wrong in my code?
 
    #define ADC_RES 4096
    int i ;
    uint16_t TSHR2;
    uint32_t ADC_AVG, ADC_Value;
    float V_out, Vref, offset, Ta ;
    
    Vref= 2.048; // because FVRA2X = 3XFF
    
// Read out TSHR2
NVMCON1bits.NVMREGS = 0x01;
NVMADRL = 0x16;
NVMADRH = 0x81;
NVMCON1bits.RD = 0x01;
while (NVMCON1bits.RD == 1);
TSHR2 = (NVMDATH<<8)+NVMDATL;

// calculating offset Value
V_out = TSHR2 * Vref ;
V_out = V_out / (ADC_RES -1);
offset = V_out * 270 ;
offset = 405 - offset;
offset = 90 - offset;


while (1)
  {
    // Read AVG ADC Value for the TIM Module
        ADC_AVG = 0;
        for(i=0; i<5; i++)
        {
        ADC_Value = ADCC_GetSingleConversion(channel_Temp_Sensor, 4000);
        ADC_AVG = ADC_AVG + ADC_Value;
        }
        ADC_Value = ADC_AVG / i;
 // Calculate Temperature Ta
        V_out = ADC_Value ;
        V_out = V_out * Vref;
        V_out = V_out / (ADC_RES -1);
        Ta = V_out * 270 ;
        Ta = 405 - Ta ;
        Ta = Ta + offset ;
        
     
    }
 

#9
coffee critic
Super Member
  • Total Posts : 360
  • Reward points : 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/21 09:48:04 (permalink)
0
20C error would not have surprised me on the old temp indicator but this one should be much better. 
Did you verify that the value you are reading in TSHR2 matches what you are seeing in the debugger? (printf)
 
Here are some other thing to check,
Verify that sensor is high range (3X) in FVRCON.
Verify that the reference is 2X FVR.
Try oversampling as mentioned in paragraph 2.1 to see if the value changes. There may be a single point error on the first sample (only) sample if the oversampled value is different.  
Measure the FVR with the ADC to calculate the actual FVR value.  This will also require oversampling.  This step will be not needed once we have determined why we are not seeing the DIA FVR values.
Lastly, verify all the math in a spread sheet to make sure that it matches the output of the chip. 
 
 

n_*$
#10
coffee critic
Super Member
  • Total Posts : 360
  • Reward points : 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/21 11:42:36 (permalink) ☄ Helpfulby MarcelC 2019/03/25 23:16:16
0
Also check out errata 1.6.  This might also explain some of the error. 

n_*$
#11
MarcelC
Starting Member
  • Total Posts : 37
  • Reward points : 0
  • Joined: 2018/08/31 05:01:52
  • Location: Germany
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/25 07:28:05 (permalink)
0
coffee critic
Also check out errata 1.6.  This might also explain some of the error. 


Thanks alot!
I have changed to FOSC/64 and now the measurement will work perfect!
#12
coffee critic
Super Member
  • Total Posts : 360
  • Reward points : 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/25 10:13:28 (permalink)
0
That is good to know. 
Question: How perfect is perfect? 
Was this using DIA90?
Were you able to get a part with usable FVR values?
Did you need to use oversampling or was a single conversion enough? 

n_*$
#13
MarcelC
Starting Member
  • Total Posts : 37
  • Reward points : 0
  • Joined: 2018/08/31 05:01:52
  • Location: Germany
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/03/25 23:11:03 (permalink)
+2 (2)
I Use the sourcecode above (fix value for FVR), and test three devices from -10°C - 60C°
the biggest deviation was 3.86°C at -10°C. (see attached picture)
I also opend a case at microchip support due to the unreadable FVRX* values odf the DIA.
 

Attached Image(s)

#14
oliverb
Super Member
  • Total Posts : 178
  • Reward points : 0
  • Joined: 2009/02/16 13:12:38
  • Location: 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/06/08 04:26:58 (permalink)
0
Is this effectively the same sensor as the PIC18F46K42 has? I've tried it out using example code and I get a reading about 10C above ambient. I tried coding my own version but I did resort to copy/pasting the math functions, so if there's an error in the example I may have copied it?
 
Two chips give very similar values.
 
 
#15
mpgmike
Super Member
  • Total Posts : 175
  • Reward points : 0
  • Joined: 2014/01/23 17:27:06
  • Location: NJ
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/06/08 07:32:48 (permalink)
0
I tested (I think) a PIC16F1824 about 3 years ago, going through every chip in my inventory (about 10 or so) and got radically different results from one to the next.  I've been afraid of using that function ever since.  Maybe I didn't give enough time for the read?  Don't even have that experiment around anymore (or whatever software I fabbed for the test).

I don't need the world to know my name, but I want to live a life so all my great-grandchildren proudly remember me.
#16
mbrowning
Just a Member
  • Total Posts : 1416
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/06/08 07:55:59 (permalink)
0
I’ve used the K42 temp sensor with good results. Using the datasheet typical slope and DIA calibration data my code calculates the offset at 90C once and applies it at each reading. The readings are off by a few degrees at room temp (compared to several other sensors on my boards) but are more accurate at higher temps closer to the 90C cal DIA cal point.

Higher temps are all I really care about but better total range accuracy could be achieved by getting a cal point at room temp and using that plus DIA data to calculate the real slope.

I haven’t used a device without DIA to read temp so I’ve no experience there. I assume you would have to have at least one cal point to get any accuracy. Perhaps two if the slope varies much from part to part.

Oh well - there's always next year
#17
coffee critic
Super Member
  • Total Posts : 360
  • Reward points : 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/06/10 09:21:24 (permalink)
0
oliverb,
Every mask has potential differences but in theory the temp indicator in the K42 should be very similar to the one in the 16F19176.

n_*$
#18
mbrowning
Just a Member
  • Total Posts : 1416
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/06/10 10:54:48 (permalink)
0
Here's my calculations for a K42 for whatever it's worth. Obviously some adjustment needed for your device and configuration.
I use VDD as ADC reference, and sum 16 ADC samples (burst averaging). VDD is calculated from FVR reading.
DIA temp sensor calibration value assumes FVR reference, but I use Vdd so offset calculation compensates for that.
// values calculated once
// read device information data
  dia_fvra2x    = FLASH_ReadDevice(0x3f0032);
  dia_tshr      = FLASH_ReadDevice(0x3f002c);
// pic ts offset = 90C - Vtdia/Mv = 90*16 - (tshr*fvr2x*16)/(4096*-3.684)
  tspic_offset  = 1440L + (((int32_t)dia_tshr*(int32_t)dia_fvra2x*16L)/15090L);
 
// values calculated for every ADC reading cycle (about 10ms)
  vdd = (16ul * 4096ul * dia_fvra2x) / ad_fvr;  // ad_fvr holds 16x ADC reading of FVR
// K = -3.684*4096 = -15090
// T = 90 + (ADC/16)*Vd/(-15090) - dia_tshr*FVRA2x/(-15090)   (ADC is 16x sample)
// T*16 = (ADC*Vd/(-15090)) + offset
// offset = 16*90 - 16*dia_tshr*FVRA2x/(-15090)
  tmp16s = (int16_t)((( (int32_t)vdd * ad_temp) / -15090L) + tspic_offset); // ad_temp is temp snsr reading



 

Oh well - there's always next year
#19
oliverb
Super Member
  • Total Posts : 178
  • Reward points : 0
  • Joined: 2009/02/16 13:12:38
  • Location: 0
  • Status: offline
Re: Temperature Indicator Module (TIM) PIC16F19176 2019/06/10 11:58:42 (permalink)
0
Here's the code I'm trying right now. The PICkit demo board appears convinced the temp is 32-33C. The xpress puts it at 30C
 
#include "mcc_generated_files/mcc.h"

// Definitions from tutorial
#define MV_HIGH_RANGE_FLOAT -3.684
#define MV_HIGH_RANGE_FIXED 3684 //-3.684
#define MV_FIXED_DIVIDER 1000 //Factor of 1000
#define ADC_RES_MINUS_ONE 4095 //2^12-1=4095

#define READ_TSHR2 FLASH_ReadWord(0x003F002C)
#define READ_FVRA2X FLASH_ReadWord(0x003F0032)

unsigned char reverse(unsigned char b) {
   b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
   b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
   b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
   return b;
}

adc_result_t adcc_read_average(adcc_channel_t channel)
{
    ADCC_GetSingleConversion(channel);
    return ADCC_GetFilterValue();
}
/*
                         Main application
 */
void main(void)
{
    SYSTEM_Initialize();
    adc_result_t adc_dia = READ_TSHR2;
    uint16_t fvra2x = READ_FVRA2X;
    float mv_float = MV_HIGH_RANGE_FLOAT;
    uint32_t mv_fixed = MV_HIGH_RANGE_FIXED;
    
    while (1)
    {
        adc_result_t adc_meas = adcc_read_average(channel_Temp);
        // Equation to implement:
        // float t_meas = 90 + (((adc_meas - adc_dia) * fvra2x)/(4095 * mv));
        // 4095 = 2^n-1, where n = 12 (adc resolution)

        uint32_t num_fixed = (uint32_t)(adc_meas - adc_dia) * fvra2x * MV_FIXED_DIVIDER;
        uint32_t den_fixed = (uint32_t)(ADC_RES_MINUS_ONE * mv_fixed) / MV_FIXED_DIVIDER;
        int32_t t_meas_fixed = (int32_t)90 * MV_FIXED_DIVIDER - num_fixed/den_fixed;
 

        uint8_t t_meas = t_meas_fixed/ MV_FIXED_DIVIDER;
// uint8_t t_bcd = (t_meas % 10) + (t_meas/10)*0x10;
        LATD=t_meas;
        __delay_ms(200);
        __delay_ms(200);
        __delay_ms(200);
        __delay_ms(200);
        __delay_ms(200);
    }
}

post edited by oliverb - 2019/06/10 12:06:30
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5