In the process of creating various products that deal with analog signals, one frequently requested function is automatic gain control. This feature is needed to control the amplitude of a given input signal so that it always remains within some desired range. Knowing that the signal won't vary from the established range makes it easier to perform a variety of mathematical and electrical operations on it. To keep the incoming analog signal between the predetermined range limits, an attenuation or amplification is applied. Using gain reduction to keep a signal below an upper limit can prevent clipping or mathematical overflow. To increase the signal-to-noise ratio, amplification is generally utilized to keep the signal above some minimum. Amplification also will help prevent underflow.
The amplification or attenuation function is performed dynamically on the incoming analog signal based on the signal amplitude. Furthermore, the amplification-/attenuation-to-amplitude relationship can be a linear, logarithmic, or some other mathematical relationship (commonly known as a transfer function). When applied as a system, these concepts form the basis of an automatic-gain-control (AGC) circuit.
The applications of AGC circuits include audio processing, speech processing, and some types of instrumentation. In audio applications, AGC systems are used to prevent an analog signal from overdriving subsequent gain, filter, and signal-routing stages. AGC systems also can be useful in audio applications. They keep signal levels from exceeding a point at which—if amplified further—damage to output transducers like loud speakers could result. Professional audio systems often use a specific piece of equipment, which is referred to as a compressor/limiter, to maintain the signal level below a certain point. While a compressor/limiter has many other features and functions, its operation typically utilizes AGC circuits.
In speech-processing or communications systems, AGC is generally employed to keep a signal's amplitude within the boundaries of the subsequent communications channel. Using AGC prior to applying some form of modulation can prevent certain types of distortion from being induced as the signal is transferred over some medium.
One method of creating an AGC circuit is by using two primary analog components: a precision rectifier and a voltage-controlled amplifier. These two components are needed to provide the most basic AGC form. In the simplest sense, the precision rectifier operates on the incoming signal and generates a control voltage. That voltage is then used to control the gain of the voltage-controlled amplifier. Typically, that amplifier's response is fixed, making for a fixed compression/expansion transfer function.
This implementation demonstrates a technique that incorporates a microcontroller. Through this approach, the added benefit of transfer-function programmability can then be realized. If the specific microcontroller happens to have analog-signal-processing capabilities, the entire circuit can even be compressed into a single programmable chip.
In order to create a microcontroller-based automatic-gain-control system, it's necessary to mimic the two basic analog-circuit building blocks: the rectifier and the voltage-controlled amplifier. Let's begin with the rectifier. The manner in which signal rectification is accomplished depends upon the microcontroller. Some microcontrollers have analog features, which allow the user to create a hardware-based AC-signal rectifier. Many other microcontrollers only have analog-to-digital converters (ADCs).
For now, focus on the ADC-based approach. The technique discussed here allows multiple channels of AGC to be handled by a single device. All of the examples given, however, utilize a single channel implementation. Only the ADC resources of a given microcontroller limit the number of channels that is allowed.
Implementing the rectifier requires an analog-to-digital converter, which samples the incoming AC waveform. The digitized signal is then mathematically rectified and averaged in order to form a direct-current (DC) value. This DC value is used to determine when to apply gain compression or expansion.
Because many ADCs provide a 2's-complement output value, rectifying the signal in firmware is relatively straightforward. The conversion involves simply detecting a negative reading from the ADC and then converting it to a positive value with the same numeric significance. This converted value is added to a running sum, which is later divided by the number of samples. The result is a determination of the average signal level.
Using a microcontroller that includes a digital-to-analog converter (DAC), it's possible to feed the mathematically rectified value into the DAC. The analog output can then be observed on an oscilloscope or other test equipment. This technique can be very useful for debugging not only the rectifier, but other digital-signal-processing functions as well.
When choosing the ADC conversion rate, consider the incoming signal's frequency range. For example, suppose that the incoming signal will be between 300 and 3300 Hz. Per the Nyquist sampling theorem, the ADC should sample at 2X the highest frequency (2 × 3300 Hz) = 6600 Hz or 151 µs. For convenience, 150 µs was chosen.
In order to cleanly represent the lowest frequency (300 Hz), it's necessary to have at least \[(1/300)/150 µs\] ~= 22 samples. To make the mathematics run more efficiently, it was decided to accumulate 32 samples before calculating the average DC value. The reason for this choice is that the number 32 (base 10) is actually the binary equivalent of 25. In other words, divisions can be simply handled by five shifts instead of a much longer division routine. This method helps to improve the overall execution speed. It can be a useful technique to remember for other designs as well.
Once the incoming signal has been mathematically rectified, summed, and averaged, the result can be used to determine the appropriate amplifier action. One way to implement the internal signal path is through the use of a Cypress Microsystems PSoC Mixed Signal Array (FIG. 1). This device contains analog amplifiers that help in the implementation of the AGC circuit. More specifically, the programmable gain amplifier (PGA) uses firmware to set the gains that result from the ADC calculations. This approach will effectively raise or lower the signal level on the output-signal pin.
The multiplying DAC (MDAC) is optional. It is used to give the incoming signal additional gain before entering the ADC. The MDAC can be a useful addition if the input signal mandates higher utilization of the ADC's range.
To use the multiplying DAC, determine how much gain can be tolerated before the ADC hits its limit under maximum-input-signal conditions. This gain amount becomes the value set on the MDAC digital input during power-up. Afterward, any analog input on the MDAC will be automatically multiplied by the digital-gain value. No further MDAC attention is needed after initialization.
Because most microcontrollers operate using a single, positive-voltage power supply, the internal analog ground (AGND) is generally VCC/2. This AGND level typically determines the operational 'center' of the ADCs. In other words, the 2's-complement digital outputs from the ADC will numerically swing above and below AGND (with AGND being the equivalent 0 output of the ADC).
Given this scenario, it is generally necessary to bias the input signal in such a way that it too will swing above and below AGND. The easiest way to do this is by using an external bias network (FIG. 2). In this example, the component values shown will be sufficient for the input-signal range. The circuit will place the incoming AC signal at approximately +2.5 Vdc, which should be very close to the microcontroller's internal AGND.
Some microcontrollers also allow the internal AGND voltage to be driven to an external pin. In this case, the true internal AGND can be used to more accurately bias the external signal. For these situations, the resistor that's connected to GND in Figure 2 can be omitted. The remaining resistor would then be tied to the microcontroller's AGND signal as opposed to 'VCC' as shown.
With the input signal properly biased, it can now be fed into the microcontroller. If the microcontroller has an amplifier in front of the ADC, make sure that the amplifier also is referenced to AGND and not true ground (GND). Otherwise, any gain applied to the amplifier also will be applied to the AGND DC bias (typically +2.5). Under these conditions, it's easy to see that the amplifier will quickly clip into the positive rail.
This amplification is the only gain stage that the output signal will experience before leaving the microcontroller. It is here that any gain expansion or reduction takes place. Accomplishing this task requires the use of a lookup table (LUT) for the amplifier's various gain settings. The input-voltage level—as determined by the ADC—will control the selection of the gain setting that's stored in the LUT. The gain table contains the desired gain-transfer function. It also is possible to use multiple gain-transfer LUTs that are selected by some other input signal.
As mentioned earlier, the multiplying DAC shown in Figure 1 is optional. It can be used to put a slight amount of gain on the input signal before input to the analog-to-digital converter. This step can be done to boost the input signal as much as possible before digitizing. It also will increase the range of the ADC that's used. In some instances, this approach will yield better performance as well.
Once the MDAC gain is set, it will automatically multiply the incoming analog signal by the digital-gain value. The output of the MDAC then feeds the ADC. This ADC is where the digital rectification takes place.
Once the microcontroller design has been completed, it's time to proceed with an actual example application. This particular example makes reference to the Cypress Microsystems PSoC Mixed Signal Array. The input- and output-signal specifications, which form the basis for the nominal input level and maximum input threshold, are as follows:
- Minimum input: −25 dBm
- Maximum input: 0 dBm
- Nominal input: −12.5 dBm
- Nominal output: −10 dBm
- Impedance: 600 Ω
- Gain-reduction attack time: 20 ms
- Gain-expansion release time: 40 ms
Given these performance specifications, the PSoC internal ADC reference was configured to use its internal bandgap (+1.3-V) reference. The internal AGND was selected to be VCC/2. This AGND provided an operating range for the ADC of VCC/2 plus or minus the bandgap voltage. Or, it could have a full-scale signal range of ±1.3 V centered about +2.5 Vdc (AGND). The ADC was a 6-b SAR type. Therefore, each bit had a value of: \[2.6 V/(26)\] ~= 41 mV.
The MDAC was set up to have a gain of 1.15. This was the maximum gain allowed before the (max) input signal was clipped. If the max input voltage was lower, the gain could be increased. Better ADC resolution would then be attained.
For this configuration, the ADC outputs can be seen in the equations below (SEE EQUATIONS). Using these values, the nominal ADC output is a conversion value of '6.' In contrast, the minimum value is approaching the bottom of the ADC range. Again, increasing the MDAC gain will improve this situation by allowing the signal to reach closer to the ADC limit. Care must be used, however, so that the maximum input will not clip the ADC.
Even though additional MDAC gain would clip the signal, this clipping may not be a problem. A signal that's large enough to clip the ADC would in turn receive maximum gain compression. For this example, keep the MDAC gain low enough to allow the full input-voltage range without clipping the ADC.
The next step is to use two digital timers to control the basic operation of the AGC circuit. One of these timers will control the ADC sample rate, whereas the other timer will control the gain compression and expansion 'attack' and 'release' times. The sample timer determines when it's time to read the ADC. In the sample timer's interrupt service routine (ISR), the ADC is read, mathematically rectified, and then added to a 16-b sum.
Upon summing 32-b conversions, a flag will be set for the main loop to indicate that it is time to process the sample set. Upon completing 32 analog-to-digital-converter samples (approximately every 5 ms), another flag will be set. This flag, which is known as the sample-set complete, calls a subroutine to process the ADC-conversion sample set.
In this subroutine, the average of the 32 samples is computed. Next, the threshold is checked. If it is determined that gain compression or expansion is necessary, another flag is set to indicate this condition. A difference or delta value is computed between the actual ADC reading and the nominal value. This value is used to form a basis for the amount of gain reduction/expansion that needs to be applied. Upon exiting this subroutine, the sample-set-complete flag is cleared, thereby allowing a new sample set to be accumulated.
The second timer is the attack/release timer. It is configured to interrupt every 1 ms. The ISR for this timer has two flags: the attack-release X1 (or tick_X1) and X2 (or tick_X2). The specification for this example calls for a release time of two times the attack time. This is accomplished by generating a tick_X2 flag every two interrupts or approximately 2 ms. The attack time is based on the tick_X1 flag, which occurs every interrupt cycle or 1 ms. These flags also are detected in the main loop of the microcontroller.
Once the sample set has been processed—as described previously—the ISR for the attack/release function will inform the main loop when a 1-ms and 2-ms timer interval have elapsed. These intervals correspond to a 1X compression time and a 2X release time.
The term "attack" refers to the system's desired reaction time to an over-signal condition. Sometimes, excessively fast reaction times can cause undesirable effects on the signal—particularly when considering speech or music signals. To perform the attack function, one first needs to test the 1-ms (X1) compression flag. If it is set, execute a subroutine that will test the other flags that were set in the sample-set processing function. This step will determine if gain compression is necessary.
If a data channel needs compression, the subroutine must ensure that there is a difference between the threshold and the actual value (using the delta value). Furthermore, the subroutine must check that the gain setting isn't already at the lower limit. If both conditions are satisfied, the subroutine can decrease the channel's programmable-gain-amplifier (PGA) gain by retrieving the next-lower gain setting from the gain-transfer-function lookup table. If the compression flag isn't set, the gain-compression-function routine is exited. No changes will be made to the PGA gain.
Every 1-ms time interval, this subroutine is entered and the above action takes place. Additionally, the sample-set processing subroutine will be called every 5 ms. The delta value will therefore be refined with each pass until the signal level is within the nominal band. This technique should aid in controlling compression/expansion overshoot. It also should help minimize gain oscillation.
"Release" is the counterpart of attack. It refers to how fast the gain-compression function is allowed to diminish or release. Like excessively fast attack times, a fast release time is sometimes undesirable. When either or both of these parameters is allowed to run too fast, a pumping effect on the signal can be observed. This pumping effect occurs when the AGC system reacts quickly and harshly on the over- and under-signal conditions. This result can be particularly undesirable when dealing with audio signals.
To perform the release function, the X2 release flag must be tested. Again, this flag is set every 2 ms. Upon detecting this flag, another subroutine is called. This subroutine tests the other flags that indicate that the channel has dropped below the lower threshold and needs to be expanded. These flags are actually set/cleared in the sample-set processing subroutine.
If a channel needs expansion, this subroutine will make sure that there is a difference between the threshold and the actual value (using the delta value). It also will ensure that the gain setting isn't already at the highest level. If both conditions are satisfied, the subroutine will increase the channel's PGA gain by retrieving the next-higher gain setting from the gain-transfer-function lookup table. If no expansion flag is set for a particular channel, the gain-expansion function is simply bypassed. The subroutine is then exited.
Every 2 ms, this subroutine is entered and the above action takes place. In addition, the sample-set processing subroutine is called every 5 ms. The delta value is refined with each pass until the signal level is within the nominal band. This technique should aid in controlling compression/expansion overshoot. It also should help minimize gain oscillation.
There are only a few design limitations that result from a digital implementation of an analog automatic gain control. Tradeoffs can be used, however, to minimize the effect of each limitation. One tradeoff is response time (FIG. 3). From the compression and expansion curves, it's clear that there is a definite response time associated with the rising and falling edges of an input step function (FIG. 4). In the example presented here, it is approximately 5 ms. This measure is determined by the time that it takes to call the sample-set processing subroutine. It is based on a signal-rectifier design that accumulates 32 samples at 150 µs each or 4.8 ms. A compression or expansion sequence cannot be initiated until a complete sample set is obtained. The response could be as long as ~5 ms, depending on the input conditions.
If the design can tolerate this response time, no further adjustments are necessary. In a case in which this response time is not acceptable, two options exist:
- Lower the number of samples required for a complete sample set from 32 to some other number (and adjust the equations accordingly). Actually, the sample-set size could be reduced to 22 without theoretically reducing the accuracy. Basic tests have shown that sample-set sizes below this (i.e., 24 = 16) also can produce acceptable results, improve transient response, and produce similarly tight math loops.
- Increase the rate of the sample timer. This increase will cause the ADCs to be read at a faster rate, which will accumulate the sum more quickly. Care should be exercised so as not to exceed the sample-rate limit of the ADC. Also, the Nyquist sample rate for all of the signals of interest must be satisfied.
Either of the above techniques will serve to improve the system's transient response. Depending on the exact design requirements, a combination of the two techniques may yield even better results. As with any microcontroller design, one must always keep in mind the additional computational strain that is placed on the microcontroller when increasing the sample rates.
Shortening the ADC sample period from 150 to 100 µs results in an improved transient response time (FIG. 5). This improvement comes from the shorter accumulation time—now only 3.2 ms—needed to acquire the 32 data samples. As stated earlier, the overall accuracy of this example design will improve if the MDAC gain can be increased so that the maximum range of the ADC is used. If greater ADC range is desired, it may be acceptable to increase the MDAC gain to its maximum of '2.' Then, let the high signal clip into the input of the ADC.
Even with clipping, the nominal positive threshold will still be within the active region of the ADC. Because anything above this level will need compression, having the ADC input clipped doesn't really pose a problem.
Microcontrollers are becoming more powerful. Many such devices include analog-signal-processing capabilities—functions that normally would require many external components but now may be performed in a single chip. Hopefully, this article has presented some techniques that you may find useful for your AGC or other mixed-signal-processing applications.