I am using dsPIC33EP64MC202-I/SP to read analog inputs with the code shown below. It is using a 2.5V voltage reference on pin5 (VREF+) as ADC reference voltage. When I connect 1.1V to pin3 (AN0) ADC1BUF1 (CH0) reads 0x1F5, which converts to 1.223V (501*(2.5/1024)). AN3 (CH0) reads 0x3FF, which seem correct. What is causing the error in reading AN0?

To test the voltage reference, I changed the code to use AVDD (connected to 3.3V) as voltage reference by setting AD1CON2bits.VCFG = 0. Then AN0, ADC1BUF1 reads 0x155 = 341*(3.3/1024) = 1.099V, which is the correct answer.

So I am wondering why the 2.5V reference is not working as expected?

void initAdc() {
    ANSELAbits.ANSA0 = 1;       // set AN0/RA0 as analog input
    ANSELAbits.ANSA1 = 1;       // set AN1/RA1 as analog input
    ANSELBbits.ANSB0 = 1;       // set AN2/RB0 as analog input
    ANSELBbits.ANSB1 = 1;       // set AN3/RB1 as analog input 2.5V
    TRISAbits.TRISA0 = 1;       // set AN0/RA0 as input
    TRISAbits.TRISA1 = 1;       // set AN1/RA1 as input
    TRISBbits.TRISB0 = 1;       // set AN2/RB0 as input
    TRISBbits.TRISB1 = 1;       // set AN3/RB1 as input 
    /* Initialize ADC module */
    AD1CON1 = 0;
    AD1CON1bits.SIMSAM = 1;     // Simultaneous sampling 
    AD1CON1bits.SSRC = 7;       // Auto convert
    AD1CON1bits.ASAM = 1;       // auto sample 
    AD1CON2 = 0;
    AD1CON2bits.CHPS = 2;       // all four channels
    AD1CON2bits.ALTS = 0;       // Always uses channel input selects for Sample MUXA. MUXB not used
    AD1CON2bits.VCFG = 1;       // External VREFH = VREF+, VREFL = Avss 
    AD1CON3 = 0;
    AD1CON3bits.SAMC = 0x1f;    // Auto-Sample Time for 31 TAD
    AD1CON3bits.ADCS = 0x0f;    // TAD = 16TP

    AD1CON4 = 0;

    /* Assign MUXA inputs */
    AD1CHS0bits.CH0SA = 3;      // Channel 0 Positive Input Select for Sample MUXA bits
                                // Channel 0 positive input is AN3
    AD1CHS0bits.CH0NA = 0;      // Channel 0 negative input is VREFL 
    AD1CHS123 = 0;              // CH1 = AN0 (voltage FB), CH2 = AN1 (I_OUT), CH3 = AN2 (temp) 
    /* Enable interrupts */
    IFS0bits.AD1IF = 0;
    IEC0bits.AD1IE = 0;

    /* Enable ADC module and provide ADC stabilization delay */
    AD1CON1bits.ADON = 1;
} //initAdc
  • \$\begingroup\$ Check the errata sheet. ww1.microchip.com/downloads/en/DeviceDoc/80000533M.pdf \$\endgroup\$ Aug 8, 2018 at 14:48
  • \$\begingroup\$ @JohnBirckhead I checked the errata sheet. I don't see any relevant items for the issue I am seeing. Please explain - thanks. \$\endgroup\$
    – TreeCity
    Aug 8, 2018 at 17:40
  • \$\begingroup\$ I wasn't sure if item 16 applied - possibly not \$\endgroup\$ Aug 8, 2018 at 18:12
  • \$\begingroup\$ Can you be more explicit about the error you are seeing. In other words spell it out succinctly. \$\endgroup\$
    – Andy aka
    Aug 8, 2018 at 18:26
  • \$\begingroup\$ You have the comparators disabled? \$\endgroup\$ Aug 8, 2018 at 18:57

2 Answers 2


With external 2.5V ADC reference, when I connect 1.1V to AN0, it reads 1.223V (501*(2.5/1024)) in SW. But the actual voltage connected is 1.1V. This is error I am trying to troubleshoot.

ADCs are not perfect and you should probably take a few more measurements. Here are where the errors can arise: -

  • Basic measurement error i.e. DVM not quite perfect
  • Reference voltage not 2.5 volts but maybe a bit lower
  • ADC Zero error - can be in the realm of 1% and is sometimes specified in LSBs
  • ADC Gain error - full scale can be "out" by +/- 1% on a lot of ADCs and this happens even though the reference accuracy may be perfect.
  • Integral non-linearity error - divergence from the perfect straight line that represents gain. This can be several LSBs in magnitude
  • Differential non-linearity - this is the factor that dictates how imperfect the step accuracy is. Think of it like a staircase where the height/depth of each step has a random factor involved.

If you add all these up, you might approach a total error of maybe 5% and 5% in a full-scale of 2.5 volts, is 0.125 volts of potential error and can turn a real input voltage of 1.1 volts to 1.225 volts as perceived digitally.


I had a similar problem with an PIC24HJ128GP504 and a LM4050-3.3 as external ADC reference. I discovered that the voltage of the LM4050 dropped from 3.3 V to 3.05 V as soon as the ADC started to use it. The reason: I chose a 4k7 resistor to operate the LM4050 at 5 V with 360 µA - this is within the range of 45 µA to 20 mA and seemed reasonable for 10 µA flowing into the ADC. The solution: After reading the manual more carefully I realised that this is the current while ADC is OFF - obviously the LM4050 circuit was not able to keep the 3.3 V stable when loaded. As I found no information for the real current while ADC is ON I used a 1k and the issue was gone.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.