• Processor: PIC18F66K22
  • Compiler: C18 (XC8 is fine also)

I've just made (and succesfully tested) code to measure the voltage on AN4 analog pin.

Now I want to try something else, not quite sure if it's theoretically possible.

My test-board has a PIC processor, with VDD,AVVD connected to a supply (ranging from 0(if the battery is empty/disconnected) to 4,2(full battery).

Can I use ADC to measure the VDD(-in) of my board?

Why not?:

  • It's not an ANx pin, not sure how to make the ADC measure it? (Channel?)
  • If the voltage on VDD(-in) drops, will my ADC reference voltage also drop? (So when my PIC only gets 3,3V the ADC will still say it's 100% (as the max Voltage on the chip, also the reference is 3,3V).

Why/what do you ask?:

  • Can I just measure Channel 30 (VDDCORE)?
  • Could I set my Vref to Vdd and measure a precision voltage reference with the A/D converter. (Not sure how)
  • Or I could add a wire from VDD-in to an ANx pin?

  • Will Internal VREF+ (4.096V) stay 4+V when the VDD-in is around 3,4V? Is there some kind of transformator that makes it so?

  • Internal VREF+ (4.096V) is a bit lower than the max of the battery (4,2V), does this mean I can damage the ADC? Or just that the result will be max when the battery is full. (4,2V out of 4,096V)

Please mind that my knowledge of Electronics is "low". I've learnt way more about the software part in my education, but I'd like to know more about (Embedded) Electronics as it's a crucial part in Embedded Engineering. (It's sad how my school doesn't see this.)


1 Answer 1


That PIC has an internal 1.024V bandgap reference, selected by setting the Channel Select bits to 11111.
So if you set your ADC module's reference to Vdd and then tell it to measure the 1.024V reverence, you can infer back to what your Vdd actually is.

Normally you would work out the voltage on a pin which you've A2D'd with something like:
Vin = (ADCval/ADCrange)*Vref

But in this case its Vin which you know (1.024v) and you want to solve for Vref (your Vdd), so:
Vref = (Vin * ADCrange)/ADCval
or more specifically for your case:
Vdd = (1.024 * 4096)/ADCval

  • \$\begingroup\$ I'll give this a try! ((tomorrow)and put this as answer if it works) Another collegua pointed out that it had a "Bandgap reference" Thanks for the insight on the calculation for the 'scale', didn't know that! \$\endgroup\$
    – aaa
    Commented Mar 19, 2015 at 15:52
  • \$\begingroup\$ Perfect! Thanks for the theory in combination with the specific details, this was fixed in a matter of minutes, thinking & testing took more time as the actual development (after your answer). \$\endgroup\$
    – aaa
    Commented Mar 20, 2015 at 8:18

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.