Shop OBEX P1 Docs P2 Docs Learn Events
P2 ADC question — Parallax Forums

P2 ADC question

JRoarkJRoark Posts: 1,215
edited 2020-08-06 02:32 in Propeller 2
@JonnyMac posted some Spin code in his "Nuts & Volts" article that reads ADC pins and returns the value. I did a quick translation to FlexBASIC (which works fine) and then added some trivial features.

The question I have is this: In the following code if I swap "P_ADC_1X" to "P_ADC_10x", shouldn't this result in a range of 0-0.330 volts instead of 3.3v? (ie, 10x)? If I do this, that simple subsitution breaks the code and I don't understand why. All it returns is a full-scale reading, even when the pin is driven by 0.125 volts. Smart pin docs seem to be a little sketchy on this. Can anyone shed some light on why this does not work?

Here is the code:
SUB ADCStart(pin_num as ulong) 

	direction(pin_num) = input				' reset smart pin
	wrpin(pin_num, P_ADC OR P_ADC_GIO)			' read ground reference
	wxpin(pin_num, %00_1101)				' 8192 samples, 14 bit resolution, SINC2 filter
	wypin(pin_num, 0)
	pinlo(pin_num)						' enable
	waitcnt(getcnt() + 8192 << 3)				' allow 8x readings
	ADC.CalLO(pin_num) = rdpin(pin_num)                     ' save ground cal level

	direction(pin_num) = input				' reset smart pin
	wrpin(pin_num, P_ADC OR P_ADC_VIO)			' read VIO reference
	wxpin(pin_num, %00_1101)				' 8192 samples, 14 bit resolution, SINC2 filter
	wypin(pin_num, 0)
	pinlo(pin_num)						' enable
	waitcnt(getcnt() + 8192 << 3)				' allow 8x readings
	ADC.CalHI(pin_num) = rdpin(pin_num)			' save VIO cal level

	direction(pin_num) = input				' reset smart pin  
	wrpin(pin_num, P_ADC OR P_ADC_1X)			' read the pin voltage <=== THIS LINE
	wxpin(pin_num, %00_1101)				' 8192 samples, 14 bit resolution, SINC2 filter
	wypin(pin_num, 0)
	pinlo(pin_num)						' enable
	
END SUB

If I need to post the entire program, I will, but this is the bit that seems to be misbehaving. The complete program configures 58 pins for ADC input and displays all 58 values every 5 seconds.

EDIT: For clarity, this is running on a P2-EVAL with Rev B silicon using @ersmith FlexBASIC V4.2.7

Comments

  • AribaAriba Posts: 2,682
    JRoark wrote: »
    ...
    The question I have is this: In the following code if I swap "P_ADC_1X" to "P_ADC_10x", shouldn't this result in a range of 0-0.330 volts instead of 3.3v? (ie, 10x)?
    ...
    No, it's 0.33V around the mid point of the ADC (~1.65V), so you can measure something like 1.48..1.82 V.
    The calibration values are not directly usable, so this higher gain modes are mainly for AC measurements, like audio.

    Andy


  • @Ariba Interesting!

    As a point of clarification: So if you are trying to measure small voltages with anything other than P_ADC_1X, you would either need to run it through a voltage follower (maybe an op amp) with a DC offset towards ~1.65v, or we would need to capacitively couple the signal to the pin and use a weak voltage divider on the pin side in order to achieve the 1/2Vio bias?

  • AribaAriba Posts: 2,682
    You can use just a capacitor for AC coupling, the voltage divider is part of the internal ADC modulator circuit. (See the schematic of the Accessory-boards for Audio).

    For DC you will need to generate some offset, yes. Maybe the average of the LO- and HI-calibration values will be usable for correction of the mid-point drift in this case.

    Andy

  • evanhevanh Posts: 15,184
    A detail: Full scale, P_ADC_10X is closer to 0.5 Volts (1.4 to 1.9) than 0.33 Volts.
  • As an aside - I was surprised * shockingly * how accurate the P2 ADC converter was, when compared to my 4-1/2 digit voltmeter. Typically within 1 or 2 millivolts. Good Job Chip & Parallax team.
  • Not trying to highjack this thread, just curious how the P2 ADC pin would work with a 12V battery?

    It has been mentioned that there is some kind of voltage divider, is it capable of handling up to maybe 14V. Since I would like to data log battery activity, which would include charge/discharge cycles, would the P2 be able to do this.

    Ray
  • @PropGuy2 I was impressed as well. Chip & Company did a wonderful job on the ADC design. But I was surprised about current draw. Running 60 pins in 14-bit/8192-count/1x mode (running a single cog) draws 340 ma at 200 mhz and 525 ma at 330 mhz (with the red warning led on the USB flashing on and off). The chip gets quite warm, but not hot.

    I've got a clientless morning so I'll be playing with the 10x ADC mode shortly. Thanks to all for your input!
  • JRoarkJRoark Posts: 1,215
    edited 2020-08-06 16:04
    This was an eye-opener for me. @ariba and @evanh pointed me down the right path. Experimental (measured) results are below:
    • The P_ADC_3X input range is from 0.867v to 2.455v. 1.661v midpoint
    • The P_ADC_10X input range is from 1.40079v to 1.91163v. 1.65621v midpoint
    • The P_ADC_30X input range is from 1.57316v to 1.73787v. 1.65552v midpoint
    • The P_ADC_100X input range is from 1.62780v to 1.68242v. 1.65511v midpoint
    I'm not even going to attempt measuring in P_ADC_100X mode. 30x mode is all I can reasonably manage. (I'm using a potentiometer as a voltage divider to drive the pin and I've already had some caffeine). :) I went there but take the 100x numbers with a grain of salt.

    The ADCs seem to center around a 1.66v-ish reference voltage.

    I had read the ADCs could read slightly above and below the supply rails in P_ADC_1X mode. At a hard ground the ADC reports 2771 counts, and at the positive rail it reports 13,543 counts, so that seems to be born-out (and the code snippet by @JonnyMac for Nuts & Volts reflects this possibility in the way he does the pre-calibration).

    A fun morning! Many thanks to all for helping me get my brain sorted on ADCs.
  • Rsadeika wrote: »
    Not trying to highjack this thread, just curious how the P2 ADC pin would work with a 12V battery?

    It has been mentioned that there is some kind of voltage divider, is it capable of handling up to maybe 14V. Since I would like to data log battery activity, which would include charge/discharge cycles, would the P2 be able to do this.

    Ray

    That's actually where I'm going with this. I guess great minds think alike?

    I'll be using the 1X mode and feeding the Prop pin from a voltage divider in a 5:1 ratio. Whatever voltage the ADC measures, multiply it by 5 to get the real-world voltage. This gives a 0 to 16.5 volt battery range (not counting the area the ADCs can measure above the rails, which I haven't played with yet).


  • evanhevanh Posts: 15,184
    edited 2020-08-06 18:34
    JRoark wrote: »
    • The P_ADC_3X input range is from 0.867v to 2.455v. 1.661v midpoint
    • The P_ADC_10X input range is from 1.40079v to 1.91163v. 1.65621v midpoint
    • The P_ADC_30X input range is from 1.57316v to 1.73787v. 1.65552v midpoint
    • The P_ADC_100X input range is from 1.62780v to 1.68242v. 1.65511v midpoint
    ...
    The ADCs seem to center around a 1.66v-ish reference voltage.
    The voltage ranges are dependant on what the VIO voltage is. If the VIO supply is lowered to say 3.0 Volts then everything scales down by 10%, including the reference voltage point. So power supply noise and drift is a big factor with the ADCs. Temperature is also expected to have an impact.

    The one fixed number is the usable +0.3 Volts above VIO and -0.3 Volts below GND.

    EDIT: Had quoted the wrong piece.
  • :wink: Perhaps we can use an ADC pin to monitor the VIO drift :smile:
  • Ltech wrote: »
    :wink: Perhaps we can use an ADC pin to monitor the VIO drift :smile:

    I see what you did there... :smile:

  • evanhevanh Posts: 15,184
    edited 2020-08-07 13:07
    Oh, maybe it's only the reference that shifts with VIO. That's significant on its own of course. But the range is possibly defined by resistors only, because balancing is done in current mode rather than voltage mode. That would mean that, for example, P_ADC_10X will always be full range of 0.5 Volts.

    Honestly I'm not sure.

  • JRoarkJRoark Posts: 1,215
    edited 2020-08-07 14:10
    @evanh Until the docs are finished, we’re pretty much guessing. But rereading this thread it occurs to me that maybe I can meatball an experiment with what I already have.

    The ADCs are power hungry and act like a stiff on-board load. All together the board pulls ~500+mA with all of them running and the red warning light glowing. I’m presently driving the ADC inputs with a lab supply monitored by a 5-1/2 digit meter so this input value shouldnt change. By making two measurements of the same ADC pin, one with the 3.3 volt bus lightly loaded and the other with a heavy load, we can get a clue. If the 3.3 v buss drops a bit, and the ADC changes its output value accordingly, wouldnt that give us a clue the ADCs use a simple voltage divider as a reference?

    I’ll try this in a bit and post the result. The “new normal” of Covid means I’ve got time to play!
  • evanhevanh Posts: 15,184
    No question it's definitely a divider for the reference.

    The question remaining is about the supply volts on span/range, ie: What is the numerical readings of calibration at VIO and GIO at different supply voltages? Do the numbers stay roughly the same? That should answer the question but I haven't got any time to test it right now.

  • evanh wrote: »
    No question it's definitely a divider for the reference.
    The question remaining is about the supply volts on span/range, ie: What is the numerical readings of calibration at VIO and GIO at different supply voltages? Do the numbers stay roughly the same? That should answer the question but I haven't got any time to test it right now.

    Seems reasonable. I'll take a shot at this in a bit and report back.

  • jmgjmg Posts: 15,144
    edited 2020-08-14 02:29
    JRoark wrote: »
    The ADCs seem to center around a 1.66v-ish reference voltage.

    Yes, there is no band-gap voltage reference, it is just a 50% (matched resistors) divider from Vio, to create a mid-virtual-gnd, and every adc has their own 50% divider. (so that will vary from pin to pin, by the resistor matching )
    That also means power supply drift and noise * 50%, are added to the measurement.
    Rsadeika wrote: »
    Not trying to highjack this thread, just curious how the P2 ADC pin would work with a 12V battery?
    It has been mentioned that there is some kind of voltage divider, is it capable of handling up to maybe 14V. Since I would like to data log battery activity, which would include charge/discharge cycles, would the P2 be able to do this.

    You need to account for the 50% Vcc 'virtual reference' as the ADC measures relative to that.
    The very simplest 12V interface would be a single series resistor, but that would be less precise than a 2 resistor divider.
    With a single resistor you have internal fab-variance and temperature changes on the feedback resistor, but the dropper resistor does not track that.

    A 2 resistor divider would give you 0~24V range if you set 12V as mid point ~1.66V, if you needed less span than that, choices would be
    * A ~6V Zener + 2 resistors would give 6~18V span ( example PDZ6.8B,115 ±2% 500µA slope specified)
    * A '431'-like shunt regulator + 4 resistors would give 6~18V span, choose a better 431, with lower min current like the AS431 ±0.5% 50µA
    * An opamp + 5 resistors allows any gain/offset you like.

  • If you can intermittently drive the ADC pin as an output without interfering with whatever's attached (a voltage buffer with a resistor on the output should do the trick), you could probably calibrate 10x mode with a process like this:

    - Calibrate the ADC at full 1x scale
    - Measure the ADC's bias point with the %100010 mode that used to be PinB mode before Revision C
    - Have a neighboring smartpin read and filter the ADC's digital output bitstream, and configure the ADC pin's own smartpin to drive the output in %00111 NCO DUTY mode
    - Calibrate the DUTY output against the previously calibrated full-scale ADC by outputting a few different duty cycle values and seeing what voltages you get back
    - Put the ADC in in 10x mode
    - Calibrate the ADC, now in 10x mode, against the previously calibrated DUTY output by outputting a few voltages near the ADC's bias point and seeing what measurements you get back
    - Disable the DUTY output, allowing the input to work again, and use ADC pin's own smartpin (or its already-configured neighbor) to do ADC filtering on real input data
  • @Electrodude Would this require Rev B silicon exclusively?
  • ElectrodudeElectrodude Posts: 1,621
    edited 2020-08-07 22:15
    No. It would work best on Rev. C silicon; otherwise, on Rev. B, the neighboring pin would have to be floating in order for %100010 to measure the ADC's bias point. The ADC is reading its own analog pin A, but a nearby smartpin is in ADC filtering mode to process the digital bitstream. I haven't actually tried this, though.
  • evanhevanh Posts: 15,184
    Huh, the more testing I do, the more busted functions I'm discovering in my revB glob-top. This time it's the ADCs on pins P0-P3. No matter the voltage source nor gain nor sample period, P0 and P1 are returning solid 100% on their readings. With P2 and P3 returning solid 0% on their readings. Am sure glad I've got the finished revB to compare with.

  • jmgjmg Posts: 15,144
    evanh wrote: »
    Huh, the more testing I do, the more busted functions I'm discovering in my revB glob-top. This time it's the ADCs on pins P0-P3. No matter the voltage source nor gain nor sample period, P0 and P1 are returning solid 100% on their readings. With P2 and P3 returning solid 0% on their readings. Am sure glad I've got the finished revB to compare with.
    Do you mean the hardware inside the glob-top package is degrading over time ? Do the digital functions and pin-drive choices still work on those pins ?
    The package may not be moisture proof ?

  • evanhevanh Posts: 15,184
    I'd not tried to use them until now so I wouldn't know if those ADCs ever worked from the outset. What little I had done with the ADC hardware was usually on other pins. The VGA accessory is typically plugged into the first bank of I/O pins.

    BTW, latest finding is those four pins give valid ADC readings when VIO supply voltage is at 2.5 Volts.

  • evanhevanh Posts: 15,184
    edited 2020-08-09 04:14
    Well, at differing supply voltages, I'm seeing pretty constant numerical readings for VIO and GIO. So I guess they scale too, along with the reference. Makes my first statement the correct one - https://forums.parallax.com/discussion/comment/1502491/#Comment_1502491

    There is some change below 2.5 volts, presumably that's due to other factors though:
    - With VIO supply at 3.3 Volts, the readings are: VIO is 83.3% (13653+-445 of 16384) and GIO is 17.0%, (2788+-460 of 16384).
    - With VIO supply at 3.0 Volts, the readings are: VIO is 83.3% (13656 of 16384) and GIO is 17.1%, (2795 of 16384).
    - With VIO supply at 2.75 Volts, the readings are: VIO is 83.3% (13652 of 16384) and GIO is 17.1%, (2806 of 16384).
    - With VIO supply at 2.5 Volts, the readings are: VIO is 83.3% (13641 of 16384) and GIO is 17.2%, (2824 of 16384).
    - With VIO supply at 2.25 Volts, the readings are: VIO is 83.0% (13606 of 16384) and GIO is 17.5%, (2872 of 16384).
    - With VIO supply at 2.0 Volts, the readings are: VIO is 82.0% (13439 of 16384) and GIO is 18.3%, (3006 of 16384).
  • cgraceycgracey Posts: 14,133
    The ADC's need 3.3V to run properly.

    Also, if you go much below 3.3V, you unbias the level translators, unless you also drop the 1.8V core voltage. That could be why you were seeing 100% duty - no transitions were getting through.
  • evanhevanh Posts: 15,184
    edited 2020-08-13 09:22
    That odd behaviour was at regular 3.3 Volt supply via the Eval Board's LDOs. It only showed on pins P0-P3 and only with the glob-top package. The finished package prop2 is fine.

    I excluded those four pins from the above testing.

  • This may be a @cgracey question. The schematic below is derived from Chip's discussion of the ADC input section located here: https://forums.parallax.com/discussion/comment/1496007/#Comment_1496007

    My question is this: “what are the values of R1 and R2 in the attached schematic?". I can't find anything in the P2 hardware docs or on the forum that describes this.

    FWIW I’m trying to design an AFE that needs to know what impedence it is driving.
  • jmgjmg Posts: 15,144
    edited 2020-08-14 02:30
    JRoark wrote: »
    My question is this: “what are the values of R1 and R2 in the attached schematic?".
    FWIW I’m trying to design an AFE that needs to know what impedence it is driving.
    There are no R1,R2 in that location, that is a virtual earth (mid) point, so the impedance is the 540k to 50% of VIO.
    Provided the ADC is within range, that node is always very close to 50% of VIO.

  • JRoarkJRoark Posts: 1,215
    edited 2020-08-14 01:59
    Bingo. Thanks JMG. So its the same thing as if it was a virtual ground on an op amp. This is the piece I was missing.

    Somehow I erroneously read your answer above: “...Yes, there is no band-gap voltage REFERENCE. it is just a 50% (matched resistors) divider from Vcc, and every adc has their own 50% divider...” to apply to the input bias, not to the *reference*.

    I blame trifocals. Lol
Sign In or Register to comment.