五类噪声通常指
N(t) = N_bg + N_nbi + N_ppi + N_api + N_harmonic
- 背景有色噪声(粉红色/AR 型)
- 窄带干扰(AM 广播 / 单频泄露)
- 周期脉冲噪声(与工频同步)
- 异步脉冲噪声(开关瞬态)
- 工频相关谐波/幅度调制噪声
1)主脚本:plc_noise_demo.m
matlab
%% plc_noise_demo.m
% 电力线信道五类噪声仿真(不调用任何搜索/下载)
clear; clc; close all;
fs = 10e6; % 采样率,例 10 MHz(按你系统来)
T = 0.005; % 噪声长度 5 ms
N = round(T*fs);
t = (0:N-1)/fs;
% ========== 参数(你对着实测可调) ==========
% 1) 背景有色噪声:用一阶AR(1)近似"粉噪声"
bg_amp = 0.12; % 幅度尺度
bg_rho = 0.92; % AR(1) 相关系数(越大越红)
% 2) 窄带干扰:k个单频分量
nbi_freqs = [50e3, 550e3, 1.2e6]; % Hz(例:工频谐波+广播带)
nbi_amps = [0.25, 0.18, 0.10];
nbi_phases= rand(1,numel(nbi_freqs))*2*pi;
% 3) 周期脉冲噪声(与工频同步)
f_line = 50; % 工频 Hz
ppi_period = 1/f_line;
ppi_width = 1e-6; % 脉冲宽度 1 us
ppi_amp = 1.2; % 脉冲幅度
ppi_edge = 0.5*ppi_period; % 脉冲在时间窗内偏移(免得刚好卡边界)
% 4) 异步脉冲噪声(泊松到达)
api_lambda = 80; % 每秒平均脉冲数
api_amp = 1.0; % 脉冲幅度尺度
api_tau = 2e-6; % 脉冲宽度(指数衰减时间常数)
% 5) 工频谐波调制噪声(慢时变包络)
harm_amp = 0.15;
harm_h = [1, 0.6, 0.3]; % 1f,2f,3f 相对幅度
harm_f = [50, 100, 150];
% ========== 生成 ==========
n_bg = plc_bg_colored_noise(N, fs, bg_amp, bg_rho);
n_nbi = plc_narrowband_ifn(t, nbi_freqs, nbi_amps, nbi_phases);
n_ppi = plc_periodic_pulses(t, fs, f_line, ppi_width, ppi_amp, ppi_edge);
n_api = plc_async_pulses(t, fs, api_lambda, api_amp, api_tau, rng(1));
% harmonic:看成宽带噪声被工频谐波调幅
n_har = plc_harmonic_am_noise(t, fs, harm_amp, harm_h, harm_f);
n_total = n_bg + n_nbi + n_ppi + n_api + n_har;
% ========== 绘图 ==========
figure('Color','w','Position',[120 80 1200 700]);
% 时域
subplot(3,2,1); plot(t*1e3, n_bg); grid on;
xlabel('t (ms)'); ylabel('Amplitude'); title('1) 背景有色噪声(pink/AR)');
subplot(3,2,2); plot(t*1e3, n_nbi); grid on;
xlabel('t (ms)'); ylabel('Amplitude'); title('2) 窄带干扰(NBIs)');
subplot(3,2,3); plot(t*1e3, n_ppi); grid on;
xlabel('t (ms)'); ylabel('Amplitude'); title('3) 周期脉冲噪声(工频同步)');
subplot(3,2,4); plot(t*1e3, n_api); grid on;
xlabel('t (ms)'); ylabel('Amplitude'); title('4) 异步脉冲噪声(泊松到达)');
subplot(3,2,5); plot(t*1e3, n_har); grid on;
xlabel('t (ms)'); ylabel('Amplitude'); title('5) 工频谐波相关调制噪声');
subplot(3,2,6); plot(t*1e3, n_total); grid on;
xlabel('t (ms)'); ylabel('Amplitude'); title('叠加总噪声');
% PSD对比(Welch 手写简易版)
[pxx,f] = my_pwelch(n_total, fs, 1024);
figure('Color','w'); semilogy(f/1e3, pxx); grid on;
xlabel('Frequency (kHz)'); ylabel('PSD (线性幅值^2/Hz)');
title('总噪声功率谱(简易 Welch)');
xlim([0 fs/2/1e3]);
2)五类噪声各自的手写生成函数
2.1 背景有色噪声(用 AR(1) 造"粉噪声")
matlab
function n = plc_bg_colored_noise(N, fs, A, rho)
% rho~0.9..0.98:越大频谱越红(1/f^α)
% 更严谨可用滤波白噪声:H(z)=1/(1-rho*z^-1)
w = randn(N,1);
n = zeros(N,1);
n(1) = w(1);
for k=2:N
n(k) = rho*n(k-1) + sqrt(1-rho^2)*w(k);
end
n = A * n / std(n);
end
2.2 窄带干扰(若干单频)
matlab
function n = plc_narrowband_ifn(t, freqs, amps, phases)
n = zeros(size(t));
for i=1:numel(freqs)
n = n + amps(i)*cos(2*pi*freqs(i)*t + phases(i));
end
end
2.3 周期脉冲噪声(工频同步,矩形/指数)
matlab
function n = plc_periodic_pulses(t, fs, f_line, pw, amp, edge_offset)
% 周期脉冲:每 1/f_line 秒出现一个脉宽为 pw 的脉冲
n = zeros(size(t));
Tline = 1/f_line;
edges = (edge_offset:Tline:(t(end)+Tline));
for e = edges
idx = (t>=e) & (t < e+pw);
n(idx) = n(idx) + amp;
end
end
2.4 异步脉冲噪声(泊松到达 + 指数衰减脉冲)
matlab
function n = plc_async_pulses(t, fs, lambda, amp_scale, tau, ~)
% 用均匀随机数近似泊松到达:每秒平均 lambda 个脉冲
% 每个脉冲:矩形宽度~rand,或者指数衰减 exp(-(t-tk)/tau)
n = zeros(size(t));
dt = 1/fs;
prob = lambda * dt; % 每个采样点"开始脉冲"的概率(近似)
rng_state = 0; % 这里不用搜索,直接固定种子就够
for k=1:numel(t)
if rand < prob
% 脉冲长度随机(1~3个tau)
len = max(1, round((1+2*rand())*tau*fs));
pulse = amp_scale * exp(-(0:len-1)/fs/tau);
n(k:min(k+len-1,numel(n))) = n(k:min(k+len-1,numel(n))) + pulse;
end
end
end
2.5 工频谐波相关调制噪声(慢时变包络)
matlab
function n = plc_harmonic_am_noise(t, fs, A, harm_h, harm_f)
% 把白噪声用 [1 + Σ h_k cos(2πfk t)] 调幅,模拟"工频相关"
w = randn(size(t));
env = ones(size(t));
for k=1:numel(harm_f)
env = env + harm_h(k)*cos(2*pi*harm_f(k)*t);
end
% 让 env 永远正(更像幅度调制式噪声,而不是纯乘性)
env = 1 + A*env;
env = max(env, 0.01);
n = w .* env;
n = n / std(n) * A; % 用A当"输出幅度尺度"
end
3)简易 Welch
matlab
function [pxx,f] = my_pwelch(x, fs, winLen)
x = x(:);
N = length(x);
Nseg = floor(N/winLen);
win = ones(winLen,1);
Xsq = zeros(winLen,1);
cnt = 0;
for s=1:Nseg
seg = x((s-1)*winLen+1:s*winLen) .* win;
S = abs(fft(seg)).^2;
Xsq = Xsq + S; cnt=cnt+1;
end
Xsq = Xsq / cnt / (winLen * fs);
f = (0:winLen-1)*fs/winLen;
pxx = Xsq;
end
参考代码 仿真电力线信道五类噪声 www.youwenfan.com/contentcsv/81221.html
4)怎么把噪声接到"PLC接收机"
matlab
rx_signal = tx_signal + n_total; % 加到接收信号
% 或按SNR加:
SNRdB = 18;
rx_signal = awgn(tx_signal, SNRdB); % 若你想把"背景热噪声"用AWGN体现
rx_signal = rx_signal + n_ppi + n_api + n_nbi; % 再把非AWGN项叠上去