Engee documentation
Notebook

Modelling an unstable multivibrator

This example will demonstrate the modelling of an unstable multivibrator.

An unstable multivibrator is an auto-oscillating circuit that generates continuous rectangular pulses. It has no steady states and automatically switches between two transistors, generating a periodic signal.

Multivibrators can be used to generate clock signals in a variety of systems.

Mathematical description

The duration of pulses and pauses is determined by the RC circuits in the base circuits of the transistors.

The duration of the "ON" state for each transistor:

$$t = 0.69 \cdot R \cdot C$$

Total oscillation period (with symmetrical circuit): $$T = 2 \cdot t = 1.38 \cdot R \cdot C$$

Frequency of signals: $$f = \frac{1}{T} = \frac{1}{1.38 \cdot R \cdot C}$$

Schematic of the model:

novator1_2_1741865268001.png

Define the function to load and run the model:

In [ ]:
function start_model_engee()
    try
        engee.close("npn_transistor", force=true) # закрытие модели 
        catch err # в случае, если нет модели, которую нужно закрыть и engee.close() не выполняется, то будет выполнена её загрузка после catch
            m = engee.load("$(@__DIR__)/astable_multivibrator.engee") # загрузка модели
        end;

    try
        engee.run(m, verbose=true) # запуск модели
        catch err # в случае, если модель не загружена и engee.run() не выполняется, то будут выполнены две нижние строки после catch
            m = engee.load("$(@__DIR__)/astable_multivibrator.engee") # загрузка модели
            engee.run(m, verbose=true) # запуск модели
        end
end
Out[0]:
start_model_engee (generic function with 1 method)

Running the simulation

In [ ]:
start_model_engee();
Building...
Progress 0%
Progress 5%
Progress 11%
Progress 16%
Progress 21%
Progress 27%
Progress 32%
Progress 37%
Progress 43%
Progress 48%
Progress 54%
Progress 59%
Progress 65%
Progress 70%
Progress 75%
Progress 81%
Progress 86%
Progress 92%
Progress 97%
Progress 100%
Progress 100%

Write simulation data to variables:

In [ ]:
t = simout["astable_multivibrator/правый"].time[:]
V_right = simout["astable_multivibrator/правый"].value[:]
V_left = simout["astable_multivibrator/левый"].value[:]
I_R1 = simout["Resistor 1.i"].value[:]
I_R4 = simout["Resistor 4.i"].value[:]
Out[0]:
WorkspaceArray{Float64}("Resistor 4.i").value

Data visualisation

In [ ]:
using Plots

Visualisation of the collector-emitter voltage on both transistors:

In [ ]:
plot(t, V_left, linewidth=2)
plot!(t, V_right, linewidth=2)
Out[0]:

Visualisation of the current on the resistors connected to the collectors of the transistors:

In [ ]:
plot(t, I_R1, linewidth=2)
plot!(t, I_R4, linewidth=2)
Out[0]:

Processing of simulation results:

Running the statistics library:

In [ ]:
using Statistics

Defining a function to find the frequency and period of voltage fluctuations:

In [ ]:
function calculate_oscillation_properties(time::Vector{T}, x::Vector{T}) where T <: Real
    # Проверка длины векторов
    if length(time) != length(x)
        error("Векторы времени и сигнала должны быть одинаковой длины")
    end
    n = length(time)
    n < 2 && return (NaN, NaN)  # Недостаточно данных

    # Находим среднее значение сигнала
    avg = sum(x) / n

    # Ищем моменты пересечения среднего значения снизу вверх
    up_crossings = T[]
    for i in 2:n
        if x[i-1] < avg && x[i] >= avg
            # Линейная интерполяция для точного определения времени пересечения
            t = time[i-1] + (time[i] - time[i-1]) * (avg - x[i-1]) / (x[i] - x[i-1])
            push!(up_crossings, t)
        end
    end

    # Проверка достаточного количества пересечений
    length(up_crossings) < 2 && return (NaN, NaN)

    # Расчёт периодов (в единицах времени)
    periods = diff(up_crossings)
    mean_period = mean(periods)
    frequency = 1 / mean_period

    return "Частота колебаний: $frequency Гц. Период колебаний: $mean_period с."
end
Out[0]:
calculate_oscillation_properties (generic function with 1 method)

Applying the function to a vector of voltage values (any signals can be substituted):

In [ ]:
calculate_oscillation_properties(collect(t)[:,1], collect(V_left)[:,1])
Out[0]:
"Частота колебаний: 461.73240656747765 Гц. Период колебаний: 0.002165756584931969 с."

Conclusions:

In this example we have considered a model of unstable multivibrator, where the key elements that determine the frequency and period of oscillations are base resistors (R2, R3) and capacitors forming time-delay RC circuits. Collector resistors (R1, R4) do not influence the frequency of the signal - their role is reduced to limiting the current through the transistors and forming the amplitude of the output voltage.