Skip to content

Commit f059237

Browse files
Merge pull request #346 from langestefan/potentiometer
Add variable resistor component
2 parents c351837 + 2e4122a commit f059237

File tree

4 files changed

+144
-2
lines changed

4 files changed

+144
-2
lines changed

docs/src/API/electrical.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Inductor
3333
IdealOpAmp
3434
Diode
3535
HeatingDiode
36+
VariableResistor
3637
```
3738

3839
## Analog Sensors

src/Electrical/Analog/ideal_components.jl

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,91 @@ Temperature dependent diode based on the Shockley diode equation.
342342
i ~ Is * (exp(v / (n * Vt)) - 1) # Shockley diode equation
343343
port.Q_flow ~ -v * i # -LossPower
344344
end
345-
end
345+
end
346+
347+
"""
348+
VariableResistor(; name, R_ref = 1.0, T_ref = 300.15, R_const = 1e-3, T_dep = false)
349+
350+
Variable resistor with optional temperature dependency.
351+
352+
The total resistance R ∈ [R_const, R_const + R_ref], where pos is the
353+
position of the wiper and R_ref is the variable resistance between p and n.
354+
The total resistance is then:
355+
356+
R = R_const + pos * R_ref
357+
358+
If T_dep is true, then R also depends on the temperature of the heat port with
359+
temperature coefficient alpha. The total resistance is then:
360+
361+
R = R_const + pos * R_ref * (1 + alpha * (port.T - T_ref))
362+
363+
# States
364+
365+
- See [OnePort](@ref)
366+
- `pos(t)`: Position of the wiper (normally 0-1)
367+
- `R(t)`: Resistance
368+
369+
# Connectors
370+
371+
- `p` Positive pin
372+
- `n` Negative pin
373+
- `position` RealInput to set the position of the wiper
374+
- `port` [HeatPort](@ref) Heat port to model the temperature dependency
375+
376+
# Parameters
377+
378+
- `R_ref`: [`Ω`] Resistance at temperature T_ref when fully closed (pos=1.0)
379+
- `T_ref`: [K] Reference temperature
380+
- `R_const`: [`Ω`] Constant resistance between p and n
381+
- `T_dep`: Temperature dependency
382+
- `alpha`: [K⁻¹] Temperature coefficient of resistance
383+
- `enforce_bounds`: Enforce bounds for the position of the wiper (0-1)
384+
"""
385+
@mtkmodel VariableResistor begin
386+
@extend v, i = oneport = OnePort()
387+
388+
@structural_parameters begin
389+
T_dep = false
390+
enforce_bounds = true
391+
end
392+
393+
@parameters begin
394+
R_ref = 1.0,
395+
[description = "Resistance at temperature T_ref when fully closed (pos=1.0)",
396+
unit = "Ω"]
397+
T_ref = 300.15, [description = "Reference temperature", unit = "K"]
398+
R_const = 1e-3, [description = "Constant resistance between p and n", unit = "Ω"]
399+
end
400+
401+
@components begin
402+
position = RealInput()
403+
end
404+
405+
@variables begin
406+
pos(t), [description = "Position of the wiper (normally 0-1)"]
407+
R(t), [description = "Resistance", unit = "Ω"]
408+
end
409+
410+
if T_dep
411+
@parameters begin
412+
alpha = 1e-3,
413+
[description = "Temperature coefficient of resistance", unit = "K^-1"]
414+
end
415+
@components begin
416+
port = HeatPort()
417+
end
418+
@equations begin
419+
port.Q_flow ~ -v * i # -LossPower
420+
R ~ R_const + pos * R_ref * (1 + alpha * (port.T - T_ref))
421+
end
422+
else
423+
@equations begin
424+
R ~ R_const + pos * R_ref
425+
end
426+
end
427+
428+
@equations begin
429+
pos ~ (enforce_bounds ? clamp(position.u, 0, 1) : position.u)
430+
v ~ i * R
431+
end
432+
end

src/Electrical/Electrical.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include("utils.jl")
1515

1616
export Capacitor,
1717
Ground, Inductor, Resistor, Conductor, Short, IdealOpAmp, EMF,
18-
HeatingResistor, Diode, HeatingDiode
18+
HeatingResistor, Diode, HeatingDiode, VariableResistor
1919
include("Analog/ideal_components.jl")
2020

2121
export CurrentSensor, PotentialSensor, VoltageSensor, PowerSensor, MultiSensor

test/Electrical/analog.jl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,57 @@ end
486486
@test SciMLBase.successful_retcode(sol)
487487
@test sol[capacitor.v][end] < capacitor_voltage[end]
488488
end
489+
490+
@testset "VariableResistor with Temperature Dependency" begin
491+
R_ref = 2.0
492+
R_const = 1.0
493+
494+
# Define the RC model as described
495+
@mtkmodel RC begin
496+
@parameters begin
497+
R = R_ref # Variable resistance reference value
498+
C = 1.0 # Capacitance
499+
k = 10.0 # Voltage source scaling factor
500+
f = 0.2 # Frequency of sine input
501+
T = 300.0 # Ambient temperature in Kelvin
502+
end
503+
@components begin
504+
res_input = Sine(frequency = f, amplitude = 1.0, offset = 0.0)
505+
volt_input = Constant(k = 1.0)
506+
resistor = VariableResistor(R_ref = R_ref, R_const = R_const, T_dep = true)
507+
capacitor = Capacitor(C = C, v = 0.0)
508+
source = Voltage()
509+
temp = FixedTemperature(T = T)
510+
ground = Ground()
511+
end
512+
@equations begin
513+
connect(temp.port, resistor.port)
514+
connect(res_input.output, resistor.position)
515+
connect(volt_input.output, source.V)
516+
connect(source.p, resistor.p)
517+
connect(resistor.n, capacitor.p)
518+
connect(capacitor.n, source.n, ground.g)
519+
end
520+
end
521+
522+
# Build and solve the system
523+
@mtkbuild sys = RC()
524+
prob = ODEProblem(sys, [0.0, 0.0], (0.0, 10.0)) # No state variables initially
525+
sol = solve(prob)
526+
527+
# Perform Tests
528+
resistor_resistance = sol[sys.resistor.R]
529+
capacitor_voltage = sol[sys.capacitor.v]
530+
531+
@test SciMLBase.successful_retcode(sol) # Ensure the simulation is successful
532+
@test all(resistor_resistance .>= R_const) # Resistance should be >= constant value
533+
@test maximum(resistor_resistance) R_const + R_ref # Maximum resistance when pos=1 (R_const + R_ref)
534+
@test all(capacitor_voltage .>= 0.0) # Capacitor voltage should not be negative
535+
536+
# For visual inspection
537+
# plt = plot(sol; vars = [sys.resistor.R, sys.capacitor.v],
538+
# size = (800, 600), dpi = 300,
539+
# labels = ["Variable Resistor Resistance" "Capacitor Voltage"],
540+
# title = "RC Circuit Test with VariableResistor")
541+
# savefig(plt, "rc_circuit_test_variable_resistor")
542+
end

0 commit comments

Comments
 (0)