sharpie7 / circuitjs1

Electronic Circuit Simulator in the Browser
GNU General Public License v2.0
2.23k stars 619 forks source link

Unusual behavior of sampling capacitor through analog switch when use trapezoidal approximation #929

Open ericfont opened 3 months ago

ericfont commented 3 months ago

Here is a simple circuit of an input voltage going through a clocked analog switch that gets sampled by a capacitor:

circuit-20240307-1340

The expected behavior would be that the when the switch closes, the capacitor's voltage quickly charges though the switch's small 20 ohm internal resistance to gets set to whatever the input is when the switch is closed and then holds that value when the switch is open. But instead the capacitor's voltage is doing a strange dance when it jumps up to double to 10V and gradually over many clock cycles gradually approaches the input's 5V level:

image

The issue isn't as pronounced when I use larger capacitor values. Also the issue pretty much goes away if I uncheck "trapezoidal approximation" in the capacitor's edit menu. So it quite possibly is simply a limitation of the "trapezoidal approximation", and in which case it may not be considered a bug. I'm also wondering maybe "trapezoidal approximation" shouldn't be used by default if it produces such glitches...

pfalstad commented 3 months ago

Yes, this is exactly the problem with trapezoidal approximation, and why there's a checkbox to turn it off. Trapezoidal is more accurate for circuits without analog switches (or the equivalent), and I thought those would be more common, so that's why I made it the default. The accuracy difference is pretty small though, so maybe I should turn it off by default.

ericfont commented 3 months ago

Ah. Well I'm thinking the type of glitch I experienced from trapezoidal is a dramatically greater "inaccuracy", even though it only occurs with circuits with the equivalent of analog switches. (Now that you mention that, I recall seeing a similar glitches in other circuits with similar types of switching...)

It took me a while to ponder this strange behavior and to take a guess to turn off trapezoidal, but an electronics beginner would be even more confused by it and might misinterpret the circuit functionality. I consider circuitjs to be more suited for getting reasonable behavior rather than most accurate (users can use spice if accuracy is most desired, or even protype it is real world behavior is desired), so I would suggest to disable trapezoidal by default. But you are the maintainer, so you be the judge.

ericfont commented 3 months ago

I'm also observing that the glitch with trapezoidal decreases as the simulator's time step size is decreased, such that when reduced to 100 ns, then it is just a one pixel difference in the scope. So maybe as an alternative solution would be for the simulator to automatically detect if this glitch is going to be noticeable and to automatically decrease the time step size...but that might be too involved of a solution.

ericfont commented 3 months ago

I'm noting the glitch also happens with a regular mechanical switch (in addition to the "analog switch"), for instance with the following circuit:

circuit-20240307-1839

If I repeatedly toggle the switch with my mouse, the capacitor's voltage will randomly jump up either to 10 V or down to 0 V, when it should always just remain at the voltage it was at when the switch was closed:

image

I can't quite figure out the pattern of whether it jumps up or down, but I'm guessing the direction it jumps may be due to the exact time that the switch toggling in relation to the simulator tick.

I am also noting that I can produce the glitch while the simulator is running by manually removing the wire between the voltage source and the capacitor:

circuit-20240307-1847

...for instance when deleting it:

circuit-20240307-1847 (1)

or also by dragging the wire away to disconnect the capacitor:

circuit-20240307-1849

I think this was how I've experienced the glitch before.

Anyway I'm more and more thinking that the trapezoidal approximation should be disabled by default. And then only if the user deliberately knows what they are doing, then they can manually enable the approximation.