% antennas. This simulation tests estimation of phase and freq of
% mixer LO.
%
-% [ ] built in hackrf_dc
-% [ ] test mode
-% [ ] compass needle
-% [ ] real time operation (or close to it)
+% [X] built in hackrf_dc
+% [X] test mode
+% [X] compass needle
+% [X] real time operation (or close to it)
fm;
more off;
format short
-simulate = 0; % set to 0 for HackRF input, 1 for simulated input
-
f = 48E3; % signal frequency
flo = 32.768E3; % LO frequency
m = 10^(-0/20); % modulation index of our mixer, how far each
% Main -------------------------------------------------------------------------
-if simulate
- % Simulate rx signal ---------------------------------------------------------
-
- t=0:N-1;
-
- % tx signal
-
- tx = fm_mod(Fs, fmod);
-
- % simulate rx signals at antenna 1 and 2 by adding noise. Note signal
- % at antenna 2 is phase shifted phi due to path difference. Both signals
- % experience a time of flight path different theta.
-
- n = sqrt(var/2)*randn(1,N) + j*sqrt(var/2)*randn(1,N);
- ant1 = tx*exp(j*(theta+phi)) + n;
- ant2 = tx*exp(j*(theta)) + n;
-
- % ant2 passed through mixer with local osc frequency wlo and phase alpha
-
- ant2_mix = 2.0*m*(ant2 .* cos(t*wlo + alpha));
-
- % The SDR receives the sum of the two signals
-
- rx = ant1 + ant2_mix;
-
-else
- % Off air signal from HackRF -------------------------------------------------------
-
- s1 = load_hackrf("df1.iq");
- rx = downsample(rot90(s1), Fshrf/Fs)/127;
- t = 1:length(rx);
-end
-
-Rx = (1/N)*fft(rx,N);
-
-% BPF each signal
-
-sam1 = filter(bcentre,1,rx);
-sam2 = exp( j*wlo*t) .* filter(bcentre, 1, rx .* exp(-j*wlo*t));
-sam3 = exp(-j*wlo*t) .* filter(bcentre, 1, rx .* exp( j*wlo*t));
-
-% Do the math on phases using rect math
-
-two_phi_est_rect = conj(sam2.*sam3) .* (sam1.^2);
-phi_est = angle(two_phi_est_rect)/2;
-
-phi_est_av = angle(mean(two_phi_est_rect))/2;
-
-printf("phi_est : %3.2f rads %3.1f degrees\n", phi_est_av, phi_est_av*180/pi);
-
-% some plots ....
+mode = "sample";
+finished = 0;
+while !finished
-figs = 0x1 + 0x20;
+ if strcmp(mode, "simulate")
+ % Simulate rx signal ---------------------------------------------------------
+
+ t=0:N-1;
-if bitand(figs, 0x1)
- figure(1);
- clf;
- plot((1:N)*Fs/N, 20*log10(abs(Rx)),'markersize', 10, 'linewidth', 2);
- axis([1 Fs -80 0])
- title('Rx signal at SDR input');
-end
-
-if bitand(figs, 0x2)
- figure(2)
- clf
- Sam1 = (1/N)*fft(sam1,N);
- Sam2 = (1/N)*fft(sam2,N);
- Sam3 = (1/N)*fft(sam3,N);
- subplot(311)
- plot((1:N)*Fs/N, 20*log10(abs(Sam1)),'markersize', 10, 'linewidth', 2);
- axis([1 Fs/2 -60 0])
- title('Band Pass filtered signals');
- subplot(312)
- plot((1:N)*Fs/N, 20*log10(abs(Sam2)),'markersize', 10, 'linewidth', 2);
- axis([1 Fs/2 -60 0])
- subplot(313)
- plot((1:N)*Fs/N, 20*log10(abs(Sam3)),'markersize', 10, 'linewidth', 2);
- axis([1 Fs/2 -60 0])
-end
-
-if bitand(figs, 0x4)
- figure(3)
- Np = 1000;
- subplot(311)
- plot(real(sam1(1:Np)))
- title('Band Pass filtered signals');
- subplot(312)
- plot(real(sam2(1:Np)))
- subplot(313)
- plot(real(sam3(1:Np)))
-end
-
-if bitand(figs, 0x8)
- figure(4)
- clf;
- hist2d([real(two_phi_est_rect)' imag(two_phi_est_rect)'],50)
- xmax = 2*mean(abs(two_phi_est_rect));
- axis([-xmax xmax -xmax xmax])
- title('Scatter Plot');
-end
-
-if bitand(figs, 0x10)
- figure(5)
- clf;
- subplot(211)
- plot(real(two_phi_est_rect(1:Np)))
- subplot(212)
- plot(imag(two_phi_est_rect(1:Np)))
- title('two phi est rect')
-end
-
-if bitand(figs, 0x20)
- figure(6)
- clf
- [r theta] = hist([angle(two_phi_est_rect)/2 -pi/2 pi/2],100);
- polar([theta pi+theta],[r r])
-end
-
-if bitand(figs, 0x40)
- figure(7)
- clf
- plot(phi_est)
- axis([0 length(phi_est(1:Np)) -pi/2 pi/2]);
- title('phi est')
+ % tx signal
+
+ tx = fm_mod(Fs, fmod);
+
+ % simulate rx signals at antenna 1 and 2 by adding noise. Note signal
+ % at antenna 2 is phase shifted phi due to path difference. Both signals
+ % experience a time of flight path different theta.
+
+ n = sqrt(var/2)*randn(1,N) + j*sqrt(var/2)*randn(1,N);
+ ant1 = tx*exp(j*(theta+phi)) + n;
+ ant2 = tx*exp(j*(theta)) + n;
+
+ % ant2 passed through mixer with local osc frequency wlo and phase alpha
+
+ ant2_mix = 2.0*m*(ant2 .* cos(t*wlo + alpha));
+
+ % The SDR receives the sum of the two signals
+
+ rx = ant1 + ant2_mix;
+ end
+
+ if strcmp(mode,"file") || strcmp(mode,"sample")
+ % Off air signal from HackRF stored in file ----------------------------------------------
+
+ if strcmp(mode,"sample")
+ [status output] = system("hackrf_transfer -r df1.iq -f 439000000 -n 10000000 -l 20 -g 40");
+ end
+ s1 = load_hackrf("df1.iq");
+ rx = downsample(rot90(s1), Fshrf/Fs)/127;
+ t = 1:length(rx);
+ end
+
+ Rx = (1/N)*fft(rx,N);
+
+ % BPF each signal
+
+ sam1 = filter(bcentre,1,rx);
+ sam2 = exp( j*wlo*t) .* filter(bcentre, 1, rx .* exp(-j*wlo*t));
+ sam3 = exp(-j*wlo*t) .* filter(bcentre, 1, rx .* exp( j*wlo*t));
+
+ % Do the math on phases using rect math
+
+ two_phi_est_rect = conj(sam2.*sam3) .* (sam1.^2);
+ phi_est = angle(two_phi_est_rect)/2;
+
+ phi_est_av = angle(mean(two_phi_est_rect))/2;
+
+ printf("phi_est : %3.2f rads %3.1f degrees\n", phi_est_av, phi_est_av*180/pi);
+
+ % some plots ....
+
+ figs = 0x1 + 0x2 + 0x20;
+
+ if bitand(figs, 0x1)
+ figure(1);
+ clf;
+ plot((1:N)*Fs/N, 20*log10(abs(Rx)),'markersize', 10, 'linewidth', 2);
+ axis([1 Fs -80 0])
+ title('Rx signal at SDR input');
+ end
+
+ if bitand(figs, 0x2)
+ figure(2)
+ clf
+ Sam1 = (1/N)*fft(sam1,N);
+ Sam2 = (1/N)*fft(sam2,N);
+ Sam3 = (1/N)*fft(sam3,N);
+ subplot(311)
+ plot((1:N)*Fs/N, 20*log10(abs(Sam1)),'markersize', 10, 'linewidth', 2);
+ axis([f-bw/2 f+bw/2 -60 0])
+ title('Band Pass filtered signals');
+ subplot(312)
+ plot((1:N)*Fs/N, 20*log10(abs(Sam2)),'markersize', 10, 'linewidth', 2);
+ axis([f+flo-bw/2 f+flo+bw/2 -60 0])
+ subplot(313)
+ plot((1:N)*Fs/N, 20*log10(abs(Sam3)),'markersize', 10, 'linewidth', 2);
+ axis([f-flo-bw/2 f-flo+bw/2 -60 0])
+ end
+
+ if bitand(figs, 0x4)
+ figure(3)
+ Np = 1000;
+ subplot(311)
+ plot(real(sam1(1:Np)))
+ title('Band Pass filtered signals');
+ subplot(312)
+ plot(real(sam2(1:Np)))
+ subplot(313)
+ plot(real(sam3(1:Np)))
+ end
+
+ if bitand(figs, 0x8)
+ figure(4)
+ clf;
+ hist2d([real(two_phi_est_rect)' imag(two_phi_est_rect)'],50)
+ xmax = 2*mean(abs(two_phi_est_rect));
+ axis([-xmax xmax -xmax xmax])
+ title('Scatter Plot');
+ end
+
+ if bitand(figs, 0x10)
+ figure(5)
+ clf;
+ subplot(211)
+ plot(real(two_phi_est_rect(1:Np)))
+ subplot(212)
+ plot(imag(two_phi_est_rect(1:Np)))
+ title('two phi est rect')
+ end
+
+ if bitand(figs, 0x20)
+ figure(6)
+ clf
+ [r theta] = hist([angle(two_phi_est_rect)/2 -pi/2 pi/2],100);
+ polar([theta pi+theta],[r r])
+ end
+
+ if bitand(figs, 0x40)
+ figure(7)
+ clf
+ plot(phi_est)
+ axis([0 length(phi_est(1:Np)) -pi/2 pi/2]);
+ title('phi est')
+ end
+
+ % when sampling hit any key to finish, finish after one pass in other modes
+
+ finished = 1;
+ if strcmp(mode, "sample")
+ finished = length(kbhit(1));
+ end
end