Helpful ReplyInternal Temperature Indicator - PIC10F322

Page: < 123 Showing page 3 of 3
Author
dan1138
Super Member
  • Total Posts : 3021
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/29 17:16:27 (permalink)
+1 (1)
viki2000
I tested 30 pieces PIC10F322 extended version (up to 125°C) in package SOT23-6 without calibration.

If I interpret you test method correctly you have used the ADC to read the internal temperature input and report that to your data log.
 
Your test setup supplies the PIC10F322 with a well regulated 5.0 VDC VDD and holds it at a constant temperature of 25°C.
 
Under these conditions your data shows that ADC value read from the internal temperature input when the part is at 25°C varies from a low of 107 to a high of 126 ADC counts.
 
To convert these ADC values to °C I find just confusing.
 
What this does show is that 25°C can be represented by 19 different ADC values for the 30 samples you have tested.
 
The typical VT forward voltage threshold of the temperature sensor at 25°C for the "typical" device is 0.5735 volts. Using the "high range" will result with an ADC 8-bit value of 138.
 
I suspect that you may have some bugs in your code as your logged ADC value is significantly less that what is expected from a typical device.
post edited by dan1138 - 2015/07/29 17:18:53
#41
NKurzman
A Guy on the Net
  • Total Posts : 16995
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: online
Re: Internal Temperature Indicator - PIC10F322 2015/07/29 17:24:15 (permalink)
+1 (2)
"when the part is at 25°C "
The die will be warmer.  Optimally you would want a low Clock for testing and not sinking or sourcing.
But for production "Calibration" Normal conditions.
#42
dan1138
Super Member
  • Total Posts : 3021
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/29 20:28:39 (permalink)
+1 (1)
All true, but the ADC value are too low. For this to be true the "die" would have to be colder than 25°C.

The OP should look for bugs.
#43
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/30 03:04:55 (permalink)
0 (1)
I tried to find if there is an error in code, maybe with RS232 communication or on receiver side when I display  it on the OLED.
The only changes compare with previous code are related with:
     1) Using pin RA1 instead of RA2 for RS232
     2) Offset 120 instead of 40 for temperature calculation on PIC10F322 side, which I correct proper on receiver side and the proof is that Excel formula gives the same temperature value,  based on ADCfvr and ADCti 8bit variables, as I see it on display sent by PIC10F322.
Then I checked the value of the data sent for ADCfvr, ADCti and Temperature.
I updated the Excel sheet with 2 more columns on the right side:
https://docs.google.com/s...-2loM/edit?usp=sharing
 
The numbers sent for temperature are in the range 27-98, then ADCti is in the range 107-126 as you noticed, ADCfvr is constant 52, therefore I see no problem for serial communication when I sent 1 byte with ID markers 253 or 254 or 255. The data is not mixed up with the markers.
Everything seems fine to me.
 
The code used:
#include <xc.h>
#define _XTAL_FREQ 16000000

__CONFIG(FOSC_INTOSC & MCLRE_OFF & WDTE_OFF & LVP_OFF & CP_ON & WRT_OFF &

        PWRTE_ON & WRT_OFF & BOREN_ON & LPBOR_ON & BORV_LO);

unsigned char i;
unsigned short ADCfvr, ADCti, TEMPX;
void TX(unsigned char TEMP);

void main(){

OSCCON=0b01110000;
TRISA=0b00001101;
LATA=0b00000000;

while(1){
    __delay_ms(100);
    //set FVR
    FVRCON=0b11110001;
    ADCON=0b11111101;
    __delay_ms(1);
    //measure FVR
    GO_nDONE = 1;
    while(GO_nDONE) continue;
    ADCfvr=ADRES;
    __delay_ms(1);

    //set temperature indicator
    FVRCON=0b11110001;
    ADCON=0b11111001;
    __delay_ms(1);
    //measure temperature indicator
    GO_nDONE = 1;
    while(GO_nDONE) continue;
    ADCti=ADRES;
    __delay_ms(1);

    TEMPX = 579-(194*(255-ADCti)/ADCfvr);

    //send the 1st marker to identify the 1st byte that will be sent
    TX(253);
    __delay_ms(15);
    //send the 1st byte - ADCfvr
    TX(ADCfvr);
    __delay_ms(15);
    //send the 2nd marker to identify the 2nd byte that will be sent
    TX(254);
    __delay_ms(15);
    //send the 2nd byte - ADCti
    TX(ADCti);
    __delay_ms(15);
     //send 13rd marker to identify 1the 3rd byte that will be sent
    TX(255);
    __delay_ms(15);
     //send the 3rd byte - temperature
    TX(TEMPX);
}
}

void TX(unsigned char TEMP){
    LATA1=0;
    __delay_us(412);
    for (i = 0; i < 8; i++){
         if( ((TEMP>>i)&0x1) == 0x1)
         {
             LATA1=1;
         }
         else
         {
             LATA1=0;
         }
         __delay_us(406);
    }
    LATA1=1;
    __delay_us(416);
}
 
To demolish any doubt I repeated the test with the same code for PIC10F322, same setup, but this time using 30x PIC10F322 I/P industrial version up to 85°C and package PDIP-8.
The results are here:
https://docs.google.com/spreadsheets/d/1Sp4X8oMsgnUMJDDK9AYYJvSZA53hTQkXlefjshloK60/edit?usp=sharing
https://drive.google.com/open?id=0BwXmKaSw75eKT1ozMnJiLWdibUU
 

post edited by viki2000 - 2015/07/30 03:17:39
#44
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/30 06:46:48 (permalink)
+2 (1)
Regarding the lot question, I do not know exactly because I do not have the reels. The last batch was bought few months ago with of volume of over 10.000 pieces and I got 100-150 for test purpose from that lot. I expect to be the same lot, but to be sure I must ask the production site. The small PIC10F322 in SOT-23-6 has only an ID mark on it to know the type and the dot for pin1. The PDIP8 package: 29 of them have the production code 1213, meaning year 2012 and week 13 and the 30th piece is marked 1142, meaning production year 2011 week 42, clear a different lot, the one  which gave the result -44°C, 120 ADCti.
 
The PIC has only one pin for RS232 RA1 connected to one input of PIC18F4550, which has high impedance input, so we cannot speak about sourcing and sinking important current to affect the measurements. And RS232 communication is done 100ms after the measurements of FVR and junction voltage/temperature.
The clock is indeed high 16MHz, but I got the same negative results for SOT-23-6 with 8MHz. With 4MHz and less I get some communication errors, which must be fixed, because the numbers received on display are not good, they are 255. That is a bit strange because the RS232 6 packages data pattern is the same seen on oscilloscope. A debug must be done for 4MHz and less. But important to know is that I need the PIC10F322 to work at 16MHz or at least 8MHz. For 4MHz or less frequency, tests are only to confirm or infirm the finding up to now, but are not suitable for my real application.
 
Regarding the numbers mentioned by Dan above, I think is good to give some explanations for future readers. If we look into the AN1333 B page 1 there is next graphic:
 

 
There we see 0.5735V at 25°C as typical. But that is for only 1 device PIC16F1937. It is nothing mentioned about other PICs with internal temperature indicator and nothing about tolerances between different devices.
From my point of view to use 0.5735V at 25°C is not an absolute reference.
Deviation from 0.5735V may easy appear among devices.
There are technical articles showing the VFD (Voltage Forward) depends by temperature of a diode, a junction and the tolerances, not necessarily done by Microchip.
Then on page 4 we have the next graphic:
 

 
There we see the 138 as ADC result for a calibrated device, measured at 25°C and stabilized supply voltage.
Here is how we get those numbers.
On the page 2 we see the Vtemp=VDD-4*Vt, where Vt is the voltage for 1 junction.
Then we get Vtemp=5-4*0.5735=2.706V
Considering the VDD 5V and the ADC 8bits, meaning the result in the range 0-255, then we calculate the ADC result as follows:
     - If at 5V corresponds 255, then at 2.706V corresponds 2.706*255/5=138, which is the number from the graphic above on page 4.
In my 1st case with SOT-23-6 PICs, the ADC result is between 107 and 126.
If we calculate back the junction voltage we get:
     - for 107: (107*5/255)/4=0.5245, which gives (0.5245/0.5735-1)*100=-8.54% deviation compared with 1 device PIC16F1937 which has 0.5735V at 25°C
     - for 126: (126*5/255)/4=0.6167, which gives (0.6167/0.5735-1)*100=+7.53% deviation compared with 1 device PIC16F1937 which has 0.5735V at 25°C
     - The deviation of the junction voltage of the PIC10F322 SOT-23-6 compared with 1 device PIC16F1937 is then +7.5/-8.5%.
     - The deviation range is +7.5%-(-8.5%)=7.5%+8.5%=16%
In my 2nd test with PDIP-8 PICs, the ADC result is between 120 and 140.
If we calculate back the junction voltage we get:
     - for 120: (120*5/255)/4=0.5882, which gives (0.5882/0.5735-1)*100=+2.56% deviation compared with 1 device PIC16F1937 which has 0.5735V at 25°C
     - for 140: (140*5/255)/4=0.6862, which gives (0.6862/0.5735-1)*100=+19.65% deviation compared with 1 device PIC16F1937 which has 0.5735V at 25°C
     - The deviation of the junction voltage of the PIC10F322 PDIP-8 compared with 1 device PIC16F1937 is then +2.5/+19.6%.
     - The deviation range is 19.6%-2.5%=17.1%
The deviation range is the almost the same for SOT-23-6 as for PIDP8, only that is shifted with an offset.
 
Does anybody know the typical tolerance of the silicone diode junction forward voltage?
 
If we know that then we can think twice why the results are like that.
For my curiosity I tested one more time random some of SOT-23-6 PICs, re-programming them, and I got the same negative numbers for temperature.
It is nothing wrong with the code.
There is an important difference between results obtained with SOT-23-6 and PDIP-8 packages. It is obviously an offset besides the spread of the results in a quite wide range when there is no calibration done.
Based on 30 device, we have for SOT-23-6 the temperature in the range -93….22°C and the ADCti in the range 107…126. That 115°C spread range.
Based on 30 device, we have for PDI-8 the temperature in the range -44…+39°C  and the ADCti in the range 120…140. That is 83°C spread range.
The VDD was 4.99-5.00, detected by PIC10F322 with FVR sometimes 52 as 5.02V and sometimes 53 as 4.93V.
It is like a shifting/offset of the results for these 2 packages with 13-14 for ADCti, which corresponds to around 48-50°C.
I need to use SOT-23-6 anyway, but I made the test with PDIP-8 only to double check the possible errors.
The problem is what we get as offset for non-calibrated devices.
 
The conclusion after such analysis effort is that PIC10F322 gives a too wide range for the temperature measurement which cannot be used without calibration.
 
The last thing which will be interesting to be analyzed is the idea proposed by Nikolay: a self calibration at first power up with self-writing flash for 1 location memory with calibration coefficient, assuming a constant ambient temperature of around 25°C at first power on/board test.
That would make sense if after such code implementation, the PICs are tested again for a wider range of temperature to see the error range for cold and hot environments.
 
Unfortunately I have no more time to continue the investigations now, but if are any suggestions/code examples regarding how the code should be written for self-writing at first power on, then later I may be able to test. For me the information from datasheet regarding the self-writing is not enough.
post edited by viki2000 - 2015/07/30 07:29:42
#45
dan1138
Super Member
  • Total Posts : 3021
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/30 14:12:35 (permalink) ☄ Helpfulby viki2000 2015/07/31 02:01:37
+3 (2)
After looking at the PIC10F322 code you posted it seem unlikely there is bug in it. If a bug exists it may be in the code that is processing the PIC10F322 serial data.
 
Here is some code that will output the ADC values as HEX ASCII to a TTL serial interface on the PGC/PGD pins:
;
; File: main.asm
; Target: PIC10F322
; IDE: MPLABX 3.05
; Assembler: MPASM v5.62
;
; Additional files:
;   P10F322.INC
;   10F322_g.lkr
;
; Description:
;   
;   Demo application to show reading the PIC10F322 ADC on
;   two channels, FVR and Temp Indicator.
;   
;   System clock is the Fast Internal Oscillator at 8MHz.
;
;   Default baud rate is 9600.
;
;   Wait for serial input on PORTA bit 1, the PGC pin.
;   The default ADC report display is about once per second.
;
;   When a byte is received it is checked for these characters:
;
;     'A' ADC display ON/OFF
;     '6' ADC in TI
;     '7' ADC in FVR
;     '?' show this message
;
;   Note: Characters are case sensitive and are UPPER CASE.
;
;   Data is sent using a bit-bang UART on PORTA bit 0, PGD.
;
;   Using the PGD/PGC pins for a TTL serial interface allows
;   the use of a PICkit2 as a serial to USB interface. The
;   PICkit2 does not support programming the PIC10F322.
;
    list      p=10F322            ; list directive to define processor
    #include <p10F322.inc>        ; processor specific variable definitions
     
    __CONFIG   _WRT_OFF & _BORV_24 & _LPBOR_OFF & _LVP_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_OFF & _WDTE_OFF & _BOREN_OFF & _FOSC_INTOSC

    list    r=dec
    errorlevel -302

#define FOSC (8000000)
#define FCYC (FOSC/4)

; With an 8MHz oscillator the low end
; of range is limited to 9600 baud.
; The fastest reliable is 38400 baud.
#define BAUD (9600)
#define T0_RELOAD (256-(FCYC/BAUD))

#define ADC_DELAY_COUNT (50000)

RESET_VECTOR CODE  0x000
        goto    start

ISR_DATA    UDATA
WREG_SAVE   res     1
STATUS_SAVE res     1
PCLATH_SAVE res     1
;
; Application wide status flags
App_Status  res     1
#define RX_DataAvailable App_Status,1
#define RX_FamingError App_Status,2
#define RX_OverrunError App_Status,3
#define ADC_Sample App_Status,4
#define ADC_Show_Sample App_Status,5
;
; Serial data
TX_Data     res     1
RX_Data     res     1
UART_State  res     1

#define TX_START    (11)
#define RX_START    (16)
#define TXD_BIT     LATA,0
#define RXD_BIT     PORTA,1
;
; Interrupt vector
;
ISR_VECTOR  CODE    0x004
        movwf   WREG_SAVE
        movf    STATUS,W
        clrf    STATUS
        movwf   STATUS_SAVE
        movf    PCLATH,W
        movwf   PCLATH_SAVE
        clrf    PCLATH
;
; TIMER0 ISR
;   This is a bit banged half duplex UART
;
; Note:
;   The TIMER0 interrupt uses a PC relative
;   jump table to process the transmitter state.
;   This jump table must be within a 256 byte
;   program memory page.
;
ISR_TMR0:
        btfsc   INTCON,TMR0IE
        btfss   INTCON,TMR0IF
        goto    ISR_TMR0_Exit

        bcf     INTCON,TMR0IF
        movlw   T0_RELOAD+3
        addwf   TMR0,F

        decfsz  UART_State,W      ; skip if transmitter is empty
        goto    UART_DoState
;
; TX empty
;
TX_State_0:
        bcf     INTCON,TMR0IE     ; Disable interrupt when TX empty
;
; Stop bit
;
TX_State_1:
        bsf     TXD_BIT
        goto    ISR_Exit

UART_DoState:
        andlw   0x0F            ; This prevents a crash but does not prevent
        movwf   UART_State      ; data errors when UART_state is corrupted.
        addwf   PCL,F
        goto    TX_State_0      ; TX empty
        goto    TX_State_1      ; stop
        goto    TX_State_2      ; data 7
        goto    TX_State_3      ; data 6
        goto    TX_State_4      ; data 5
        goto    TX_State_5      ; data 4
        goto    TX_State_6      ; data 3
        goto    TX_State_7      ; data 2
        goto    TX_State_8      ; data 1
        goto    TX_State_9      ; data 0
        goto    TX_State_10     ; start
        goto    TX_State_1      ; stop
        goto    TX_State_1      ; stop
        goto    TX_State_1      ; stop
        goto    RX_State_0      ; RX Stop bit
        goto    RX_State_1      ; RX Data bit
;
; Start bit
;
TX_State_10:
        bcf     TXD_BIT
        goto    ISR_Exit
;
; Data bits
;
TX_State_9:
TX_State_8:
TX_State_7:
TX_State_6:
TX_State_5:
TX_State_4:
TX_State_3:
TX_State_2:
        btfss   TX_Data,0
        bcf     TXD_BIT
        btfsc   TX_Data,0
        bsf     TXD_BIT
        rrf     TX_Data,F
        goto    ISR_Exit
;
; RX Stop bit
;
RX_State_0:
        btfss   RXD_BIT         ; Skip if stop bit present
        bsf     RX_FamingError
        btfsc   RX_DataAvailable ; Skip if data buffer available
        bsf     RX_OverrunError
        bsf     RX_DataAvailable ; Assert new data arrived
        bcf     INTCON,TMR0IE     ; Disable interrupt when RX complete
        goto    ISR_Exit
;
; RX Data bit
;
RX_State_1:
        btfsc   RXD_BIT         ; CARRY always zero when state starts
        setc                    ; Set CARRY if RX data is ZERO
        rrf     RX_Data,F       ; Shift in bit
        skpc                    ; CARRY is set when all 8 bits arrived
        incf    UART_State,F    ; Stay in RX data bit state until byte received
        goto    ISR_Exit
ISR_TMR0_Exit:

;
; Interrupt On Change ISR
;   This is a bit banged UART receive start bit
ISR_IOC:
        btfsc   INTCON,IOCIE
        btfss   INTCON,IOCIF
        goto    ISR_IOC_Exit

        movf    PORTA,W         ; Clear miss match
        clrf    IOCAF           ; Clear IOC assert
        btfsc   RXD_BIT         ; Skip if RXD is a Start Bit (LOW)
        goto    ISR_Exit

        movlw   T0_RELOAD+30    ; Add start bit ISR overhead
        movwf   TMR0
        bcf     INTCON,TMR0IF
        bsf     INTCON,TMR0IE

        movlw   0x80            ; Set to receive 8 bits of RX data
        movwf   RX_Data
        movlw   RX_START        ; Set UART to receive data bits state
        movwf   UART_State
        bcf     INTCON,IOCIE    ; Disable RX start bit interrupt

        goto    ISR_Exit
ISR_IOC_Exit:
;
; Handle ADC interrupt
;
ISR_ADC:
        btfss   PIE1,ADIE       ; must be enabled to wake from sleep
        goto    ISR_ADC_Exit

        btfss   PIR1,ADIF       ; must be enabled to wake from sleep
        goto    ISR_ADC_Exit
        bcf     PIR1,ADIF
        btfss   ADC_Sample
        bsf     ADC_Sample
        goto    ISR_Exit
ISR_ADC_Exit:

ISR_Exit:
        movf    PCLATH_SAVE,W
        movwf   PCLATH
        movf    STATUS_SAVE,W
        movwf   STATUS
        swapf   WREG_SAVE,F
        swapf   WREG_SAVE,W
        retfie
;
; PutC
;   put a character out serial port
;
Putc:
        btfsc   INTCON,TMR0IE     ; skip when UART not busy
        goto    Putc
        bcf     INTCON,IOCIE    ; cannot receive when sending

        movwf   TX_Data
        movlw   TX_START        ; select UART start send state
        movwf   UART_State

        movlw   T0_RELOAD
        movwf   TMR0
        bcf     INTCON,TMR0IF
        bsf     INTCON,TMR0IE
        return
;
; Wait for UART transmit to complete
;
WaitForSend:
        btfsc   INTCON,TMR0IE     ; skip when UART not busy
        goto    WaitForSend

        return
;
; Put HEX nibble
;
PutHexNibble:
        call    GetHexChar
        call    Putc
        return
;
; Look up ASCII character to low 4-bits in W
; Input: HEX nibble low 4-bits of W
; Output: W = ASCII character of HEX value
;
GetHexChar:
        andlw   0x0F
        movwf   PCLATH
        xorlw   HIGH(HexTable)
        xorwf   PCLATH,F
        xorlw   HIGH(HexTable)
        addlw   LOW(HexTable)
        skpnc
        incf    PCLATH,F
        movwf   PCL
HexTable:
        DT      '0','1','2','3','4','5','6','7'
        DT      '8','9','A','B','C','D','E','F'
PUTS_DATA UDATA
prString    res 2
RPUTS_CODE CODE
;
; Print an ASCII zero terminated sring from CODE space
;
rPuts:
    movf    prString+1,W
    iorwf   prString,W
    skpnz
    return
    call    rPutsGetChar
    iorlw   0
    skpnz
    return
    call    Putc
    incf    prString,F
    skpnz
    incf    prString+1,F
    goto    rPuts
;
; Fetch a character from CODE space
;
rPutsGetChar:
    movf    prString+1,W
    movwf   PCLATH
    movf    prString,W
    movwf   PCL
;
; Main application data
;
MAIN_DATA    UDATA
;
; ADC data
ADC_Value   res     1
;
; Process ADC delay
ADC_Delay   res     2
;
;
;
MAIN_CODE CODE
;
; Do a very simple command processor
;
ProcessCharacter:
        bcf     RX_DataAvailable

        movlw   'A'             ; see if it is a toggle ADC display request
        xorwf   RX_Data,W
        skpnz
        call    ToggleAdcDisplay

        movlw   '6'             ; see if it is a select ADC channel Temperature Input
        xorwf   RX_Data,W
        movlw   B'00011000'     ; Select Temp Indicator as ADC input
        skpnz
        call    SetADC_Channel

        movlw   '7'             ; see if it is a select ADC channel Fixed Voltage Reference
        xorwf   RX_Data,W
        movlw   B'00011100'     ; Select FVR as ADC input
        skpnz
        call    SetADC_Channel
;
; This must be here and must be the last input checked
;
        movlw   '?'             ; see if it is a usage request
        xorwf   RX_Data,W
        skpz
        goto    EnableStartBitDetect

ShowSignOnMessage:
        movlw   LOW(PowerOnMessage)
        movwf   prString
        movlw   HIGH(PowerOnMessage)
        movwf   prString+1
        call    rPuts
        call    WaitForSend
;
; Enable RX start bit detect
;
EnableStartBitDetect:
        movf    PORTA,W
        bcf     INTCON,IOCIF
        bsf     INTCON,IOCIE
        return
;
; Select ADC channel
;
SetADC_Channel:
        bcf     PIE1,ADIE   ; disable ADC interrupt for channel change
        
        xorwf   ADCON,W
        andlw   B'00011100' ; Channel select mask
        xorwf   ADCON,F

        bsf     PIE1,ADIE   ; enable ADC interrupt

        return
;
; Turn the ADC display on or off
;
ToggleAdcDisplay:
        clrc
        btfss   ADC_Show_Sample
        setc
        skpc
        bcf     ADC_Show_Sample
        skpnc
        bsf     ADC_Show_Sample
        return
;
; Process ADC sample
;
ProcessAdcSample:
        btfsc   ADCON,GO_NOT_DONE ; Skip if ADC conversion is complete
        return
;
; Delay between ADC outputs because
; if we send too fast the UART receiver
; gets no cycles to detect a start bit.
;
        movf    ADC_Delay,W
        iorwf   ADC_Delay+1,W
        skpnz
        goto    DisplayAdcSample
        decf    ADC_Delay,F
        skpnz
        decf    ADC_Delay+1,F
        return

DisplayAdcSample:
;
; Reload delay count
;
        movlw   LOW(ADC_DELAY_COUNT)
        movwf   ADC_Delay
        movlw   HIGH(ADC_DELAY_COUNT)
        movwf   ADC_Delay+1
;
; Read all 8-bits of the ADC
;
        movf    ADRES,W
        movwf   ADC_Value

        bcf     ADC_Sample          ; Clear process flag for ADC

        btfss   ADC_Show_Sample
        return

        call    ShowAdc             ; Display ADC value
        call    EnableStartBitDetect
        return
;
; Display ADC value
;
ShowAdc:
        swapf   ADC_Value,W
        call    PutHexNibble
        movf    ADC_Value,W
        call    PutHexNibble

        movlw   0x0D
        call    Putc
        movlw   0x0A
        call    Putc

        call    WaitForSend
        return
;
; Power On Reset starts here
;
start:
;
; Set internal oscillator to 8 MHz
;
        movlw   0x60
        movwf   OSCCON      ; Set internal oscillator to 8MHz

        clrf    INTCON      ; Disable interrupts
;
; Set all outputs to zero
;
        movlw   0x01
        movwf   LATA       ; Set TXD high
        clrf    TRISA
        movlw   0x07
        movwf   PORTA      ; Set TXD high

        clrf    ANSELA      ; Make all GPIOs digital I/O
        clrf    WPUA        ;
        clrf    IOCAN       ;
        clrf    IOCAP       ;
        clrf    IOCAF       ;

        movlw   0x5F        ; Set OPTION register
        movwf   OPTION_REG  ; TIMER0 clocks source is FCYC
                ; Pull-ups enabled

        clrf    PIE1        ; Disable all peripheral interrupt sources
        bcf     TRISA,0     ; Make RA0(TXD) an output
        bsf     TRISA,1     ; Make RA1(RXD) an input
        bsf     WPUA,1      ; Enable pull up on RXD (RA1)
        bsf     IOCAN,1     ; Enable interrupt on change of RXD (RA1)

;
; Initialize UART state
;
        bcf     INTCON,TMR0IE
        clrf    UART_State
;
; Initialize application status flags
;
        clrf    App_Status
;
; Setup FVR and Temp Indicator
;
        movlw   B'10110001'
        movwf   FVRCON
;
; Setup ADC
;
        bsf     PIE1,ADIE   ; must be enabled to wake from sleep
        
        movlw   B'11111000' ; Set ADC clock as FRC, select Temp Indicator as input channel
        movwf   ADCON
        bsf     ADCON,ADON
        bcf     PIR1,ADIF
        bsf     INTCON,PEIE
;
; We wake from sleep because the ADC
; interrupt request is asserted.
;
        bsf     INTCON,GIE
;
; Show the ADC value by default
;
        bsf     ADC_Show_Sample
;
; Print the power on message
;
        call    ShowSignOnMessage
;
; This is the main process loop
;
ProcessLoop:
;
; Check process flags and sleep when idle
;
        btfsc   INTCON,TMR0IE
        goto    ProcessAwake    ; do not sleep when UART is running

        btfsc   RX_DataAvailable
        goto    ProcessAwake    ; do not sleep when UART RX data is available

        btfsc   ADC_Sample
        goto    ProcessAwake    ; do not sleep when ADC is sampling

        bsf     ADCON,GO_NOT_DONE ; start an ADC conversion
        sleep                   ; sleep and wait for an interrupt
        nop
        nop
;
; Process loop is awake
;
ProcessAwake:
        btfsc   RX_DataAvailable
        call    ProcessCharacter

        btfsc   ADC_Sample
        call    ProcessAdcSample

        goto    ProcessLoop

PowerOnMessage:
        dt      "PIC10F322 Analog input demo",13,10
        dt      "Samples ADC inputs TI, FVR",13,10
        dt      "Type:",13,10
        dt      " 'A' ADC ON/OFF",13,10
        dt      " '6' ADC in TI",13,10
        dt      " '7' ADC in FVR",13,10
        dt      " '?' show this message",13,10
        dt      0
        end

I am waiting for some PIC10F322 chips to arrive so I can test this in a real part. It does work in the simulator but with the MPLABX simulator you can never know. Do try this code to see if you get the same ADC values.
 
If this code works you should be able to see the ADC values directly from the PIC10F322 using a serial terminal application running on your development system.
post edited by dan1138 - 2015/07/31 01:56:31
#46
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/31 00:53:45 (permalink)
0
I have done one more test.
Instead of my PIC18F4550 + OLED as serial terminal, I attached to the test setup one MAX232 connected to an USB-RS232 and to PC. Then I used RealTerm as serial capture program and I get continuously next sequence:
 
253 53 254 119 255 82 253 52 254 119 255 72 253 53 254 119 255 82
 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 11
9 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 5
3 254 119 255 82 253 52 254 119 255 72 253 52 254 119 255 72 253 53 254 119 255
82 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254
119 255 82 253 52 254 119 255 72 253 52 254 119 255 72 253 53 254 119 255 82 253
 53 254 119 255 82 253 53 254 119 255 82 253 52 254 119 255 72 253 53 254 119 25
5 82 253 53 254 119 255 82 253 52 254 119 255 72 253 53 254 119 255 82 253 53 25
4 119 255 82 253 53 254 119 255 82 253 52 254 119 255 72 253 53 254 119 255 82 2
53 52 254 119 255 72 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 119
255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 53
254 119 255 82 253 52 254 119 255 72 253 52 254 119 255 72 253 52 254 119 255 72
 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 53 254 11
9 255 82 253 53 254 119 255 82 253 52 254 119 255 72 253 52 254 119 255 72 253 5
3 254 119 255 82 253 52 254 119 255 72 253 52 254 119 255 72 253 52 254 119 255
72 253 53 254 119 255 82 253 52 254 119 255 72 253 53 254 119 255 82 253 53 254
119 255 82 253 53 254 119 255 82 253 53 254 119 255 82 253 52 254 119 255 72 253
 53 254 119 255 82 253 53 254 119 255 82
 
Here we see how I send 253 as first ID for the first data following as 52 or 53. That is ADCfvr.
Then comes 254 followed by 119 as ADCti and finally 255 with 82 which is calculated temperature inside the PIC10F322 with an offset of 120, so what I see on OLED display is -38. ADCfvr and ADCti I see them on OLED as above.
 
Now, with MAX232 and PC I would like to test your proposed code. I use the same MPLABX 3.05 and there is MPASM v5.62 inside.
As I am not an ASM boy, I would need some help with next error which I get when I try your code:
 
nbproject/Makefile-default.mk:78: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/viki2000/MPLABXProjects/Dan_TEMP_ASM_1.X'
make[2]: *** No rule to make target 'build/default/production/Dan_TEMP_ASM_1.o', needed by 'dist/default/production/Dan_TEMP_ASM_1.X.production.hex'.  Stop.
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
 
I checked next
http://microchip.wikidot.com/mplabx:no-rule-to-make-target
but I still get the error.
post edited by viki2000 - 2015/07/31 01:05:57
#47
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/31 01:24:24 (permalink)
+7 (4)
Some minutes later i found the problem. Don’t tell to anyone, the source  file used was with extension .c instead of .asm. Now is fine.
The ASCII that I receive now on PC with RealTerm are 78 most of them time and 77 sometime.
I use only pin RA0 PGD of PIC10F322 to look at the data.
post edited by viki2000 - 2015/07/31 01:29:28
#48
dan1138
Super Member
  • Total Posts : 3021
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/31 01:44:36 (permalink)
0 (3)
viki2000
Some minutes later i found the problem. Don’t tell to anyone, the source file used was with extension .c instead of .asm

Oh no, I won't tell a soul. :)
 
viki2000
The ASCII that I receive now on PC with RealTerm are 78 most of them time and 77 sometime.
I use only pin RA0 PGD of PIC10F322 to look at the data.

The hex number 78 is 120 decimal. It sure looks like the PIC10F322 parts you have are far from the "typical" device they used for AN1333.
post edited by dan1138 - 2015/07/31 01:45:40
#49
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/31 01:57:46 (permalink)
0
Some minutes later, I connected also the pin RA1 PGC to interact with the keyboard.
Your code is working good from interaction point of view and shows the help screen and next data:
For ADCti “6” shows 78 and for ADCfvr “7” shows 34.
And that was the "30th piece is marked 1142, meaning production year 2011 week 42, clear a different lot, the one  which gave the result -44°C, 120 ADCti."
So we get the same result with different code and different serial communication setup.
I will try few more chips, but I guess we know now how the situation is with the error spread for the internal temperature indicator, because I believe the test results above with 60 such PIC10F322 are correct.
post edited by viki2000 - 2015/07/31 02:05:46
#50
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/31 02:26:13 (permalink)
0
2 random PICs PDIP-8 with “the production code 1213, meaning year 2012 and week 13” show:
ADCfvr=34 ADCti=8B, which in decimal become ADCfvr=52 ADCti=139, which translated in volts and degrees become 5.02V and 26.6°C
ADCfvr=35 ADCti=8A, which in decimal become ADCfvr=53 ADCti=138, , which translated in volts and degrees become 4.93V and 31.1°C
 
Then I took 2 random PICs SOT-23-6, purchased few months ago, no idea for the moment about production code, but I expect 2015 for sure, because Microchip could not deliver last year by the end of the year.
They show the same values as follows.
ADCfvr=34 ADCti=77, which in decimal become ADCfvr=52 ADCti=119, which translated in volts and degrees become 5.02V and -47.98°C.
 
There are the same results as with the C code.
The error spread is big without calibration as in the above charts.
#51
Nikolay_Po
Super Member
  • Total Posts : 1839
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/07/31 05:08:02 (permalink)
0 (1)
I think you shouldn't use °C units until the calibration of each chip (or at least each silicon batch). You have proved this already. -48 or +31 have no sense here.
#52
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/03 04:58:21 (permalink)
0
It depends to whom we address the results.
For example, it make no sense for the people here who supposedly passed through the explanations and tests above.
For a first time reader or for my boss who cannot understand the code, but can understand references to Celsius degrees, then for results communication make sense the usage of Celsius degree in discussion together with the charts above.
 
@Dan
For the further readers, I tried to implement a C code which give the same results/interactivity similar with your ASM code for easier understating. Because XC8 has no RS232 bit-bang function implemented, I used this time CCS C compiler. Of course the code is a lot bigger than assembly, but I tested it on the same hardware setup and works.
The “show menu” text/strings takes a lot of ROM memory.
#include <10F322.h>
#use delay(internal=16000000)
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1)
unsigned int8 ADCfvr, ADCti, TEMP, time1s;
//unsigned int16 ADCfvr, ADCti, TEMP;
char ch;
int1 ST;

void main(){
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_oscillator(OSC_16MHZ);
   setup_timer_0(T0_INTERNAL|T0_DIV_256|T0_8_BIT);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   delay_ms(1);
   time1s=0;
   ST=1;
   ch=63;

   while(TRUE){
      ch = getc();
   }
}

#int_timer0
void T0_ISR(){
set_timer0(0);
time1s++;

if(ch==63){//? - show menu
   printf("PIC10F322 Analog input demo\n\r");
   printf("Samples ADC inputs TI, FVR\n\r");
   printf("Type:\n\r");
   printf(" 'a' ADC ON/OFF\n\r");
   printf(" '6' ADC in TI\n\r");
   printf(" '7' ADC in FVR\n\r");
   printf(" '?' show this message\n\r");
   ch=0;
}

if(ch==65){ //A - START/STOP
   ST=!ST;
   ch=0;
}
if(time1s==61){ //check for approx. 1s delay
  if(ST){
      set_adc_channel(FVR_CHANNEL);
      setup_vref(VREF_1v024);
      delay_ms(1);
      ADCfvr=read_adc();
      delay_ms(1);

      setup_vref(TEMPERATURE_INDICATOR_ENABLED | TEMPERATURE_RANGE_HIGH);
      set_adc_channel(TEMPERATURE_INDICATOR);
      delay_ms(1);
      ADCti=read_adc();
      delay_ms(1);
// TEMP = 459-(194*(255-ADCti)/ADCfvr);
      if(ch==55) //7 - show ADCfvr
        TEMP=ADCfvr;
      if(ch==54) //6 - show ADCti
        TEMP=ADCti;
// printf("%x", TEMP);
      putc(TEMP);
      putc('\n');
      putc('\r');
  }
   time1s=0;
}
clear_interrupt(INT_TIMER0);
}

 
If we cut the first 2 lines of the menu to gain ROM memory:
//   printf("PIC10F322 Analog input demo\n\r");
//   printf("Samples ADC inputs TI, FVR\n\r");
 
Then the ADCfvr and ADCti may be displayed in decimal if we replace
putc(TEMP);
with
printf("%u", TEMP);
post edited by viki2000 - 2015/08/03 05:17:40
#53
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/03 06:54:52 (permalink)
+3 (2)
I opened a Microchip ticket with the next question:
-What is the maximum temperature error guaranteed or estimated using internal temperature indicator when no calibration is performed?

I got the next answer:
-Not tested or specified.

Under such circumstances the datasheet should mention at the end of the chapter Temperature Indicator Module next warning:

based on AN1333:

 
 And confirmed by 60 PIC10F322 measurements at 25°C, 30 with SOT-23-6 package and 30 with PDIP-8 package:


#54
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/05 03:46:45 (permalink)
+1 (1)
I asked Microchip about +/-19% FVR tolerance.
The answer:
If you are looking for a device with a Fixed Voltage Reference the 10F322 device is obviously a device you do not want to use. Instead I would recommend having a look at some of the following devices. All devices listed below should be 8 pin devices.
PIC12F1571
PIC12F1501
PIC12F1572
PIC16F18313
PIC12F1822
PIC12F1840

 
But I need SOT-23-6.
#55
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/06 22:53:34 (permalink)
0
Me:
Page 174 of the datasheet, parameter AD06 VREF – Reference Voltage with Note 3 and Note 5.
Note 3 refers to FVR as reference input and Note 5 specify it as 2.048V or 4.096V.
But on page 84, chapter 15.1.3 is mentioned "The FVR is only available as an input channel and not a VREF+ input to the ADC."
http://ww1.microchip.com/...eviceDoc/40001585C.pdf
Is it not that a contradiction?
Which one is true?

 
Microchip:
Our apps team has confirmed that Note 5 on page 174 is indeed an error. It has been marked for correction.
In regards to Note 3, it is intended to be a generic statement and is found is most if not all our data sheets. If you don't have the ability to select a positive voltage reference other than Vdd, than Vdd is your selection. It could be worded better.

#56
dan1138
Super Member
  • Total Posts : 3021
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/09 01:20:29 (permalink)
+2 (1)
There are other inconsistencies in the data sheet.
 
http://ww1.microchip.com/downloads/en/DeviceDoc/40001585C.pdf
 
On page 168 in TABLE 24-7: OSCILLATOR PARAMETERS, parameter OS08 specifies the frequency tolerance of the HFINTOSC as ±3% for (0°C <= TA <= +85°C, VDD >= 2.3V), and -8% to +4 for (-40°C <= TA <= +125°C). On page 169 FIGURE 24-6: HFINTOSC FREQUENCY ACCURACY OVER DEVICE VDD AND TEMPERATURE, suggests much less precision for the internal oscillator. If I am reading this figure correctly for (0°C <= TA <= +85°C, VDD >= 2.3V) the accuracy is ±6.5% and outside of this range -15% to +12%.
 
After testing the PIC10F322 temperature input of some real parts I've found the usable range of ADC values to be so small that even after two point calibration the part seem more like a toy than a tool.
 
The data sheet issues along with the behavior of the temperature input the PIC10F322 seems unsuitable for even low precision temperature sensing applications.
#57
viki2000
Super Member
  • Total Posts : 344
  • Reward points : 0
  • Joined: 2013/05/08 16:54:07
  • Location: Germany
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/11 02:36:17 (permalink)
0
Could you publish your results?
Since almost 2 weeks I have on my desk the setup with PIC10F322 communicating with PIC18F4550 attached to the small display showing ADCti, ADCfvr and temperature without calibration. The VDD is 4.9xxx not very stable for the 3rd and/or 4th decimal point.
The ADCfvr is jumping up/down 1 digit 52/53.
The ADCfti is jumping up/down 1 digit 139/140.
The calculated temperature jumps between 27-39°C.
By calculation, and also practical, I noticed a jump of 1 digit error of ADCfvr leads to 8°C error and 1 digit error of ADCti leads to 4°C error.
It does not matter the value or if it is calibrated, important is the range of imprecision.
 
If we trust the datasheet and consider the FVR tolerance +/-19%, then we are in trouble when the VDD is not constant and we want to determine the VDD value. The error is too big to be usable.
It is enough to take 1 example of VDD=5V and supposing we do not know that is 5V, so we want to find how much is it by measuring it using FVR as described in AN1072
http://ww1.microchip.com/downloads/en/AppNotes/01072A.pdf
ADCfvr=1.024*((2^n)-1)/VDD=1.024*255/5=52.224, so we can say ADCfvr must show 52 or 53  as my system shows.
With FVR +/-19%,  we get instead of 1.024 two values 0.82944 and 1.21856.
Then the ADCfvr may be ADCfvr1=0.82944 *255/5=42,30 or ADCfvr2=1.21856*255/5=62.14, so we can take ADfvr1=42 up to ADCfvr2=62.
If we calculate back the VDD, supposing you do not know it is 5V, then you get VDD1=1.024*255/42=6.21V and VDD2=1.024*255/62=4.21V
With this big error range of 4.21-6.21V finding the VDD when is not stable or known we arrive to such big errors in measuring the temperature, only due to FVR tolerance, that makes it totally unusable.
For stabilized VDD=5V , mode 4 and 27°C we should get for ADCti the value 139 – calculated.
Assuming the ADCti is stable 139 with zero tolerance, because the VDD is in reality 5VDC even if was measured with error 4.2-6.2V, then for the calculated  temperature we get for VDD1 and VDD2 between -76°C up to +96°C. Just use ADCti=139 and ADCfvr1=42 and ADCfvr=62 in the formula from previous page assuming we have VDD=5V and 27°C in reality. That is 172°C range.
That leads clear to the fact that even with calibration we cannot use temperature indicator on PIC10F322 with unknown VDD and AN1333 makes no sense at all for this PIC as long as FVR tolerance is +/-19%.
The temperature indicator inside PIC10F322 must be used at known VDD without FVR.
post edited by viki2000 - 2015/08/11 04:21:53
#58
Nikolay_Po
Super Member
  • Total Posts : 1839
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/11 05:08:29 (permalink)
0
I can't understand why you're trying to calculate the temperature directly, parameter by parameter?
The chip has two bandgaps: one is temperature compensated (FVR) and one is not (temperature sensor). They both are produced by the same process on the same die. The only thing you need to calibrate is the relation between of this two bandgaps vs the temperature. The supply voltage is out of the braces. You needn't even bother by tolerance of FVR or dispersion of temp.sensor output.
Just try to compare the relations of different chips at the temperatures of interest. Yes, the quantization error is huge. But it may be acceptable to define very hot or very cold cases.
post edited by Nikolay_Po - 2015/08/11 05:10:29
#59
dan1138
Super Member
  • Total Posts : 3021
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: Internal Temperature Indicator - PIC10F322 2015/08/11 09:25:53 (permalink)
+2 (1)
viki2000
Could you publish your results?

The range of ADC values for the Temperature Indicator from the 10 sample PIC10F322 parts I have are lower that the "typical" part described in AN1333.
 
The PIC10F322 has only an 8-bit ADC, as such the usable range of values for temperatures between -40°C to +85°C is very limited.
 
These are the values for the largest possible span of the PIC10F322:
VDD     = 3.30
MODE    = 4.00
ALPHA   = 0.778 (value corrected for my specific lot of parts)
BETA    = 0.00132
FORMULA = [ALPHA-(VDD/MODE)*(1-<ADC>/255)]/BETA-40

ADC   Temp °C
14  = -41.3
15  = -38.8
16  = -36.4
17  = -33.9
18  = -31.5
19  = -29.0
20  = -26.6
21  = -24.1
22  = -21.7
23  = -19.2
24  = -16.8
25  = -14.3
26  = -11.9
27  = - 9.4
28  = - 7.0
29  = - 4.5
30  = - 2.1
31  =   0.4
32  =   2.8
33  =   5.3
34  =   7.7
35  =  10.2
36  =  12.6
37  =  15.1
38  =  17.5
39  =  20.0
40  =  22.4
41  =  24.9
42  =  27.3
43  =  29.8
44  =  32.2
45  =  34.7
46  =  37.1
47  =  39.6
48  =  42.0
49  =  44.5
50  =  46.9
51  =  49.4
52  =  51.8
53  =  54.3
54  =  56.7
55  =  59.2
56  =  61.6
57  =  64.1
58  =  66.6
59  =  69.0
60  =  71.5
61  =  73.9
62  =  76.4
63  =  78.8
64  =  81.3
65  =  83.7
66  =  86.2

 
As you can see there are at most 53 values of ADC readings in the 125°C temperature range from -40°C to +85°C.
 
This means under the best of all possible modes the PIC10F322 temperature resolution is 125/52 or ±2.4°C per ADC count.
 
Unfiltered ADC reading tend to have an error ±1 count. This means that the best achievable temperature resolution for the PIC10F322 temperature indicator will be at least ±4.8°C.
 
With some low pass filtering this could be ±2.4°C if the sample size is about 100 ADC readings.
 
With the system error so high actual data from any lot of parts seems irrelevant.
post edited by dan1138 - 2015/08/11 12:09:11
#60
Page: < 123 Showing page 3 of 3
Jump to:
© 2019 APG vNext Commercial Version 4.5