# Trying to Create a Schmitt Trigger Component in ModelingToolkit.jl

**URL:** <https://discourse.julialang.org/t/trying-to-create-a-schmitt-trigger-component-in-modelingtoolkit-jl/99503>\
**Category:** Modelling & Simulations\
**Tags:** question, modelingtoolkit, circuits, electricalcomponent\
**Created:** [May 28, 2023, 3:26am UTC](https://discourse.julialang.org/t/trying-to-create-a-schmitt-trigger-component-in-modelingtoolkit-jl/99503 "2023-05-28T03:26:21Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![astra\_kawa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/astra_kawa/32/204424_2.png) [@astra\_kawa](https://discourse.julialang.org/u/astra_kawa)\
**Post date:** [May 28, 2023, 3:26am UTC](https://discourse.julialang.org/t/trying-to-create-a-schmitt-trigger-component-in-modelingtoolkit-jl/99503/1 "2023-05-28T03:26:22Z")

</div>

Hello all. I am trying to create a [Schmitt trigger](https://en.wikipedia.org/wiki/Schmitt_trigger) component in ModelingToolkit.jl. Specifically the circuit in the image below ([source](https://howtomechatronics.com/how-it-works/electrical-engineering/schmitt-trigger/)):

 ![Screenshot 2023-05-27 at 10.57.29 PM](https://global.discourse-cdn.com/julialang/original/3X/2/a/2a246e24ac94c51e1790cebb6fb6ddd8653cbc1b.png)

I am using the `IdealOpAmp` component from the MTK standard library, I am assuming it is setup in the same way as the figure below ([source](https://rodanski.net/ben/work/symbolic/opamp_models.html)):

 ![Screenshot 2023-05-27 at 10.59.27 PM](https://global.discourse-cdn.com/julialang/original/3X/f/0/f01edf200d85a342495ec4b59e9e628d3fe1141d.png)

However I am running into some problems with my code:

```julia
using ModelingToolkit
using ModelingToolkitStandardLibrary
using DifferentialEquations
using Plots

const B = ModelingToolkitStandardLibrary.Blocks
const E = ModelingToolkitStandardLibrary.Electrical
@parameters t

@named R1 = E.Resistor(R = 1)
@named R2 = E.Resistor(R = 2)

@named voltage_signal = B.Sine(frequency=1, amplitude=10)
@named source = E.Voltage()

@named op_amp = E.IdealOpAmp()

@named ground = E.Ground()

@named output_pin = E.OnePort()

eqs = [
    connect(voltage_signal.output, source.V)
    connect(source.p, R1.p)
	connect(source.n, ground.g)
    connect(R1.n, op_amp.p1)
	connect(R1.n, R2.p)
    connect(ground.g, op_amp.n1)
	connect(ground.g, op_amp.n2)
	connect(R2.n, output_pin.p)
	connect(op_amp.p2, output_pin.p)
	connect(output_pin.n, ground.g)
]

@named model = ODESystem(
	eqs, t; systems = [R1, R2, voltage_signal, source, op_amp, ground, output_pin]
)

sys = structural_simplify(model)

prob = ODEProblem(sys, [], (0, 10.0), [])

```

I get the following error when running the `ODEProblem` function:

```julia
ArgumentError: Equations (1) and states (0) are of different lengths. To allow these to differ use kwarg check_length=false.

#check_eqs_u0#150@abstractsystem.jl:1672[inlined]
var"#process_DEProblem#548"(::Bool, ::Nothing, ::Nothing, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Symbolics.SerialForm, ::Bool, ::Bool, ::Bool, ::Base.Pairs{Symbol, Integer, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:t, :has_difference, :check_length), Tuple{Int64, Bool, Bool}}}, ::typeof(ModelingToolkit.process_DEProblem), ::Type, ::ModelingToolkit.ODESystem, ::Vector{Any}, ::Vector{Any})@abstractodesystem.jl:621
var"#_#555"(::Nothing, ::Bool, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{SciMLBase.ODEProblem{true, SciMLBase.AutoSpecialize}}, ::ModelingToolkit.ODESystem, ::Vector{Any}, ::Tuple{Int64, Float64}, ::Vector{Any})@abstractodesystem.jl:719
ODEProblem@abstractodesystem.jl:712[inlined]
#_#553@abstractodesystem.jl:699[inlined]
ODEProblem@abstractodesystem.jl:698[inlined]
#ODEProblem#552@abstractodesystem.jl:695[inlined]
ODEProblem@abstractodesystem.jl:694[inlined]
top-level scope@Local: 1[inlined]

```

Setting the keyword argument `check_length=false` results in another error when running `solve`:

```julia
Mass matrix size is incompatible with initial condition

sizing. The mass matrix must represent the `vec`

form of the initial condition `u0`, i.e.

`size(mm,1) == size(mm,2) == length(u)`

size(prob.f.mass_matrix,1): 1

length(u0):

Some of the types have been truncated in the stacktrace for improved reading. To emit complete information

in the stack trace, evaluate `TruncatedStacktraces.VERBOSE[] = true` and re-run the code.

get_concrete_u0@solve.jl:1197[inlined]
var"#get_concrete_problem#46"(::Base.Pairs{Symbol, Union{Nothing, Vector{Float64}}, Tuple{Symbol, Symbol}, NamedTuple{(:u0, :p), Tuple{Nothing, Vector{Float64}}}}, ::typeof(DiffEqBase.get_concrete_problem), ::SciMLBase.ODEProblem{Nothing, Tuple{Float64, Float64}, true, Vector{Float64}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, ModelingToolkit.var"#f#522"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xb7b77d1d, 0x7ab1eaa7, 0x99752a83, 0x405ba9ae, 0xa2972979), Expr}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x25da9c91, 0x42425f27, 0xecfdcda6, 0x60e772c3, 0xcf06bdb2), Expr}}, Matrix{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Vector{Any}, Symbol, Vector{Symbol}, ModelingToolkit.var"#570#generated_observed#530"{Bool, ModelingToolkit.ODESystem, Dict{Any, Any}}, Nothing, ModelingToolkit.ODESystem}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Bool)@solve.jl:1059
get_concrete_problem@solve.jl:1056[inlined]
#solve_up#30@solve.jl:969[inlined]
solve_up@solve.jl:945[inlined]
#solve#28@solve.jl:882[inlined]
solve@solve.jl:872[inlined]
top-level scope@Local: 1[inlined]

```

I am not an expert with electronic circuits, so I am unsure if my connections are setup correctly. Or let me know if there are other/better ways to model the behaviour of a Schmitt trigger using MTK. Any help with this would be greatly appreciated, thank you!

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [May 28, 2023, 4:38am UTC](https://discourse.julialang.org/t/trying-to-create-a-schmitt-trigger-component-in-modelingtoolkit-jl/99503/2 "2023-05-28T04:38:00Z")

</div>

The errors you are getting both stem from a typo:

```julia
	connect(R1.n, R1.p)

```

should be

```julia
	connect(R1.n, R2.p)

```

But even after that, this [ideal op-amp model](https://github.com/SciML/ModelingToolkitStandardLibrary.jl/blob/main/src/Electrical/Analog/ideal_components.jl#L149) won’t produce a Schmitt trigger. This model enforces the constraint that there is no current or voltage difference between the inputs, but does not enforce that the sign of the gain is positive. A Schmitt trigger circuit also needs the property that the output sign is the same as the input sign (infinite gain) and the non-ideality that the op-amp has limited output voltage.

You might try connecting a Voltage Sensor to a Voltage Source (with a limiter) via a large gain to produce a more appropriate ideal op-amp for this circuit.

Edit:  
A plot after correcting the typo:

```julia
soln = solve(prob)
ts=0:0.05:10
plot(soln(ts; idxs=[0, source.v, output_pin.v]))

```

![nogainconstraint](https://global.discourse-cdn.com/julialang/original/3X/1/1/112feb257a5d11cde25f1b193b1d8b4c12d177cf.png)

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [May 28, 2023, 4:38am UTC](https://discourse.julialang.org/t/trying-to-create-a-schmitt-trigger-component-in-modelingtoolkit-jl/99503/3 "2023-05-28T04:38:19Z")

</div>

MTK might struggle with this system since it does not contain any differential equations, and thus no state variables. You could try connecting an inductive or capacitive load to the output port and see if that works?

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [May 28, 2023, 4:40am UTC](https://discourse.julialang.org/t/trying-to-create-a-schmitt-trigger-component-in-modelingtoolkit-jl/99503/4 "2023-05-28T04:40:22Z")

</div>

I have been pleasantly surprised by how well it deals with this and just solves the (perhaps nonlinear) system and produces a useful answer. But it definitely produces more interesting answers when there are stateful dynamics!
