Искусство схемотехники - практикум: RC-фильтр
RC-фильтр для выделения медленного сигнала
В этом примере рассчитывается и проверяется пассивный RC-фильтр нижних частот. Фильтр должен сохранить полезную составляющую около 1 кГц и ослабить пульсацию около 16 кГц. В скрипте используются расчет параметров, аналитическая оценка амплитудно-частотной характеристики, загрузка готовых моделей Engee, программный запуск симуляции, получение скриншотов модели и построение графиков результатов. Пример полезен инженеру, которому необходимо быстро оценить влияние нагрузки на простой аналоговый фильтр.
Введение
Этот пример описывает ход решения задачи
2W1.1 - Фильтр для ослабления сигнала и ослабления помехи
из книги
Томас К. Хейс, Пол Хоровиц
Искусство схемотехники: Теория и практика
путем компьютерного моделирования в Engee.
Пусть входной сигнал состоит из медленной полезной части и быстрой пульсации. Такая ситуация возникает после выпрямителей, импульсных преобразователей и датчиков с высокочастотной наводкой.
Используйте фильтр нижних частот, если полезная составляющая расположена ниже помехи по частоте. В этом примере вход содержит компоненту 1 кГц и пульсацию 16 кГц. Поэтому выберите частоту среза между этими значениями.
Метод фильтрации и расчетные соотношения
Ненагруженный RC-фильтр описывает передаточная функция
Частота среза по уровню дБ равна
Если к выходу подключена нагрузка , она шунтирует конденсатор. Тогда постоянная составляющая уменьшается, а полюс сдвигается вверх:
Расчет параметров
В этой ячейке задайте исходные частоты, выберите резистор и рассчитайте емкость для целевой частоты среза. Затем сравните точное значение с ближайшим удобным стандартным номиналом.
R = 10_000.0
C_standard = 10e-9
f_signal = 1_000.0
f_ripple = 16_000.0
f_target = 2_000.0
C_exact = 1 / (2pi * R * f_target)
f3db_standard = 1 / (2pi * R * C_standard)
calculation_summary = (;
R_ohm = R,
C_exact_F = C_exact,
C_standard_F = C_standard,
f3db_standard_Hz = f3db_standard,
)
calculation_summary
Расчет дает емкость около 8 нФ для частоты 2 кГц. Номинал 0.01 мкФ удобен как стандартное значение. Он снижает частоту среза примерно до 1.59 кГц. Такое смещение усиливает подавление пульсации, но немного сильнее ослабляет полезную составляющую.
Оценка влияния нагрузки
В этой ячейке рассчитайте коэффициенты передачи для трех случаев: без нагрузки, с нагрузкой 100 кОм и с нагрузкой 10 кОм. Так вы увидите, насколько нагрузка меняет уровень сигнала и положение полюса.
function rc_case(load_ohm; R = R, C = C_standard)
if isinf(load_ohm)
dc_gain = 1.0
tau = R * C
else
dc_gain = load_ohm / (R + load_ohm)
tau = R * C / (1 + R / load_ohm)
end
f3db = 1 / (2pi * tau)
gain(f) = dc_gain / sqrt(1 + (f / f3db)^2)
return (;
load_ohm,
dc_gain,
tau_s = tau,
f3db_Hz = f3db,
gain_1k = gain(f_signal),
gain_16k = gain(f_ripple),
ripple_to_signal = gain(f_ripple) / gain(f_signal),
)
end
load_cases = [
:no_load => rc_case(Inf),
:load_100k => rc_case(100_000.0),
:load_10k => rc_case(10_000.0),
]
load_cases
Нагрузка 100 кОм почти не меняет подавление высокочастотной пульсации. Нагрузка 10 кОм заметно уменьшает полезный уровень и повышает частоту среза. Поэтому такой фильтр стоит подключать ко входу с существенно большим сопротивлением, чем последовательный резистор.
Описание моделей
Для примера используются готовые модели Engee.
В набор входят три модели:
RCFilter_2W_1_1_signal.engee— сигнальная модель с тремя ветвямиTransfer Fcn;RCFilter_2W_1_1_phys_RL100k.engee— физическая RC-цепь с нагрузкой 100 кОм;RCFilter_2W_1_1_phys_RL10k.engee— физическая RC-сеть с нагрузкой 10 кОм.
В физических моделях используются блоки Controlled Voltage Source, Resistor, Capacitor, Voltage Sensor, Electrical Reference и один Solver Configuration на связную физическую сеть.
Подготовка окружения
В этой ячейке задайте пути к готовым моделям. Если вы запускаете пример в другой папке Engee, измените переменную dir.
using Plots
dir = @__DIR__
model_paths = Dict(
:signal => joinpath(dir, "RCFilter_2W_1_1_signal.engee"),
:phys_100k => joinpath(dir, "RCFilter_2W_1_1_phys_RL100k.engee"),
:phys_10k => joinpath(dir, "RCFilter_2W_1_1_phys_RL10k.engee"),
)
string("prepared; dir=", dir)
Окружение готово к запуску. Переменная model_paths хранит пути к моделям, а dir для файлов с результатами.
Аналитическая проверка
Перед запуском модели постройте расчетную амплитудно-частотную характеристику. Этот график показывает ожидаемое поведение фильтра и помогает проверить результаты симуляции.
freqs = exp10.(range(log10(100.0), log10(100_000.0), length = 600))
function rc_gain(load_ohm, f)
c = rc_case(load_ohm)
return c.dc_gain / sqrt(1 + (f / c.f3db_Hz)^2)
end
p_response = plot(
freqs,
20 .* log10.(rc_gain.(Inf, freqs));
xscale = :log10,
label = "без нагрузки",
xlabel = "Частота, Гц",
ylabel = "Амплитуда, дБ",
title = "Расчетная АЧХ RC-фильтра",
)
plot!(p_response, freqs, 20 .* log10.(rc_gain.(100_000.0, freqs)); label = "Rн = 100 кОм")
plot!(p_response, freqs, 20 .* log10.(rc_gain.(10_000.0, freqs)); label = "Rн = 10 кОм")
response_path = joinpath(output_dir, "rc_filter_response.png")
savefig(p_response, response_path)
p_response
На графике видно, что нагрузка 10 кОм поднимает частоту среза и одновременно снижает низкочастотный уровень. Это худший из рассматриваемых случаев для сохранения полезного сигнала.
Симуляция модели
Теперь загрузите сигнальную модель и запустите симуляцию. Код использует программное управление Engee: engee.load, engee.open, engee.run и engee.close.

missing_models = [path for path in values(model_paths) if !isfile(path)]
if isempty(missing_models)
signal_payload = Core.eval(Main, quote
model = engee.load($(model_paths[:signal]); force = true)
engee.open(model)
results = engee.run(model)
(; results, result_text = repr(results))
end)
signal_results = signal_payload.results
string("signal model simulated; results=", signal_payload.result_text)
else
string("missing_models=", join(missing_models, ";"))
end
Сигнальная модель запущена. Результат симуляции содержит входной сигнал и три выходных сигнала для разных нагрузок.
Проверка физических моделей
В этой ячейке запустите две физические модели. Они проверяют ту же RC-схему как acausal-электрическую цепь с реальными электрическими узлами и датчиком напряжения. По изображениям ниже видно их структуру: источник, последовательный резистор, конденсатор и нагрузка должны образовывать одну связную электрическую цепь с общей землей.

physical_payload = Core.eval(Main, quote
model_paths_main = $(model_paths)
output_dir_main = $(output_dir)
results = Dict{Symbol, Any}()
for key in (:phys_100k, :phys_10k)
model = engee.load(model_paths_main[key]; force = true)
engee.open(model)
results[key] = engee.run(model)
engee.close(model; force = true)
end
(; results, result_text = repr(results))
end)
physical_results = physical_payload.results
string("physical models simulated; results=", physical_payload.result_text)
Обе физические модели запускаются тем же программным способом.
Анализ результатов симуляции
Постройте временные графики по результатам сигнальной модели. Сравните вход с выходами для разных нагрузок. Так легче увидеть подавление пульсации и падение амплитуды при тяжелой нагрузке.
function series_from_result(results, key)
df = results[key]
return df.time, df.value
end
time, input_signal = series_from_result(signal_results, "input_sum.1")
_, y_no_load = series_from_result(signal_results, "lp_no_load.1")
_, y_100k = series_from_result(signal_results, "lp_load_100k.1")
_, y_10k = series_from_result(signal_results, "lp_load_10k.1")
p_time = plot(
time .* 1000,
input_signal;
label = "вход",
xlabel = "Время, мс",
ylabel = "Напряжение, отн. ед.",
title = "Фильтрация сигнала с пульсацией",
)
plot!(p_time, time .* 1000, y_no_load; label = "без нагрузки")
plot!(p_time, time .* 1000, y_100k; label = "Rн = 100 кОм")
plot!(p_time, time .* 1000, y_10k; label = "Rн = 10 кОм")
time_plot_path = joinpath(output_dir, "rc_filter_time_signals.png")
savefig(p_time, time_plot_path)
p_time
Выходные сигналы стали более гладкими, чем входной сигнал. Вариант с 100 кОм близок к ненагруженному фильтру. Вариант с 10 кОм дает меньший уровень полезной составляющей, потому что нагрузка образует делитель с последовательным резистором.
Сводная таблица
Соберите расчетные показатели в компактную таблицу. Она фиксирует частоту среза, коэффициент передачи полезной составляющей и относительное прохождение пульсации.
summary_rows = [
(case = string(name), values...)
for (name, values) in load_cases
]
summary_csv = joinpath(output_dir, "rc_filter_summary.csv")
open(summary_csv, "w") do io
println(io, "case,load_ohm,dc_gain,tau_s,f3db_Hz,gain_1k,gain_16k,ripple_to_signal")
for row in summary_rows
println(io, join((
row.case,
row.load_ohm,
row.dc_gain,
row.tau_s,
row.f3db_Hz,
row.gain_1k,
row.gain_16k,
row.ripple_to_signal,
), ","))
end
end
summary_rows
Таблица демонстрирует инженерный компромисс. Большая нагрузка почти не влияет на фильтр. Нагрузка, сравнимая с R, снижает уровень сигнала и ухудшает разделение полезной составляющей и пульсации.
Заключение
Мы рассчитали и проверили RC-фильтр нижних частот для отделения медленного сигнала от быстрой пульсации. Номиналы R = 10 кОм и C = 0.01 мкФ дают частоту среза около 1.59 кГц. Этого достаточно, чтобы заметно ослабить компоненту 16 кГц и сохранить большую часть сигнала 1 кГц.
Модель также показывает ограничение пассивного фильтра. Если нагрузка мала, она меняет и коэффициент передачи, и частоту среза. Поэтому подключайте такой фильтр к входу с высоким сопротивлением или добавляйте буферный каскад.
Список литературы
- Хейс Т.К., Хоровиц П. Искусство схемотехники. Теория и практика. БХВ-Петербург, 2022. с.128-130
- Хоровиц П., Хилл У. Искусство схемотехники. Том 1. Мир, 1993.
- Бессонов Л. А. Теоретические основы электротехники. Электрические цепи. Гардарики, 2002.
- Седра А., Смит К. Микроэлектронные схемы. Вильямс.
- Engee Help Center. Документация блоков
Transfer Fcn,Sine Wave,Resistor,Capacitor,Controlled Voltage Source,Voltage Sensor,Solver Configuration. - Engee Help Center. Программное управление моделями:
engee.load,engee.open,engee.run,engee.get_results,engee.close.

