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];
end
% 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];
disp(f)
pause(0.001)
end
% plot the results
close all
figure
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')
|