Wrong voltage reading with analogRead when ceramic capacitors are in the circuit

Hi everyone, first time i post here. I've built a small circuit to see how different capacitors would filter a pulsating signal at different frequencies. To do that i used analogRead pins to read the voltage. The readings are fine without the capacitors (it reads 5v when OUTPUT pin is high and 0 v when is low) and with the 100uf electrolytic capacitor (with a frequency of 1hz and 20k ohm resistance the results match with an LTSpice simulation of the circuit), but with the 100nf ceramic capacitor, instead of getting results similar to those with no capacitor, analogRead reads basically a constant voltage, while it obviously isn't (i've put an LED in series with the resistors and it turns on and off like it should).
Any idea why this happens?

Weird voltage reading:

No words, show a schematic.

Always show us a good schematic of your proposed circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.

Couldn't post more than 1 image per post, here is the schematic:

here is the actual connection:

here is also the code if it can help:

For a filter you need this arrangement.

Isn't it basically the same thing? I've put the Load resistors after the capacitor and a diode before it because i wanted to replicate the filtering that happens in power supplies... anyway it doesn't explain why analogRead doesn't read the voltage correctly with the 100nf ceramic capacitor

Attach sketches using code Tags </> from the posting menu, not images

So you are feeding 1Hz signal into the circuit ?

1 Like
boolean A = false;
boolean B = false;
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

  Serial.begin(9600);
  
}

void loop() {
  if (A == false) {         
  delay(4000);             
  digitalWrite(13, HIGH);
  A = true;                 
  }
  
  

  if (B == false) {
    digitalWrite(13, LOW);
    int Lettura0 = analogRead(A0);
    float Volt0 = Lettura0 * (5.0 / 1023);
    delay(1000);
    Serial.println(Volt0);
    B = true;
 }

else {
digitalWrite(13, HIGH);
int Lettura1 = analogRead(A5);
float Volt1 = Lettura1 * (5.0 / 1023);
delay(1000);
Serial.println(Volt1);
B = false;
}
}

Yes, i am feeding an 1hz signal right now , but the weird reading also happens with all the frequency i tested: 0.5hz (the one in the graph above), 10hz and 50hz

At very low frequencies:

100uF should give a DC voltage.

100nF should give almost a square way.

No capacitor will be a square wave.

BTW feeding an Arduino output to a large valued capacitor needs caution.

That's exactly what happens on the circuit, but when using the small 100nf capacitor analogRead reads basically a perfect DC voltage even at very low frequency, when it should read, as you said, almost a square wave.
If i put an LED in series with the load resistors with low frequency when using the small 100nf capacitor, it obviously turns on and off like it should, but AnalogRead instead of reading 4.38V and then almost 0V reads 4.38v and then 4.28v, which is obviously incorrect

BTW 100uf isn't a very large capacitor

could be an issue with being unable to read the AD fast enough to show on/off/on/off???

Yes it is but in this case your load is a very large resistance.

If you are expecting to see an oscilloscope type display on the serial monitor, it wont be happening.

BTW
This is what you would get on a scope at 50Hz input with your circuit 100nF capacitor.

to prevent floats from being converted to ints, I learned to make sure all the ints in a float calculation are cast as floats.
Such as float Volt1 = (float)Lettura1 * (5.0 / 1023.0); is more likely to result in a float.

1 Like

I'll try putting a 10ms delay between the analogReads and when i change B to either true or false, although the weird thing is that with the bigger capacitor everything works fine.

Edit: tried it, nothing changes.... regardless of the frequency it keeps reading 4.37 to 4.27 with that small capacitor

On the serial monitor i should see the highest voltage and then the lowest voltage, because when the output pin is high the voltage is just constant, while when the output pin is low i am measuring the voltage immediately before the voltage is again set to high... this is working fine with the large capacitor, while with the smaller one the reading is weird:
e.g this is the 100uf electrolytic capacitor at 0.5 hz and the high and lows match the graph in the first post

The time constant for the 100nF circuit is very short.

The serial monitor cannot keep up.

Graphing with the serial monitor will not give satisfactory results.

Also, you do know using delay( ) will screw this up supremely.


Haven’t tried here, but PWM not delay( ) should make some difference.

That is not true:

When you call Serial.print you are printing the value that was captured at the time analogRead was called - just after the digitalWrite.
Of course this does not explain behavior of the 100nF cap. I suspect some wiring mistake (e.g. no connection to the pull-down resistor).
This also explans the observed behavior. Note the "tooths" has an opposite polarity when some cap is present vs no capacitor. When no cap is present the minimum is when D13 pin is LOW and maximum when the pin is HIGH - simple. But with a capacitor it is reversed:
At the moment you turn D13 LOW the capacitor is charged and the pull-down starts slooowly discharging it. At the moment you sample it and measure nearly supply voltage.
After this the capacitor discharges during the looong delay. When you turn the pin HIGH it starts charging quickly - but not instantly. The small 100nf cap charges nearly to Vcc before the sampling but the large 100uF cap is only about halfway charged before it is smapled.