Adaptively adjust gain for constant signal-level output
object™ creates an
automatic gain controller (AGC) that adaptively adjusts its gain to
achieve a constant signal level at the output.
To adaptively adjust gain for constant signal-level output:
Starting in R2016b, instead of using the
to perform the operation defined by the System
object, you can
call the object with arguments, as if it were a function. For example,
= step(obj,x) and
y = obj(x) perform
H = comm.AGC creates an AGC System
that adaptively adjusts its gain to achieve a constant signal level
at the output.
H = comm.AGC( creates
an AGC object,
H, with the specified property
to the specified
Value. You can specify additional
name-value pair arguments in any order as (
Step size for gain updates
Specify the step size as a real positive scalar. The default
Target output power level
Specify the desired output power level as a real positive scalar.
The power is measured in Watts referenced to 1 ohm . The default is
Length of the averaging window
Specify the length of the averaging window in samples as a positive
integer scalar. The default is
If you use the AGC with higher order QAM signals, you might
need to reduce the variation in the gain during steady-state operation.
Inspect the scatter plot at the output of the AGC and increase the
averaging length as needed. An increase in
Maximum power gain in decibels
Specify the maximum gain of the AGC in decibels as a positive
scalar. The default is
If the AGC input signal power is very small, the AGC gain will
be very large. This can cause problems when the input signal power
suddenly increases. Use
|reset||Reset internal states of automatic gain controller|
|step||Apply adaptive gain to input signal|
Modulate and amplify a QPSK signal. Set the received signal amplitude to approximately 1 volt using an AGC. Then plot the output.
Create a QPSK modulated signal using the QPSK System object.
data = randi([0 3],1000,1); qpsk = comm.QPSKModulator; modData = qpsk(data);
Attenuate the modulated signal.
txSig = 0.1*modData;
Create an AGC System object™ and pass the transmitted signal through it using the
step function. The AGC adjusts the received signal power to approximately 1 W.
agc = comm.AGC; rxSig = agc(txSig);
Plot the signal constellations of the transmit and received signals after the AGC reaches steady-state.
h = scatterplot(txSig(200:end),1,0,'*'); hold on scatterplot(rxSig(200:end),1,0,'or',h); legend('Input of AGC', 'Output of AGC')
Measure and compare the power of the tranmitted and received signals after the AGC reaches a steady state. The power of the transmitted signal is 100 times smaller than the power of the received signal.
txPower = var(txSig(200:end)); rxPower = var(rxSig(200:end)); [txPower rxPower]
ans = 0.0100 0.9970
Create two AGC System objects™ to adjust the level of the received signal using two different step sizes with identical update periods.
Generate an 8-PSK signal having power equal to 10 W.
data = randi([0 7],200,1); modData = sqrt(10)*pskmod(data,8,pi/8,'gray');
Create a pair of raised cosine matched filters with their
Gain property set so that they have unity output power.
txfilter = comm.RaisedCosineTransmitFilter('Gain',sqrt(8)); rxfilter = comm.RaisedCosineReceiveFilter('Gain',sqrt(1/8));
Filter the modulated signal through the raised cosine transmit filter object.
txSig = txfilter(modData);
Create two AGC objects to adjust the received signal level. Select a step size of 0.01 and 0.1, respectively. Set the update period to 10.
agc1 = comm.AGC('AdaptationStepSize',0.01); agc2 = comm.AGC('AdaptationStepSize',0.1);
Pass the modulated signal through the two AGC objects.
agcOut1 = agc1(txSig); agcOut2 = agc2(txSig);
Filter the AGC output signals by using the raised cosine receive filter object.
rxSig1 = rxfilter(agcOut1); rxSig2 = rxfilter(agcOut2);
Plot the power of the filtered AGC responses while accounting for the 10 symbol delay through the transmit-receive filter pair.
plot([abs(rxSig1(11:110)).^2 abs(rxSig2(11:110)).^2]) grid on xlabel('Symbols') ylabel('Power (W)') legend('Step Size 0.01','Step Size 0.1')
The signal with the larger step size converges faster to the AGC target power level of 1 W.
Plot the power of the steady-state filtered AGC signals by including only the last 100 symbols.
plot((101:200),[abs(rxSig1(101:200)).^2 abs(rxSig2(101:200)).^2]) grid on xlabel('Symbols') ylabel('Power (W)') legend('Step Size 0.01','Step Size 0.1')
The larger AGC step size results in less accurate gain correction.
The reduced accuracy suggests a trade off with the
AdaptationStepSize property. Larger values result in faster convergence at the expense of less accurate gain control.
Pass attenuated QPSK packet data to two AGCs having different maximum gains. Then display the results.
Create two, 200-symbol QSPK data packets. Transmit the packets over a 1200-symbol frame.
modData1 = pskmod(randi([0 3],200,1),4,pi/4); modData2 = pskmod(randi([0 3],200,1),4,pi/4); txSig = [modData1; zeros(400,1); modData2; zeros(400,1)];
Attenuate the transmitted burst signal by 20 dB and plot its power.
rxSig = 0.1*txSig; rxSigPwr = abs(rxSig).^2; plot(rxSigPwr) grid xlabel('Symbols') ylabel('Power (W)')
Create two AGCs, where
agc1 has a maximum power gain of 30 dB and
agc2 has a maximum power gain of 24 dB.
agc1 = comm.AGC('MaxPowerGain',30, ... 'AdaptationStepSize',0.02); agc2 = comm.AGC('MaxPowerGain',24, ... 'AdaptationStepSize',0.02);
Pass the attenuated signal through the AGCs and calculate the output power.
rxAGC1 = agc1(rxSig); rxAGC2 = agc2(rxSig); pwrAGC1 = abs(rxAGC1).^2; pwrAGC2 = abs(rxAGC2).^2;
Plot the output power.
plot([pwrAGC1 pwrAGC2]) legend('AGC1','AGC2') grid xlabel('Symbols') ylabel('Power (W)')
Initially, for the second packet, the
agc1 output signal power is too high because the AGC applied its maximum gain during the period when no data was transmitted. The corresponding
agc2 output signal power does not overshoot the target power level of 1 W by the same amount. It converges to the correct power more quickly due to its smaller maximum gain.
For the logarithmic loop AGC, the output signal is the product of the input signal and the exponential of the loop gain. The error signal is the difference between the reference level and the product of the logarithm of the detector output and the exponential of the loop gain. After multiplying by the step size, the AGC passes the error signal to an integrator.
The logarithmic loop AGC provides good performance for a variety of signal types, including amplitude modulation. Unlike the previous AGC (R2015a and earlier), the detector is applied to the input signal, which results in faster convergence times and increased signal power variation at the detector input. The larger variation is not a problem for floating point systems. A block diagram of the algorithm is shown.
Mathematically, the algorithm is summarized as
x represents the input signal.
y represents the output signal.
g represents the loop gain.
D(•) represents the detector function.
z represents the detector output.
A represents the reference value.
e represents the error signal.
K represents the step size.
The AGC uses a square law detector, in which the output of the detector, z, is given by
where N represents the update period.
Attack time — The duration it takes the AGC to respond to an increase in the input amp litude.
Decay time — The duration it takes the AGC to respond to a decrease in the input amplitude.
Gain pumping — The variation in the gain value during steady-state operation.
Increasing the step size decreases the attack time and decay times, but it also increases gain pumping.
Usage notes and limitations:
See System Objects in MATLAB Code Generation (MATLAB Coder).