Is it possible to perform a simulation with parametric sweep?


I am trying to perform a simulation in the current nightly build similar to what I do in LTspice. My point is to find some parameter and use this parameter as the value of the component, for example the position of the potentiometer.

I would like to achieve something like this in KiCad combined with NGspice:


This is what my scheme looks like, I’m trying to sweep the pos parameter…

Here is the potentiometer model:

.subckt RPOT 1 2 3 value=10k pos=0.5
R2 2 3 {value * pos + 0.001}
R1 1 2 {value * (1 - pos) + 0.001}

I am quite certain this can be done, but for details you will have to read the 700+ page ngspice manual.

Note that ngSpice has been developed independently of KiCad for many years and only a small portion of it is accessible via clicking on GUI items, and a lot of the other things are accessible via adding text strings. ngSpice also has it’s own scripting language for example.

I am only just a beginner with ngSpice myself. Below an excerpt of the ngSpice manual:

15.3.2 .DC: DC Transfer Function
General form:
. dc srcnam vstart vstop vincr [ src2 start2 stop2 incr2 ]
. dc VIN 0.25 5.0 0.25
. dc VDS 0 10 .5 VGS 0 5 1
. dc VCE 0 10 .25 IB 0 10 u 1 u
. dc RLoad 1 k 2 k 100
. dc TEMP -15 75 5

The .dc line defines the dc transfer curve source and sweep limits (with capacitors open
and inductors shorted). srcnam is the name of an independent voltage or current source,
a resistor, or the circuit temperature. vstart, vstop, and vincr are the starting, final,
and incrementing values, respectively. The first example causes the value of the voltage
source V IN to be swept from 0.25 Volts to 5.0 Volts with steps of 0.25 Volt.

This is the part of the ngspice documentation that deals with parameter sweeps: .step

Repeated analysis in ngspice is offered by a short script inside of a .control section (see
Chapt. 17.8.8) added to the input file. A simple application (multiple dc sweeps) is shown

Input file with parameter sweep

parameter sweep
* resistive divider , R1 swept from start_r to stop_r
* replaces . STEP R1 1 k 10 k 1 k
R1 1 2 1 k
R2 2 0 1 k
VDD 1 0 DC 1
. dc VDD 0 1 .1
. control
let start_r = 1 k
let stop_r = 10 k
let delta_r = 1 k
let r_act = start_r
* loop
while r_act le stop_r
alter r1 r_act
write dc - sweep . out v (2)
set appendwrite
let r_act = r_act + delta_r
plot dc1 . v (2) dc2 . v (2) dc3 . v (2) dc4 . v (2) dc5 . v (2)
+ dc6 . v (2) dc7 . v (2) dc8 . v (2) dc9 . v (2) dc10 . v (2)
. endc
. end

In LTspice it was enough to do something like this: .step param X list .1u .2u .3u

Does anyone have experience with how to incorporate a .control block into a simulation in KiCad?

Currently the .step command is not implemented in Eeschema/ngspice.

You may run a .control script in Eeschema, the simulation is done in a loop, but you cannot access the resulting data in the Eeschema plot window. You may store them elsewhere and use standard ngspice for plotting, like in the following example:

You may also use Eeschema for schematic entry, and then start standard ngspice to run the simulation and plotting. Unfortunately this is still broken in 7.99 (at least for MS Windows), see 7.99 Calling external simulator stalls Eeschema (#15446) · Issues · KiCad / KiCad Source Code / kicad · GitLab). You may give the issue a ‘thumbs up’ for more developer attention. You also should pose a request for the .step command on the issue tracker.

More about .control sections is found in the ngspice control language tutorial .

I think the issue here is that although this example works like a charm, ngspice limits to one single value that can be user for the alter line be it in the textbox be it if the netlist is run via command line.

So I think we cannot see this as a solution to run via control (which is the ngspice solution to the .step in other simulators) to model the cursor of a potentiometer.

What about a pot emulated by R1 and R2 as two resistors in series with wiper in he middle (10k pot):

set controlswait
write acout.out all
set appendwrite
setplot const
let r0=5k
let r1=5k
let dr=1k
repeat 3
  let r1=r1-dr
  let r2=r2+dr
  alter R1 r1
  alter R2 r2
  write acout.out all