From f59fb8f67d2d324ab13a2b5faf274e0bcb057e87 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Fri, 14 Dec 2018 17:16:15 +0000 Subject: [PATCH] added git-svn-id: http://moon:8086/svn/matlab/trunk@100 801c6759-fa7c-4059-a304-17956f83a07c --- adc_eval.m | 41 ++++++++++++ common/f2l.m | 30 +++++++++ common/lfsr.m | 30 +++++++++ common/manchester.m | 64 ++++++++++++++++++ flexRET_eval.m | 15 +++++ garage.m | 156 ++++++++++++++++++++++++++++++++++++++++++++ garage_ip.m | 152 ++++++++++++++++++++++++++++++++++++++++++ gardner_eval.m | 60 +++++++++++++++++ im_eval.m | 98 ++++++++++++++++++++++++++++ interpol_eval.m | 50 ++++++++++++++ kalman1d_eval.m | 69 ++++++++++++++++++++ mix_eval.m | 38 +++++++++++ motor_eval.m | 50 ++++++++++++++ ppm_eval.m | 41 ++++++++++++ qdemod_eval.m | 54 +++++++++++++++ test_motor_eval.m | 59 +++++++++++++++++ tunable_bandpass.m | 114 ++++++++++++++++++++++++++++++++ 17 files changed, 1121 insertions(+) create mode 100755 adc_eval.m create mode 100755 common/f2l.m create mode 100755 common/lfsr.m create mode 100755 common/manchester.m create mode 100755 flexRET_eval.m create mode 100755 garage.m create mode 100755 garage_ip.m create mode 100755 gardner_eval.m create mode 100755 im_eval.m create mode 100755 interpol_eval.m create mode 100644 kalman1d_eval.m create mode 100755 mix_eval.m create mode 100755 motor_eval.m create mode 100755 ppm_eval.m create mode 100755 qdemod_eval.m create mode 100755 test_motor_eval.m create mode 100755 tunable_bandpass.m diff --git a/adc_eval.m b/adc_eval.m new file mode 100755 index 0000000..d5410f0 --- /dev/null +++ b/adc_eval.m @@ -0,0 +1,41 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} adc_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-12-05 + +function retval = adc_eval (x, numStages) + +retVal = []; + +for n=numStages-1:-1:0, + k = 2^n; + + if x >= k, + retVal = [retVal 1]; + x = x - k; + else + retVal = [retVal 0]; + end + x = x +end +retVal +endfunction diff --git a/common/f2l.m b/common/f2l.m new file mode 100755 index 0000000..e4331dd --- /dev/null +++ b/common/f2l.m @@ -0,0 +1,30 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} f2l (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-10-15 + +function l = f2l (f_MHz) + +c = 3.0e8 +l = 1.0e-4*c/f_MHz; + +endfunction diff --git a/common/lfsr.m b/common/lfsr.m new file mode 100755 index 0000000..8ba5b78 --- /dev/null +++ b/common/lfsr.m @@ -0,0 +1,30 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} lfsr (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-12-05 + +function next = lfsr (size, poly, curr) + + +next = 2*xor(curr, poly); + +endfunction diff --git a/common/manchester.m b/common/manchester.m new file mode 100755 index 0000000..83568cb --- /dev/null +++ b/common/manchester.m @@ -0,0 +1,64 @@ +function y = manchester(x, type) +N = length(x); + +mtype = 'ieee802.3'; +if (nargin > 1) + mtype = type +end + +t = -1; +v = -1; + +if (strcmp(mtype, 'I') || strcmp(mtype, 'ieee802.3')) + v = 0; + t = 1; +end + +if (strcmp(mtype, 'II') || strcmp(mtype, 'Thomas')) + v = 0; + t = 2; +end + +if (strcmp(mtype, 'BP-M')) + v = 1; + t = 1; +end + +if (strcmp(mtype, 'BP-S')) + v = 0; + t = 1; +end + +if (t == 1) + s = 1; + y = []; + for n=1:N, + if x(n) == v + s = not(s); + y = [y s]; + y = [y s]; + else + s = not(s); + y = [y s]; + s = not(s); + y = [y s]; + end + end +end + +if (t == 2) + s = 1; + y = []; + for n=1:N, + if x(n) == v + y = [y not(s)]; + y = [y s]; + else + y = [y s]; + y = [y not(s)]; + end + end +end + +endfunction + diff --git a/flexRET_eval.m b/flexRET_eval.m new file mode 100755 index 0000000..99b2c5d --- /dev/null +++ b/flexRET_eval.m @@ -0,0 +1,15 @@ +function flexRET_eval(tilt_ref) + +%tilt_ref = 3356 +tilt_min = 4000; +unload_steps = 560; + +tilt_target_distance = tilt_min - unload_steps + +tooth_steps = 360/14*4 + +k = fix(tilt_target_distance / tooth_steps + 0.5) +tilt_min_raster = fix(tilt_ref + k*tooth_steps + 0.5) + +probe = (tilt_min_raster-tilt_ref) / tooth_steps + diff --git a/garage.m b/garage.m new file mode 100755 index 0000000..bbf0119 --- /dev/null +++ b/garage.m @@ -0,0 +1,156 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} garage (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-12-06 + +function bits = garage (varargin) + +params = struct ('numSamplesPerSym', 4, 'with_filter', 0, 'k_noise', 0.04); +units = struct ('numSamplesPerSym', 'sps', 'with_filter', '', 'k_noise', ''); + +% Parse parameters +names = fieldnames(params); +for k=1:nargin-1, + for n=1:length(names), + if strcmpi(varargin{k}, names{n}) + params.(names{n}) = varargin{k+1}; + end + end +end + +print_parameters(params, units) + +k_n = params.k_noise; % NOise +k_s = 1.0; % Sym + +numSamplesPerSym = params.numSamplesPerSym; +baud = 9600; +fs = baud * numSamplesPerSym; + +numSyms = 50; +numBursts = 3; +numSymsPauseBetweenBurst = 50; + +syms = rand(numSyms, 1) > 0.5; + +bit = 0; +syms_m = []; + +% Line coding +for n=1:numSyms, + if syms(n) == 1 + syms_m = [syms_m bit]; + bit = not(bit); + syms_m = [syms_m bit]; + bit = not(bit); + else + syms_m = [syms_m bit]; + syms_m = [syms_m bit]; + bit = not(bit); + end +end + + +% Upconvert +x = []; + +for k=1:numBursts + for n=1:2*numSyms, + for m=1:numSamplesPerSym, + x = [x syms_m(n)]; + end + end + x = [x zeros(1, numSymsPauseBetweenBurst*numSamplesPerSym)]; +end + +% Channel +[b,a] = butter(2, baud/fs); + +if params.with_filter + x = filter(b, a, x); +end +y = k_s*x + k_n*randn(1, length(x)); + +y = wavread('seq.wav'); + +N = length(y); +n = 1:N; + + +bit = 0; +count = numSamplesPerSym; + +smp = []; +smp_n = []; +bits = []; + +% Receive +state = "Init"; +peakFindCount = 10; +v_min = 0; +v_max = 0; +for n=1:N + state_next = state; + v_thr = (v_max - v_min) / 2; + if y(n) < v_min + v_min = y(n); + elseif y(n) > v_max + v_max = y(n); + end + v_min = v_min + 1e-5*(v_thr - v_min); + v_max = v_max - 1e-5*v_max; + if strcmp(state, "Init") + state_next = "Decode"; + elseif strcmp(state, "Decode") + bit_curr = y(n) > v_thr; + if (bit ~= bit_curr) + count = fix(numSamplesPerSym/2); + bit = bit_curr; + end + if count > 0 + count = count - 1; + else + count = numSamplesPerSym-1; + smp = [smp y(n)]; + smp_n = [smp_n n]; + bits = [bits bit_curr]; + end; + _cnt(n) = count; + end + _v_tr(n) = v_thr; + + if ~strcmp(state, state_next) + fprintf(stdout, "Change state: %s => %s\n", state, state_next); + state = state_next; + end +end +bits = bits'; + +n = 1:N; + +% Plot +subplot(2, 1, 1) +plot(n, y, '-o', smp_n, smp, 'rx', n, _v_tr, 'y'); grid; +subplot(2, 1, 2) +plot(n, _cnt); grid; + +endfunction diff --git a/garage_ip.m b/garage_ip.m new file mode 100755 index 0000000..640165e --- /dev/null +++ b/garage_ip.m @@ -0,0 +1,152 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} garage (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-12-06 + +function [bits, x] = garage_ip (numSamplesPerSym) + +k_n = 0.00; % NOise +k_s = 1.0; % Sym + +baud_init = 9600; +fs = baud_init * numSamplesPerSym; + +numSyms = 100; +numBursts = 3; +numSymsPauseBetweenBurst = 50; + +syms = rand(numSyms, 1) > 0.5; + +bit = 0; +% Line coding +syms_m = manchester(syms); + +% Upconvert +x = []; + +for k=1:numBursts + for n=1:2*numSyms, + for m=1:numSamplesPerSym, + x = [x syms_m(n)]; + end + end + x = [x zeros(1, numSymsPauseBetweenBurst*numSamplesPerSym)]; +end + +% Channel +[b,a] = butter(2, numSamplesPerSym/4*baud_init/fs); +y = resample (x, 131, 121); +%y = x; +y = k_s*filter(b, a, y) + k_n*randn(1, length(y)); + +N = length(y); + +baud = baud_init; +bit = 0; + +% The master clock counter +countReload = numSamplesPerSym-1; +count = countReload; +smp = []; +smp_n = []; +bits = []; + +v_min = 0; % Threshold max +v_max = 0; % Threshold min +hyst_thr = 0.5; % Threshold hysteresis +rho_thr = 1e-5; % Threshold forgetting factor +alpha_lead = 0.016; % Symbol syncronizer loop filter lead +alpha_lag = 0.000008; % Symbol syncronizer loop filter lag +lag_accu = 1; % Symbol syncronizer loop filter +ns = 1; % Start sample source +n = 1; % Start sample sink +err = 0; % Error +while ns < N + % Get next interpolated sample + is = fix(ns); + mu = ns - is; + ys = (1-mu).*y(is) + mu.*y(is+1); + + % Calculate threshold + v_thr = (v_max - v_min) / 2; + if ys < v_min + v_min = ys; + elseif ys > v_max + v_max = ys; + end + v_min = v_min + rho_thr*(v_thr - v_min); + v_max = v_max - rho_thr*v_max; + + % Detect bit change + bitChg = 0; + if (bit == 1) + if ys < (hyst_thr*v_thr) + bit = 0; + bitChg = 1; + end + else + if ys > (hyst_thr*v_thr) + bit = 1; + bitChg = 1; + end + end + + % Calc error + if (bitChg) + err = -(count - fix(numSamplesPerSym/2)); + end + + % Sample bit at baud rate = fs/numSamplesPerSym + if count == 0 + smp = [smp ys]; + smp_n = [smp_n n]; + bits = [bits bit]; + end; + if count > 0 + count = count - 1; + else + count = countReload; + end + vcorr = alpha_lead*err + lag_accu; + lag_accu = lag_accu + alpha_lag*err; + baud = vcorr*fs/numSamplesPerSym; + _err(n) = err; + _baud(n) = baud; + _cnt(n) = vcorr; + _v_tr(n) = v_thr; + _ys(n) = ys; + n = n + 1; + ns = ns + vcorr; +end +bits = bits'; + +n = 1:length(_ys); + +% Plot +subplot(3, 1, 1) +plot(n, _ys, smp_n, smp, 'ro', n, _v_tr, 'y'); grid; +subplot(3, 1, 2) +plot(n, _err); grid; +subplot(3, 1, 3) +plot(n, _baud); grid; + +endfunction diff --git a/gardner_eval.m b/gardner_eval.m new file mode 100755 index 0000000..a8363e8 --- /dev/null +++ b/gardner_eval.m @@ -0,0 +1,60 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} gardner_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-12-13 + +function gardner_eval (x, nBitsPerSample, phase) +if mod(nBitsPerSample, 2) + error ("nBitsPerSample must be divisable by 2!"); +end + +Z = zeros(1,3); + +countReload = nBitsPerSample/2; +count = countReload-1; +N = length(x); +vc = 0; +k = 1; +for n=1:N, + + if count == phase + Z = [x(n) Z(1:2)]; + vc = Z(2) * (Z(3) - Z(1)); + _y(k) = x(n); + k = k + 1; + end + + if count == 0 + count = countReload-1; + else + count = count - 1; + end + + _vc(n) = vc; +end + + +subplot(2,1 ,1) +plot(1:N, _vc); grid; +subplot(2,1 ,2) +plot(1:k-1, _y, '-o'); grid; +endfunction diff --git a/im_eval.m b/im_eval.m new file mode 100755 index 0000000..c0a46c2 --- /dev/null +++ b/im_eval.m @@ -0,0 +1,98 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} im_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-10-22 + +function s = im_eval () + +s1 = sig_gen('lo', 'sine', [0 500], [0.0 1]); +s2 = sig_gen('s1', 'sine', [0 100 500 900 1400], [0.0 0.5 1.0 0.5 0.25]); + +s = modulate(s1, s2); + +close all; +plotSig(s); +function s = sig_gen(name, type, freq, amp) + +peaks = []; +switch type + case 'sine' + f = freq; + a = amp; + case 'rect' + N = 10; + f = []; + a = []; + k = 1; + for n=1:N + f = [f k*freq]; + a = [a amp/k]; + k = k + 2; + end +endswitch + +s = struct('name', name, 'f', f, 'a', a); +endfunction + +function m = modulate(s1, s2) + +m = struct('name', sprintf("%s x %s", s1.name, s2.name), 'f', [], 'a', []); + +f = []; +a = []; + +for i=1:length(s1.f) + for j=1:length(s2.f) + f1 = s1.f(i) - s2.f(j); + f2 = s1.f(i) + s2.f(j); + a = s1.a(i) * s2.a(j); + + m = addFreq(m, f1, a); + m = addFreq(m, f2, a); + end +end + +endfunction + +function x = addFreq(x, f, a) + +found = 0; +for i=1: length(x.f) + if (x.f(i) == f) + found = i; + break; + end +end +if (found > 0) + x.a(found) = x.a(found) + a; +elseif a ~= 0 + x.f = [x.f f]; + x.a = [x.a a]; +end + +endfunction + +function plotSig(s) + stem(s.f, s.a, 'baseline', -10); grid; legend(s.name) +endfunction + +endfunction diff --git a/interpol_eval.m b/interpol_eval.m new file mode 100755 index 0000000..fc0acd4 --- /dev/null +++ b/interpol_eval.m @@ -0,0 +1,50 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} interpol_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-11-21 + +function interpol_eval () + +N = 20; +n = (0:N-1); + +f = 1; +x = cos(2*pi*f*n/N); + +Ts = 0.75; + +ii = 0; +ns = []; +while ii < (N-1) + ns = [ns ii]; + ii = ii + Ts; +end + +is = fix(ns); +fs = ns - is; +is = is + 1; + +xs = (1-fs).*x(is) + fs.*x(is+1); + +plot(n, x, '-*', ns, xs, 'rx'); grid; + +endfunction diff --git a/kalman1d_eval.m b/kalman1d_eval.m new file mode 100644 index 0000000..1dafd30 --- /dev/null +++ b/kalman1d_eval.m @@ -0,0 +1,69 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} kalman1d_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-09-28 + +function kalman1d_eval() + +var_meas = 1.0; +pos_true = 10.0; +k_motion = 0.0; +f_motion = 2.0; + +x_h = 0.0; % initial guess +v_x = 0.5; % initial guess +v_y = 1.0; % initial guess +v_y_h_0 = 0; +v_y_h = 0; + +N = 10000; +for n=1:N, + x_h_(n) = x_h; + v_x_(n) = v_x; + + y = pos_true + var_meas*randn() + k_motion*sin(f_motion*2*pi*n/N); + w = v_x/(v_x + v_y); + x_h = x_h + w * (y - x_h); + v_x = 1/(1/v_x + 1/v_y); + v_y_h_0 = 0.5*v_y_h_0 + 0.5*(y-x_h)^2; + y_(n) = y; + v_y_h = 0.995*v_y_h + 0.005*v_y_h_0; + v_y_h_(n) = sqrt(v_y_h); + w_(n) = w; + +end + +subplot(2,1,1) +plot(1:N, y_, 1:N, x_h_, '-r'); grid; legend('y', 'x_h') +subplot(2,1,2) +plot(1:N, v_x_, '-r', 1:N, w_, '-b'); grid; legend('v_x', 'w') + + + + + + + + + +endfunction + diff --git a/mix_eval.m b/mix_eval.m new file mode 100755 index 0000000..3e7da73 --- /dev/null +++ b/mix_eval.m @@ -0,0 +1,38 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} mix_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-11-30 + +function [retval] = mix_eval (input1, input2) + +fs = 2e16; +fm = 1.0e6; +bw = 1.0e5; +fif = 0; +flo = fm - fif; + + +fm_p0 = mod(fm - flo, fs) +fm_p1 = mod(fm + flo, fs) + + +endfunction diff --git a/motor_eval.m b/motor_eval.m new file mode 100755 index 0000000..5f1fb25 --- /dev/null +++ b/motor_eval.m @@ -0,0 +1,50 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} motor_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-08-01 + +function cnt_expected = motor_eval (cnt_tooth, cnt, round_mode) + +cnt_expected = 0 + +cnt_err = mod(abs(cnt),cnt_tooth); +if (cnt_err >= 0.5*cnt_tooth) + cnt_err = cnt_err - cnt_tooth; +end + +if strcmpi(round_mode, 'nearest') + cnt_expected = cnt - sign(cnt)*cnt_err; + +elseif strcmpi(round_mode, 'positive') + cnt_expected = cnt - cnt_err + if (cnt < 0) + cnt_expected = cnt - cnt_err + cnt_tooth + end + +elseif strcmpi(round_mode, 'negative') + cnt_expected = cnt - cnt_err + +end + +err = cnt - cnt_expected + +endfunction diff --git a/ppm_eval.m b/ppm_eval.m new file mode 100755 index 0000000..77f348b --- /dev/null +++ b/ppm_eval.m @@ -0,0 +1,41 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} ppm_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-10-17 + +function ppm_eval (kp, kn) + +Tp = 200; % +Tp_s = 200 ; +hp = [ones(1, Tp_s)]; + +x = kp*[zeros(1, 10*Tp) ones(1, Tp) zeros(1, 20*Tp) ones(1, Tp) zeros(1, 10*Tp)]; +x = x + kn*randn(1, length(x)); +n = 1:length(x); + + +y = filter(hp, 1, x)/Tp; + + +plot(n, x, n, y, '-r'); grid; + +endfunction diff --git a/qdemod_eval.m b/qdemod_eval.m new file mode 100755 index 0000000..ae37b54 --- /dev/null +++ b/qdemod_eval.m @@ -0,0 +1,54 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} qdemod_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-11-16 + +function qdemod_eval + +fa = 1000; +T = 1/fa; +N = 1000 + +t = (0:N-1)*T; + +omega_x_0 = 100.0; +omega_x_1 = 200.0; +phi_x = pi/8*0; + +omega_lo = 150.0; + + +lo_r = cos(2*pi*omega_lo*t); +lo_i = sin(2*pi*omega_lo*t); + +x = cos(2*pi*omega_x_0*t + phi_x) + cos(2*pi*omega_x_1*t + phi_x); +y = x.*lo_r + x.*lo_i*i; + +subplot(2,1,1); +plot(t, y, t, x); grid; +subplot(2,1,2); +Y = fftshift(fft(y, N))/N; +X = fftshift(fft(x, N))/N; +f = (-length(X)/2:length(X)/2-1)/N*fa; +plot(f, abs(X), f, abs(Y)); grid; + +endfunction diff --git a/test_motor_eval.m b/test_motor_eval.m new file mode 100755 index 0000000..8a5c6c7 --- /dev/null +++ b/test_motor_eval.m @@ -0,0 +1,59 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} test_motor_eval (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-08-01 + +function [retval] = test_motor_eval () + +k = 100; +% [cnt, expected] +test_nearest = [ 10 0; 20 0; 49 0; 50 100; 51 100; -10 0; -20 0; -49 0; -50 -100; -51 -100]; +test_positive = [ 10 0; 20 0; 49 0; 50 100; 51 100; -10 0; -20 0; -49 0; -50 -100; -51 -100]; +test_negative = [ 10 0; 20 0; 49 0; 50 100; 51 100; -10 0; -20 0; -49 0; -50 -100; -51 -100]; + +disp('Run nearest:') +for i=1:length(test_nearest), + val = test_nearest(i,:)(1); + res_exp = test_nearest(i,:)(2); + result = motor_eval(k, val, 'nearest') + printf("%4u: %f: %f => %f ", i, val, res_exp, result) + if result == res_exp + printf("Pass!\n"); + else + printf("Failed!\n"); + end +end + +disp('Run positive:') +for i=1:length(test_positive), + val = test_positive(i,:)(1); + res_exp = test_positive(i,:)(2); + result = motor_eval(k, val, 'positive') + printf("%4u: %f: %f => %f ", i, val, res_exp, result) + if result == res_exp + printf("Pass!\n"); + else + printf("Failed!\n"); + end +end + +endfunction diff --git a/tunable_bandpass.m b/tunable_bandpass.m new file mode 100755 index 0000000..b8728a4 --- /dev/null +++ b/tunable_bandpass.m @@ -0,0 +1,114 @@ +## Copyright (C) 2018 Jens Ahrensfeld +## +## This program is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{retval} =} tunable_bandpass (@var{input1}, @var{input2}) +## +## @seealso{} +## @end deftypefn + +## Author: Jens Ahrensfeld +## Created: 2018-11-26 +## taken from: https://www.mwrf.com/components/bandpass-filters-feature-wide-tuning-ranges + +function tunable_bandpass(varargin) + +params = struct ('f_low_Hz', 100e6, 'f_high_Hz', 600e6, 'f_step_Hz', 1e6, 'B_geo_Hz', 20e6, 'R_geo', 1000, 'R_0', 50, 'k_gamma', 1.0); +units = struct ('f_low_Hz', 'Hz', 'f_high_Hz', 'Hz', 'f_step_Hz', 'Hz', 'B_geo_Hz', 'Hz', 'R_geo', 'Ω', 'R_0', 'Ω', 'k_gamma', ''); + +% Parse parameters +names = fieldnames(params); +for k=1:nargin-1, + for n=1:length(names), + if strcmpi(varargin{k}, names{n}) + params.(names{n}) = varargin{k+1}; + end + end +end + +print_parameters(params) +f_low_Hz = params.f_low_Hz; % Minimum tunable filter center frequency (Hz) +f_high_Hz = params.f_high_Hz; % Maximum tunable filter center frequency (Hz) + +B_geo_Hz = params.B_geo_Hz; % -3 dB RF filter bandwidth (in Hz) at the geometric center frequency +R_geo = params.R_geo; % Internal filter impedance (in Ω) at the geometric center frequency of the filter +R_0 = params.R_0; % Port impedance, usually taken as 50 Ω + +k_gamma = params.k_gamma; % Constant value. A value of γ = 1.0 results in a constant-Q filter design, + % while a value of γ = 2.0 results in a constant-bandwidth filter design. + % A value between one and two will yield a blend of the two filter characteristics. + % Inductor Q values will be more critical as the value of γ is increased. + +f_step_Hz = params.f_step_Hz; +f_Hz = f_low_Hz:f_step_Hz:f_high_Hz; +omega = 2*pi*f_Hz; + +f_geo_Hz = sqrt(f_low_Hz*f_high_Hz) % Hz +omega_geo = 2*pi*f_geo_Hz % rad/sec + +% Design I. +R_t = R_geo*(omega/omega_geo).^k_gamma; % Equ. (1) +L_c = R_geo/omega_geo % Equ. (2) + +C_tgeo = 1./(pi*sqrt(2)*R_geo*B_geo_Hz) % Equ. (3) +L_eff = 1./(omega_geo.^2*C_tgeo) % Equ. (4) +L_r = L_eff * L_c / (L_c - L_eff) % Equ. (5) + +C_t = (omega_geo./omega).^2 * C_tgeo; % Equ. (6) + +% Tuning capacitances C1 and C2 are given by Eqs. 7 and 8 +C_1 = (omega*R_0).^(-1) .* sqrt((omega_geo./omega).^k_gamma * (R_0/R_geo) + omega.^2.*C_t.^2*R_0*R_geo.*(omega/omega_geo).^k_gamma - 1); % Equ. (7) +C_2 = ((omega.^2.*C_t)./((omega_geo./omega).^(2*k_gamma) .* (1/R_geo)^2 + (omega.*C_t).^2) - (omega.^2*R_0^2.*C_1)./(1+(omega*R_0.*C_1).^2)).^(-1); % Equ. (8) + +C_1_geo = (omega_geo*R_0).^(-1) .* sqrt((omega_geo./omega_geo).^k_gamma * (R_0/R_geo) + omega_geo.^2.*C_tgeo.^2*R_0*R_geo.*(omega_geo/omega_geo).^k_gamma - 1) % Equ. (7) +C_2_geo = ((omega_geo.^2.*C_tgeo)./((omega_geo./omega_geo).^(2*k_gamma) .* (1/R_geo)^2 + (omega_geo.*C_tgeo).^2) - (omega_geo.^2*R_0^2.*C_1_geo)./(1+(omega_geo*R_0.*C_1_geo).^2)).^(-1) % Equ. (8) + +subplot (2,1,1) +plot(f_Hz*1e-6, C_1*1e12); grid; xlabel("f/MHz"), ylabel("C_1 [pF]"); +subplot (2,1,2) +plot(f_Hz*1e-6, C_2*1e12); grid; xlabel("f/MHz"), ylabel("C_2 [pF]"); + +% Design II. +L_c = R_geo/omega_geo; % Equ. (9) +L_eff = R_geo./(pi*sqrt(2)*B_geo_Hz); % Equ. (10) +L_r = L_eff - L_c; % Equ. (11) +C_tgeo = 1./(L_eff*omega_geo^2); % Equ. (12) +C_t = (omega_geo./omega).^2 * C_tgeo; % Equ. (13) +a = -omega.^2*R_0.*R_t; % Equ. (14) +b = 1./C_t; % ... +d = R_t/R_0; % Equ. (14) +alpha = (d-b.^2/a)./(1+b.^2/a - d); % Equ. (15) +beta = (b./a)./(1 + b.^2/a - d); % Equ. (16) +C_2 = alpha.*C_1 + beta; % Equ. (17) + + +function print_parameters(params) +align = 32; +names = fieldnames(params); +for n=1:length(names), + fprintf('%s', names{n}); + remain = align - length(names{n}); + if remain < 0 + error('Invalid variable length!'); + else + for j=1:remain + fprintf(' '); + end + fprintf('= %g %s\n', params.(names{n}), units.(names{n})); + end +end +endfunction + +endfunction