40m QIL Cryo_Lab CTN SUS_Lab TCS_Lab OMC_Lab CRIME_Lab FEA ENG_Labs OptContFac Mariner WBEEShop
  40m Log  Not logged in ELOG logo
Message ID: 4245     Entry time: Thu Feb 3 16:08:06 2011
Author: Aidan 
Type: Update 
Category: Computer Scripts / Programs 
Subject: RCG VCO frequency error 

Joe and I were looking at the RCG VCO algorithm to determine if we could adapt it to run at a faster rate (you can currently change its frequency at 1Hz). I noticed that the algorithm that is used to calculated the values of sine and cosine at time T1  is a truncated Taylor series which uses the values of sine and cosine calculated at time T1 - Delta t . I was concerned that there would be an accumulating phase error so I tested the algorithm in MATLAB and compared it to a proper calculation of sine and cosine. It turns out that at a given 'requested' frequency there is a constantly accumulating phase error - which means that the 'actual' frequency of the RCG VCO is incorrect. So I have plotted the frequency error vs requested VCO frequency. It gets pretty bad!

 Here's the code I used:

dt = 1/16384;

diffList = [];
% set the frequencies

flist = 1:5:8192;
for f = flist;
    % get the 'accurate' values of sine and cosine
    tmax = 0.05;
    time1 = dt:dt:tmax;
    sineT = sin(2.0*pi*f*time1);
    cosineT = cos(2.0*pi*f*time1);
    % determine the phase change per cycle
    dphi = f*dt*2*pi;
    cosT1 = 1:numel(time1);
    sinT1 = 0*(1:numel(time1));
    % use the RCG VCO algorithm to determine the values of sine and cosine
    for ii = 1:numel(time1) - 1;                 
        cosNew = cosT1(ii)*(1 - 0.5*dphi^2) ...
                      - (dphi)*sinT1(ii);
        sinNew = sinT1(ii)*(1 - 0.5*dphi^2) ...
                      + (dphi)*cosT1(ii);
        cosT1(ii+1) = [ cosNew];
        sinT1(ii+1) = [ sinNew];
    % extract the phase from the VCO values of sine and cosine
    phaseT = unwrap(angle(cosineT + i* sineT));
    phaseT1 = unwrap(angle((cosT1 + i*sinT1)));
    % determine the phase error for 1 cycle
    diff = phaseT1 - phaseT;
    % determine the frequency error
    slope = (diff(2) - diff(1))/(dt);
    diffList = [diffList, slope];

% plot the results

close all
orient landscape
loglog(flist, abs(diffList/(2.0*pi)))
xlabel('Requested VCO Frequency (Hz)')
ylabel('Frequency error (Hz)')
grid on

print('-dpdf', '/users/abrooks/VCO_error.pdf')

Attachment 1: VCO_error.pdf  10 kB  | Hide | Hide all
ELOG V3.1.3-