Electronic – Measure PIC’s own VDD-in voltage with ADC

adcpic

  • 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.)

Best Answer

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