MATLAB Examples

Eye and Constellation Diagram

This example shows how to use comm.EyeDiagram and comm.ConstellationDiagram in analyzing communication systems.

Contents

Using the comm.EyeDiagram System Object

Plotting a modulated, filtered signal using PLOT does not display the characteristics of a modulation as clearly as an eye and constellation diagram. The eye diagram overlays many short segments, called traces, to reveal signal characteristics. The constellation diagram samples the signal at the symbol time and displays it in signal (i.e., I/Q) space. The simulation parameters (sample rate, samples per symbol) provide a high resolution for the analysis.

% Initialize system parameters
Fs = 10000;     % Sample rate
Rs = 100;       % Symbol rate
sps = Fs/Rs;    % Samples per symbol
rolloff = 0.5;  % Rolloff factor
M = 4;          % Modulation order (QPSK)

% Square root raised cosine filters.
filterSpan = 6;
filterGainTx = 9.9121;
transmitFilter = comm.RaisedCosineTransmitFilter('RolloffFactor', rolloff, ...
    'OutputSamplesPerSymbol', sps, ...
    'FilterSpanInSymbols', filterSpan, ...
    'Gain', filterGainTx);
receiveFilter = comm.RaisedCosineReceiveFilter('RolloffFactor', rolloff, ...
    'InputSamplesPerSymbol', sps, ...
    'FilterSpanInSymbols', filterSpan, ...
    'DecimationFactor', 1, ...
    'Gain', 1/filterGainTx);


% Generate modulated and pulse shaped signal
frameLen = 1000;
message = randi([0 M-1], frameLen, 1);
modulated = pskmod(message, M, pi/4);
filteredTx = transmitFilter(modulated);

t = 0:1/Fs:50/Rs-1/Fs; idx = round(t*Fs+1);
hFig = figure; plot(t, real(filteredTx(idx)));
title('Modulated, filtered in-phase signal');
xlabel('Time (sec)');
ylabel('Amplitude');
grid on;

% Manage the figures
hFig.Position = [50 400 hFig.Position(3:4)];

The Eye Diagram System object is used to plot multiple traces of a modulated, pulse shaped signal to analyze system characteristics. In the following figure, a 2D color eye diagram is plotted; the color intensity is proportional to the probability density function (PDF) of the input signal's amplitude at a given time. The upper plot is for the in-phase component of the analyzed signal, and the lower plot for the quadrature component. Since the default value of the SymbolsPerTrace property is two, the eye diagram spans two symbols. In the following example, the transmitted signal is analyzed. The intersymbol interference (ISI) introduced by the square-root, raised-cosine, pulse shaping filter can be clearly seen.

% Create an eye diagram object
eyeObj = comm.EyeDiagram(...
    'SampleRate', Fs, ...
    'SamplesPerSymbol', sps, ...
    'DisplayMode', '2D color histogram', ...
    'ShowImaginaryEye', true, ...
    'YLimits', [-0.7 0.7]) %#ok<NOPTS>

% Update the eye diagram object with the transmitted signal
eyeObj(0.5*filteredTx);

% Manage the figures:
eyeObj.Position = [hFig.Position(1)+hFig.Position(3) hFig.Position(2) ....
                   eyeObj.Position(3)*0.75 eyeObj.Position(4)];
hFig.Visible = 'off';
eyeObj = 

  comm.EyeDiagram with properties:

                  Name: 'Eye Diagram'

   Trace configuration
            SampleRate: 10000
      SamplesPerSymbol: 100
          SampleOffset: 0
       SymbolsPerTrace: 2

   Display configuration
           DisplayMode: '2D color histogram'
    EnableMeasurements: 0
      ShowImaginaryEye: 1
               YLimits: [-0.7000 0.7000]
              ShowGrid: 1
              Position: [400 220 640 460]

  Use get to show all properties

Now, the received signal will be examined. It is assumed that the received signal is corrupted by AWGN with symbol energy to noise power spectral density ratio (Es/No) of 20 dB and the receiver employs a matched filter. Therefore, the combined filter seen by the receiver is an approximate raised cosine filter with minimal ISI. One problem that is observed with this eye diagram is that the signal exceeds the amplitude limits of the object. As can be seen from the command line warning, the eye diagram object ignores out-of-range values.

EsNo = 20; SNR = EsNo - 10*log10(sps);

% Create an comm.AWGNChannel System object and set its NoiseMethod property
% to 'Signal to noise ratio (SNR)'. Set the 'SignalPower' property to the
% calculated input signal power.
channel = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)',...
  'SNR', SNR);
channel.SignalPower = var(filteredTx);
received = channel(filteredTx);
filteredRx = receiveFilter(received);

% Discard the existing eye diagram data
reset(eyeObj);

% Step the eye diagram object with the received signal
eyeObj(filteredRx);

figure(hFig);
plot(t, real(filteredRx(idx)));
title(['Modulated, filtered noisy in-phase signal, Es/No = ' ...
    num2str(EsNo) ' dB']);
xlabel('Time (sec)');
ylabel('Amplitude');
grid on;
Warning: An input value is outside the specified Y limits and is ignored. 

The amplitude limits can be adjusted to include the whole signal in the analysis. Since changing the amplitude limits resets the eye diagram object, the eye diagram needs to be updated with the same inputs again. With the new amplitude limits, the out-of-range warning is no longer thrown.

eyeObj.YLimits = [-1.5 1.5];
eyeObj(filteredRx);

The color scale can be set to logarithmic to get a better view of small PDF values in the eye diagram. The lines that pass through the eye opening around the zero level are more visible in this view. These lines are due to the initial transients of the input signal.

eyeObj.ColorScale = 'Logarithmic';

The accuracy of the eye diagram analysis increases as the number of symbols passed through the eye diagram object increases. In the following example, the eye diagram object is stepped in a loop and collects 2000 symbols of data. Observe that the widest amplitude opening of the eye occurs around 10 msec. This corresponds to the best sampling time.

eyeObj.ColorScale = 'Linear';
release(channel);
release(transmitFilter);
release(receiveFilter);
release(eyeObj);
frameLen = 50; nFrames = 40;
for p = 1:nFrames
    message = randi([0 M-1],frameLen,1);
    modulated = pskmod(message, M, pi/4);
    filteredTx = transmitFilter(modulated);

    channel.SignalPower = var(filteredTx);
    received = channel(filteredTx);
    filteredRx = receiveFilter(received);

    eyeObj(filteredRx);
end

The time offset of the eye diagram can be configure to move the open part of the eye along the time axis. A time offset of 5 msec is applied to the eye diagram of the following figure. The time offset is only for plotting purposes and does not affect the collected data.

eyeObj.SampleOffset = 5e-3*Fs;

A different color map can be specified for the eye diagram using the Style Dialog (View -> Style ...). The following example selects the 'jet' color map provided with MATLAB®. Any custom color map can also be specified. To get more information on color maps, see help colormap.

hide(eyeObj);

The background color of the eye diagram can be adjusted by specifying a custom color map. Since the background color is also the color that corresponds to zero PDF, the first element of the color map corresponds to the background color. In the following, the background color is set to black.

cmap = jet(64);
cmap(1,:) = [0 0 0];

The eye diagram object can also plot the received signal using individual traces instead of PDF values. Such a capability is useful for quickly obtaining a short-term view of the channel. The TracesToDisplay property of the eye diagram object determines the number of traces plotted by the object. Since only ten traces are plotted, the eye diagram does not fully represent the range of signal values.

eyeObj.SampleOffset = 0;
eyeObj.DisplayMode = 'Line plot';
eyeObj.TracesToDisplay = 10;
show(eyeObj);

TracesToDisplay is increased to get a better line-plot eye diagram.

eyeObj.TracesToDisplay = 100;

Using the comm.ConstellationDiagram System Object

comm.ConstellationDiagram generates a constellation diagram (also known as scatter plot), which is a plot of the in-phase component of the signal versus its quadrature component, decimated by a factor that is usually set to the number of samples per symbol, NSAMPS. The resulting plot shows the matched filtered signal sampled at the symbol rate. Since the combined transmit and receive filters is only an approximation to the ideal raised-cosine filter, the received symbols are not exactly the same as the transmitted symbols; they can be visually compared using the ShowReferenceConstellation and ReferenceConstellation properties.

% Close figures
close(hFig(ishghandle(hFig)));

% Pass the noiseless transmitted signal through a matched filter
filteredRx = receiveFilter(filteredTx);

% Create the constellation diagram
delay = 6*Fs/Rs;
filteredRxDelayed = filteredRx(delay+1:end);
cdObj = comm.ConstellationDiagram('SamplesPerSymbol', sps, ...
                                  'ShowReferenceConstellation', true, ...
                                  'ReferenceConstellation', qammod(0:3, 4, 'UnitAveragePower', 1));
cdObj(filteredRxDelayed);

% Manage the figures
cdObj.Position = [eyeObj.Position(1)+eyeObj.Position(3) eyeObj.Position(2) ....
                  cdObj.Position(3)*0.75 cdObj.Position(4)*0.75];

The signal trajectory can also be plotted by setting the ShowTrajectory property to true or by clicking the corresponding toolbar button. Distinct graphical properties can be assigned using the Style Dialog (View -> Style ...). The cyan line represents the in-phase component of the received signal trajectory versus the quadrature component, in signal space. The yellow dots represent the signal at the symbol sampling times. The red crosses represent the transmitted symbols for the given modulation scheme. This plot shows that, even though the signal moves about in signal space, its value approaches the value of the original signal when sampled at the symbol boundaries.

cdObj.ShowTrajectory = true;

The ColorFading property can be used to fade the older symbols, as a hardware oscilloscope does:

cdObj.ColorFading = true;

Analyzing Communication Systems Using Eye and Constellation Diagram

The following code plots the signal that is passed through an AWGN channel and matched filtered at the receiver (red line). Even though the noisy signal can be differentiated from the noiseless matched filtered signal (blue line), it is still difficult to determine the effect the noise has on the signal. Es/No for the noisy signal is 10 dB, which corresponds to a signal-to-noise ratio (SNR) of -10 dB.

% Create the plot
EsNo = 10; SNR = EsNo - 10*log10(sps);
frameLen = 1000;
release(channel);
release(transmitFilter);
release(receiveFilter);
channel.SNR = SNR;

message = randi([0 M-1],frameLen,1);
modulated = pskmod(message, M, pi/4);
filteredTx = transmitFilter(modulated);
filteredRxPerfect = receiveFilter(filteredTx);

channel.SignalPower = var(filteredTx);
received = channel(filteredTx);
filteredRx = receiveFilter(received);

t = 6/Rs:1/Fs:40/Rs-1/Fs;
idx = round(t*Fs+1);

hFig = figure;
plot(t,real(filteredRxPerfect(idx)),'b-',t,real(filteredRx(idx)),'r-');
title('Modulated, filtered in-phase signal and noisy signal');
xlabel('Time (sec)');
ylabel('Amplitude');
grid on;
legend('Modulated, filtered signal', ...
    ['Noisy, filtered signal, Es/No=' num2str(EsNo) ' dB'], ...
    'Location', 'SouthWest');

% Manage the figures
hFig.Position = [50 400 hFig.Position(3:4)];

The following figures are eye diagrams of the matched filtered noiseless received signal and the noisy signal. The eye diagrams clearly show the variation in the received signal from the transmitted signal due to the AWGN channel and the receive filter.

% Create the eye diagrams
eyeObj.YLimits = [-2 2];
release(eyeObj);
eyeObj(filteredRxPerfect);
eyeObj.Name = 'Noiseless Eye Diagram';

eyeObj.Position = [hFig.Position(1)+hFig.Position(3) eyeObj.Position(2)  ....
                   eyeObj.Position(3) eyeObj.Position(4)];

% Make an independent copy of the eye diagram object
eyeObjNoise = clone(eyeObj);
eyeObjNoise.Name = 'Noisy Eye Diagram, Es/No = 10 dB';
reset(eyeObjNoise);
eyeObjNoise(filteredRx);

% Manage the figures
close(hFig(ishghandle(hFig)));
eyeObjNoise.Position = [eyeObjNoise.Position(1)+eyeObjNoise.Position(3) eyeObjNoise.Position(2) ...
                        eyeObjNoise.Position(3) eyeObjNoise.Position(4)];

The following figures are constellation diagrams of the matched filtered noiseless received signal and the noisy signal. They clearly show the variation from the transmitted signal in the received signal at the ideal sampling times.

% Create the constellation diagrams
delay = 6/Rs * Fs;
cdObj       = comm.ConstellationDiagram('SamplesPerSymbol', sps);
cdObj.Name = 'Noiseless Constellation Diagram';
cdObjNoise  = comm.ConstellationDiagram('SamplesPerSymbol', sps);
cdObjNoise.Name = 'Noisy Constellation Diagram, Es/No = 10 dB';
cdObj(filteredRxPerfect(delay+1:end));
cdObjNoise(filteredRx(delay+1:end));

% Manage the figures
hide(eyeObj);
hide(eyeObjNoise);
cdObj.Position = [eyeObj.Position(1) eyeObj.Position(2) ....
                  cdObj.Position(3)*0.75 cdObj.Position(4)*0.75];
cdObjNoise.Position = cdObj.Position + [cdObj.Position(3) 0 0 0];

The following is a plot of the same transmitted signal received at an Es/No of 20 dB (magenta line). The variations caused by noise are smaller than with the previous signal (Es/No = 10 dB). In this case the eye and constellation diagrams are needed even more to determine the system characteristics.

% Close all open figures
hide(eyeObj);hide(eyeObjNoise); hide(cdObj);hide(cdObjNoise);

% Plot the transmitted signal
EsNo2 = 20; SNR2 = EsNo2 - 10*log10(sps);
channel.SNR = SNR2;
channel.SignalPower = var(filteredTx);
received = channel(filteredTx);
filteredRx = receiveFilter(received);

hFig = figure;
plot(t, real(filteredRxPerfect(idx)),'b-', t, real(filteredRx(idx)), 'm-');
title('Modulated, filtered signal and noisy signal');
xlabel('Time (sec)');
ylabel('Amplitude');
grid on;
legend('Modulated, filtered signal', ...
    ['Noisy signal, Es/No=' num2str(EsNo2) ' dB'], ...
    'Location', 'SouthWest');

% Manage the figures
hFig.Position = [50 400 hFig.Position(3:4)];

The following figures are eye diagrams of the first noisy signal and the second noisy signal. They clearly show that the variation in the second received signal is less than the first received signal.

% Close figures
close(hFig(ishghandle(hFig)));

% Create the eye diagram plots
eyeObjNoise2 = clone(eyeObj);
eyeObjNoise.Name = 'Noisy Eye Diagram, Es/No = 20 dB';
eyeObjNoise2(filteredRx);

% Manage the figures
eyeObjNoise2.Position = eyeObjNoise.Position; eyeObjNoise.Position = eyeObj.Position;
show(eyeObjNoise); show(eyeObjNoise2);

The following figures are constellation diagrams of the first noisy signal and the second noisy signal. They clearly show that the variation from the second received signal is less than the first received signal at the sampling points.

% Create constellation diagrams
cdObjNoise2 = clone(cdObj);
cdObjNoise2.Name = 'Noisy Constellation Diagram, Es/No = 20 dB';
release(cdObjNoise2);
cdObjNoise2(filteredRx);

% Manage the figures
cdObjNoise2.Position = cdObjNoise.Position; cdObjNoise.Position = cdObj.Position;
show(cdObjNoise); show(cdObjNoise2); hide(eyeObjNoise); hide(eyeObjNoise2);

Visualizing the Impact of Timing Errors Using Eye & Constellation Diagram

We can visualize the impact of timing errors using the eye and constellation diagram. This animation also shows that the constellation and eye diagram can be plotted with any offset. We use the second noisy matched filtered signal for this animation. The blue line in the eye diagram shows the sampling time. The red dots in the constellation diagram show the samples at the best sampling time, while the blue stars show the samples with a sampling time offset.

% Prepare scopes
hide(cdObjNoise);
cdObjNoise2.ShowTrajectory = true;
eyeObjNoise2.DisplayMode = '2D color histogram';
reset(eyeObjNoise2);
release(eyeObjNoise2);
release(cdObjNoise2);
eyeObjNoise2(filteredRx(idx));
cdObjNoise2(filteredRx(idx));

helperPrepareScatterEyeAnimation(cdObjNoise2, eyeObjNoise2);

% Create and animate the plots
for offset = (0:1:Fs/Rs-1)
  eyeObjNoise2.SampleOffset = offset;
  cdObjNoise2.SampleOffset  = offset;
  pause(0.1);
end