I am trying, and failing, to measure phase in LTSpice. I've used the suggestion here
.tran 0.00001 0.5
.meas TRAN time_1 TRIG V(N001)=0 RISE=1 TD=0.4 TARG V(N001)=0 RISE=2 TD=0.4
.meas TRAN time_2 TRIG V(N001)=0 RISE=1 TD=0.4 TARG V(N002)=0 RISE=1 TD=0.4
.meas phase param 360*time_2/time_1
but the result isn't very accurate, even for the simple RC filter in the picture below.
How should I be doing it?
Note that the actual phase I need to measure is in a slightly more complex circuit, but I've reduced it to a simple circuit that seems to have the same problem.
Best Answer
The measurements should be fine, there is no one way to rule them all. You can use:
just as well and it will give you what you want. It is assumed you are in the steady-state (the reason for adding
td
).The problem is that you are using
.tran 10u 0.5
probably thinking that you are imposing a timestep, but that's not what it does. It can be misleading, I agree. For an imposed timestep, you have to use:This, by itself, will help, but not much. By default, LTspice uses a waveform compression algorithm which limits the number of plotted points to 1024. For your case,
0.5/10u = 50k
points, which will be reduced, so to disable waveform compression, either alter the option inControl Panel > Compression > Window size(No. of Points)
(the setting is not remembered during sessions), or add:to the schematic. This is the preferred way, since it is remembered for any schematic that uses the option (and can be easily toggled between a SPICE directive, and a comment). The downside is that, with waveform compression off, the
.raw
file will grow and grow. One cure for that is to use the.save
command.Another thing that you can do to increase the accuracy is to use:
Any number greater than
6
fornumdgt
enablesdouble
precision data points, whilemeasdgt
sets the number of digits for the.meas
.An
.AC
analysis is recommended for frequency domain measurements (as mentioned by Bimpelrekkie), if possible (there are times when it's not). If it is possible, using.ac list 500
will work fir this case. One thing to remember is that the number of.AC
points is limited to 65536.For those cases when it's not possible, regarding imposing an even smaller timestep, there is a workaround. If your circuit has a long settling time, imposing a very small timestep will mean possible hours of simulation and many GB of storage. There may be a trick to avoid that: don't set a timestep, instead set up a
PULSE()
source with a delay>=
settling time, and with a period<=
the smallest desired timestep. This way, the simulation will fly during the transient, and will crawl during the steady-state.For example, given the circuit in your picture, the 1% settling time should be after some 46 ms, so set up a source with
PULSE 0 1 50m 1u 1u 1u 4u
. This will impose a 1 µs timestep since the timepoints for the source are known, which means the solver will have to reduce the timestep to accomodate these.The advantage is that it can also be turned on or off:
If it only has to be turned off, then specifying the number of periods will do, but be careful with this: since the timepoints need to be known, that means there will be a delay before the simulation starts caused by calculating these timepoints. This only happens if the number is large (i.e. many timepoints to calculate). If the number of periods is not specified, the engine knows it only needs a simple repeating pattern of a few timepoints.
If it needs to be turned on and off, then use the keyword
trigger
:PULSE 0 1 50m 1u 1u 1u 4u trigger V(x)>0.3
, whereV(x)
is some controlling voltage. It's pretty self-explanatory, but for the sake of future readers, ifV(x)
is from another source, e.g.SIN 0 1 10
, then thePULSE()
source will be turned on everytime `V(x)>0.3, and off otherwise.