# How to simulate sigma-delta ADC pulse train in LTspice

I am trying to simulate a complete current sense path of a motor phase, right from the shunt resistor to the MCU in LTspice.

We are using an AMC1303 (50 mV differential)(MPN: AMC1303M0520DWV) sigma-delta ADC to measure the current. The pulse train coming out of the ADC (digital) is filtered to get analog values (0 to 3.3 V), and then it is sent to the internal ADC of an MCU.

The problem that I am facing is that the duty cycle of the pulse train is not changing with time (Net: duty_cycle, DOUT).

But if I give DC values from I1, it works perfectly.

Digging a little further I found that .params in LTspice can't be evaluated as a function of time. Is there any other way to simulate the pulse train correctly?

• I'm still not clear on what you're trying to do, but I can try throwing something out there. You can use the time keyword, which represents the current simulation time, within the expression for an "Arbitrary Behavioral Voltage or Current Source". See that specific LTspice topic for more info on that. Commented Feb 27, 2023 at 5:09
• Hello Ste, just to add on further if it is not clear, if we provide a sine wave at the inputs of the adc, example(50mV), at the output that sine wave should translate to a square wave(at the DOUT pin of the adc) of 20 MHz period , with a varying on period. The on period varies from 89.06%(50mV) to 50%(0 mV) to 10.94%(-50mV) as per the datasheet. I am trying to implement this in LTSpice. The problem here is if i give a fixed value(dc value) of 50mV, i see the duty cycle of 89.06% coming correctly, but when i give a time varying signal such as a sine wave, the duty cycles do not change!!
– AK47
Commented Feb 27, 2023 at 8:31
• Uhhh...I don't think that helped clarify anything. You just repeated the same information. It doesn't matter, though. I stared at your circuit long enough that I believe I reverse-engineered your intent. Your setup doesn't represent what you want to do. Current source I1 and resistor R11 don't do anything in your circuit. If you delete them, the circuit will simulate identically. Easiest way to get what you want is to replace V8 with a B-source (bv symbol) and use some boolean math. If I get time later to re-draw your circuit and figure out an example solution, I'll post an answer. Commented Feb 28, 2023 at 20:02

Your circuit setup doesn't represent what you want to do. You made a statement within your question which highlights a misunderstanding of how .param and other evaluated expressions work, so I'll try to clarify that first.

Here is a simplified version of your schematic which only includes the relevant items:

Before the simulation begins, any expression enclosed within "curly braces" (the { and }) are evaluated to constant values. So your circuit actually looks like this right before it runs:

To summarize in words, the input parameters current and shunt are used to find vsh. Then vsh is used to find dt. And finally, dt is used to find Ton which is a constant used as the "on time" for your PULSE voltage source (in this case: 5.55335u).

Where the confusion seems to be is that you are expecting the current source and resistor to impact how the PULSE voltage source operates. However, if you look at the "evaluated" schematic, you can see that I1 and R1 in no way whatsoever impact V1. They run entirely independently. In fact, if you delete both I1 and R1 the DOUT node will still show the same exact signal as it did before. In addition, you cannot change the parameters of any PULSE source mid-simulation. They always have to be predefined and constant. So your overall approach here is invalid for those two reasons.

The crux of the problem is you're trying to use independent current/voltage sources as dependent current/voltage sources. You need a dependent/behavioral source and/or some kind of circuit that uses voltages/currents from the first circuit to create the output you desire. What you want to do actually has some nuance to it. You can't change Ton mid-period, so maybe it's best to try to sample and hold Ton right at the beginning of each period of the pulse train. This is what I came up with which seems to meet your requirements. There are of course others ways to do this, and this is just one of them.

The idea here is to use A1 (a sample&hold; found under [SpecialFunctions]) to sample the vshunt value and hold it for one full period of your pulse train (50us). V1 is a square wave clock signal which triggers this sampling on its rising edge. The top plot pane shows this behavior.

Then, a reference ramp voltage vref is generated to compare your on-time shaping function [(50u*((V(vsamp)*771.2)+49.6667)/100)] against. This is a sawtooth wave which has a delay of 1us compared to the sampling clock such that each sample is stable before any comparisons can happen. The middle plot pane shows this behavior.

The B-source B1 then does the actual comparison (notice the > sign) and scales it by 3.3 so your DOUT swings between 0V and 3.3V. The bottom plot pane shows this final output.

Below is the LTspice .ASC file schematic as text so you can copy/paste it in a text file and open it up in LTspice to play around with it. One last note: the .options plotwinsize=0 is there to disable waveform compression because it was screwing up the plot of vramp.

Version 4
SHEET 1 1540 680
WIRE 848 -16 816 -16
WIRE 816 32 816 -16
WIRE 80 96 0 96
WIRE 144 96 80 96
WIRE 384 96 144 96
WIRE 384 128 272 128
WIRE 0 144 0 96
WIRE 144 144 144 96
WIRE 272 144 272 128
WIRE 624 144 560 144
WIRE 816 144 816 112
WIRE 384 160 304 160
WIRE 0 272 0 224
WIRE 144 272 144 224
WIRE 304 272 304 160
WIRE 912 272 816 272
WIRE 816 304 816 272
WIRE 304 400 304 352
WIRE 816 416 816 384
FLAG 0 272 0
FLAG 144 272 0
FLAG 272 144 0
FLAG 80 96 vshunt
FLAG 816 416 0
FLAG 304 400 0
FLAG 816 144 0
FLAG 848 -16 vref
FLAG 912 272 DOUT
FLAG 624 144 vsamp
SYMBOL current 0 224 R180
WINDOW 0 24 80 Left 2
WINDOW 3 24 0 Left 2
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName I1
SYMATTR Value SINE(0 {current} 1k)
SYMBOL res 128 128 R0
SYMATTR InstName R1
SYMATTR Value {shunt}
SYMBOL SpecialFunctions\\sample 464 128 R0
SYMATTR InstName A1
SYMBOL voltage 304 256 R0
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName V1
SYMATTR Value PULSE(0 1 0 1n 1n 25u 50u)
SYMBOL bv 816 288 R0
SYMATTR InstName B1
SYMATTR Value V=3.3*((50u*((V(vsamp)*771.2)+49.6667)/100)>V(vref))
SYMBOL voltage 816 16 R0
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName V2
SYMATTR Value PULSE(0 50u 1u 50u 1n 1n 50u)
TEXT -48 -40 Left 2 !.param current=-100\n.param shunt=500u
TEXT -168 336 Left 2 !.tran 3m
TEXT -248 384 Left 2 !.options plotwinsize=0