on
Compensating I/Q imbalance in radio receivers
Previously …
In the previous article, how to measure of I/Q imbalance was discussed. In this article we will show how to do actual compensation.
Compensation of I/Q imbalance
When the imbalance parameters $/phi$ (in radians) and $g$ are known, the compensator coefficients $c_1$ and $c_2$ are simply:
$$ c_1 = g \cdot \sin(\phi) $$ $$ c_2 = g \cdot \cos(\phi) $$
These coefficients need only be calculated once, as long as the imbalance parameters do not change.
The compensator itself, which is applied to every incoming I/Q sample, is quite simple: $$ I_c = c_2 \cdot I $$ $$ Q_c = Q + c_1 \cdot I $$ where $I_c$ and $Q_c$ are the compensated I and Q signals.
Directly obtaining $c_1$ and $c_2$
When the imbalance parameters $/phi$ (in radians) and $g$ are not known, which is almost always the case, calculating $c_1$ and $c_2$ isn’t possible and some other technique must be found. Luckily the smoothed accumulator values saccu1, saccu2 and saccu3 from the previous article can be used to estimate $c_1$ and $c_2$.
The equations needed are:
$$ c_1 = -\dfrac{\text{saccu}_1}{\text{saccu}_2} $$ $$ c_2 = \sqrt{\dfrac{\text{saccu}_3}{\text{saccu}_2}} $$
Code
The following should be added to the calc_iq_imbalance() routine from the previous article:
// protection for division by zero
if (saccu_2 > 0.0)
{
c1 = -saccu1/saccu_2
c2 = fsqrt(saccu3/saccu_2)
}
Note: the code to calculate g and phi estimates in calc_iq_imbalance() are no longer needed, except for reporting purposes.
The following compensator needs to be added after the I/Q estimation code:
Ic = c2*I
Qc = Q + c1*I
Initialise c1 to 0 and c2 to 1 at the start of the program.
References
The method implemented is described more throughly in A Low-complexity Feed-forward I/Q Imbalance Compensation Algorithm