DC load when ADC enabled

If I drive an analog input from a high-impedance source, I expect it to be accurate but slow. That’s not what I’m seeing.

If I connect only a 100K resistor to ground, I expect the ADC value read to be 0 (or close to it). I’m seeing 821. If I connect the 100K resistor to 3V3*, I see 3273, not 4095. Similarly, 1M down and up gives 2035 and 2197, and 10K down and up read out as 117 and 3966. It seems as if a STM32 analog input pin has the Thevenin circuit of a 149K resistor connected to a 1.65V source when I do an analogRead(). If I replace the resistor with a 0.1uf cap, it charges to 1.65V with about a 6ms time constant.

Digging a little deeper, after reset, there is essentially no load on pins set to INPUT. (My voltmeter reads 0.000 volts.) After the first analogRead(), it jumps up as if driven by 149K and 1.65V. The specific call within analogRead() where the loading begins is “ADC_SoftwareStartConvCmd(ADC1, ENABLE);”. The loading persists after I stop calling analogRead(). Indeed, after switching the pin mode to OUTPUT and driving high or low, and then back to INPUT, the loading resumes. Only if I call ADC_Cmd(ADC1, DISABLE) does the loading disappear. So it would seem to be something in the ADC circuitry that is gated by the ADC enable bit.

My (imperfect) understanding of the ADC input is that it should appear as a ~4pf capacitor behind a 16-21K resistor (Rain = 15K, Radc = 1.5-6K). The spec mentions no DC issues (e.g., input bias current). Nonetheless, I see it being pulled to the midpoint between 3V3* and ground.

This loading makes the ADC useless for sensing high-impedance sources (e.g., thermistors), and is different from any other analog input I’ve ever seen. I must be missing something simple. Any ideas?

My circuit couldn’t be much simpler:

      PIN A7 --- 100K --- Gnd

My code is simple as well:

 void setup()
 {
    pinMode(A7, INPUT);
    analogRead(A7);       // After this executes, pin A7 is pulled
 }                        // towards 3V3* / 2 by 149K
 void loop()
 {
 return;
 }
1 Like

First off, you should be using a resistor voltage divider with a fixed resistor and the thermistor, or better yet a bridge to get good measurements.

In order to speed up the ADC, the internal capacitor is charged to the middle of the supply rail. That way it takes half the time to do the conversion, either up or down from that point, than it would otherwise. This input impedance of the ADC is not that simple to model since it is switched, but 40k-100k ohm is a number to keep in mind.

You have a couple of options:

  • Use a 10K rather than a 100K thermistor with another resistor in a divider.
  • Use an op-amp or instrumentation amp before the ADC input to buffer your high-impedance sensor (This is essentially built-in on the Arduino ATMEL parts).
  • Use a special purpose thermistor/thermocouple IC
  • Use an external ADC that you like better.

Here is another thread were this was discussed with some links to op-amp circuits.

1 Like

Thanks…it makes sense for the STM32 to precharge the capacitor to the halfway point for speed. I had not thought of that. Presumably the voltage I’m seeing on the analog pin arises in some way from this precharge voltage. But I’m still confused by two things:

  1. Precharging is usually done sequentially before sampling the external input, not at the same time. The external circuit should not see the precharge voltage…only the capacitor should. They certainly should not fight each other.

  2. I still do not have an explanation for getting incorrect data values. I don’t think precharging or having a high driving impedance explains the wrong data. I increased the sample time to 239.5 clocks and saw no change. I added a 0.1uf cap between A7 and ground and saw no change. Either of these should have compensated for a high source impedance if that was the issue. A 10KΩ source impedance at 0.0V or +3.3V should be low enough to get accurate results, yet I got 117 and 3966, not 0 and 4095.

  3. The sampling gate conducts for a few cycles (e.g., 7.5 or 239.5), connecting the analog pin with the capacitors. After that, it stops conducting until the next conversion. But I see 1.65 volts on the analog pin continuously with my voltmeter (if nothing else is connected). How can that the pin still be driven to that voltage minutes or hours after the sampling?

Thanks for your many thermistor suggestions, but thermistor was just an example of a typical source in the 10KΩ resistance range; I’m actually doing a moisture sensor, where the resistance ranges from an insulation-limited near infinity (100MΩ?) down to a few megohms or less. Since speed is not an issue, I can add a small capacitor to reduce the apparent source impedance, and increase the sample time as well. (Since I have many channels, I would prefer not to add an op amp circuit for each.) But with the precharge voltage driving out of the analog pin, a high impedance source is simply overwhelmed.

Might there be some way to have misconfigured the ADC so that the precharge phase persists into the sampling time (and beyond)?

HI @graphics_guy

This circuit is never going to work well:

You are depending on the leakage current of the ADC input to set the voltage across the sensor.

You want something more like this:

           R1               R2
3v3*-----/\/\/\---Pin A7---/\/\/\-----Gnd

Where either R1 is the sensor and R2 is fixed or vice versa. The 3v3* pin on the core is the filtered supply used for the ADC reference.

Thanks for replying; I appreciate your thoughts. My example circuit: “Pin A7 — 100K — Gnd” was just an experiment to try to understand the analog pins characteristics.

What I’m seeing is unexpected. The STM32F20xxx electrical spec says that I/O pins have ±1 μA of bias current, but I’m seeing 6.5μA coming out of A7 with this trivial circuit. It is far too large to be bias current, and it doesn’t behave as a voltage-independent bias current, but a 1.65V source with a 149K resistance. So 6.5μA of current flows out if my resistor goes to ground or 6.5μA flow in if my resistor goes to 3V3*.

Other than bias current, any ideas what is happening? Thanks!

You need to look at Figure 38 of the STM32F103 datasheet where a simplified diagram of the ADC input is shown. Table 46 shows that the external input impedance depends on the sampling mode but never exceeds 50k ohm. Current goes into or out of the ADC input depending on the voltage being above or below 3.3V/2 = 1.65V, the value the ADC input first sample and hold capacitor is pre-charged to. This cap is labelled Cadc in the simplified diagram in Figure 38. This is a simplified diagram that does not show the switching action or the second sample-and-hold-stage.

Thanks! I have indeed looked at Figure 38 quite a bit. It shows no DC source other than the ±1 μA bias current “IL”. The datasheet has no mention of any precharging of Cadc, but assuming it is precharged, 4pf cannot sustain current for vary long. (The time constant for 4pf and 1.5K as Radc is 6 nanoseconds.) So I’m still mystified where my continuous 6.5μA is coming from.

Equation 1, for calculating the allowed driving impedance (Rain), evaluates to 440KΩ if I use 239.5 sampling cycles. That should, in theory, give enough time for Cadc to be charged to within 1/4 LSB of the 12-bit ADC value. If I accept somewhat less accuracy, the impedance can in theory be many times higher than that. Table 47, however, simply labels Rain values for long sample periods as “NA”, and Table 46 lists 50KΩ as a maximum Rain, but defers to Equation 1 for “details”. It’s not clear to me which is the real limit. Even at 50KΩ, 6.5μA gives a 0.325 volt error. Ugh!

So I still have no explanation for the 6.5μA coming into or out of the pin continuously as long as the ADC is enabled. I guess I’ll have to design around it.

Did this ever get resolved? I’m wondering if I need to build an input buffer circuit to measure a 0 to 600V signal or if a 2Mohm voltage divider would suffice.

There is nothing to “resolve” here–the ADC on the ST32 parts just works the way it does. In some circuits, the way the onboard ADC works can be a problem and an op-amp is the easiest fix.

If you want to connect 600V to any microcontroller, I would recommend a good deal of isolation since that is instantly fatal. This is a challenging design not to be undertaken lightly. Please get professional advice.

1 Like

Here’s the diagram and numbers from the STM32F205xx datasheet.

As far as getting advice from a professional; would you consider yourself to be a professional? If so what would your general advice be in ensuring isolation for high voltage circuits? I was thinking an in-line quick-blow fuse (off board of the PCB) as well as a zener to sink current temporarily while the fuse is blowing in case a resistor from the input gets shorted. Or are you talking more about the possibility of maintenance providers getting zapped when touching the board?

Yes, I am a professional engineer, but no, I am not looking for consulting work right now, thanks.

If you think the Photon exploding from 600V across it is the biggest problem, I would say you need to hire someone (else) right away! I would look for someone who has experience with UL, EN 50178 and IEC 61010-1certification of high-voltage circuits and enclosures.

There are life safety problems, noise problems, hardening the ADC input problems, flammability problems and none of these are solved by fuses and zener diodes.

2 Likes

Haha, I wouldn’t be able to pay you anyways (you sound expensive)!

I don’t have any experience with the Photon, just the Electron, but I’m guessing that the ADC is pretty similar.

There are many potential problems that high voltage can cause, and I agree that someone getting zapped is definitely the biggest one of them all. Thanks for pointing me towards a few of the relevant safety standards dealing with high voltage.

Do you think it makes sense to hire someone with experience designing high voltage circuitry towards the beginning or more towards the end of the design process?

For now, looks like its time to hit the StackExchange forums for some advice!

1 Like

@jaza_tom, to reiterate what @bko said, 600 volts is unforgiving, even at low current and will, simply put, kill or seriously injure. Just accessing 600v panels requires a certified electrician. This is why they put that equipment in locked rooms behind locked panels. And don’t get fooled by DC versus AC. DC will kill just the same.

If you want to play in that realm, you should look at what is currently commercially available to get an idea of what is involved. The issue is not the ADC input, its the fact that you want to measure a potentially lethal voltage.

2 Likes

Hmmm… not convinced that accessing 600V panels requires a certified electrician. I worked in the solar industry for the last 3 years and have worked on PV arrays that put out over 500V. But point taken.

Our application likely won’t get too bogged down in certifications and safety doctrine since it will be an off-grid application in a location where electricians simply don’t exist.

@jaza_tom, liability is liability. However, looking at what commercial products do my give you some ideas on methods and sensors to use to avoid the entire high voltage issue. If you look at automotive circuit design, you will find ways of protecting processor inputs using a variety of methods, typically combined. DC voltages in cars can spike quite high though not as high as 600V.

1 Like