|
передискретизация, как? |
|
|
|
 |
Ответов
(1 - 47)
|
Feb 22 2010, 16:59
|
.NET developer
  
Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532

|
Цитата как и какой функцией в MATLAB пересчитать частоту дискретизации с 6400 на 5760. Причём с тем же числом отсчётов (128). а как это с точки зрения такой науки как арифметика возможно? длительность сигнала одна и та же, число отсчетов в единицу времени меньше. откуда дополнительным отсчетам взяться? что вы хотите добиться - я не понял.
|
|
|
|
|
Feb 22 2010, 17:16
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 20-09-08
Пользователь №: 40 347

|
Цитата(TigerSHARC @ Feb 22 2010, 20:11)  P.S. не использую оконное взвешиване здесь так как ГОСТ это запрещает (для моего случая) В штате Индиана (США) в 1897 году был выпущен билль (см.: en:Indiana Pi Bill), законодательно устанавливающий значение числа Пи равным 3,2. Вобще странная ситуация, когда гост запрещает чтото использовать. Почему бы не использовать окна, если они позволяют получить установленные гостом харакетристики? Чудно однако.
|
|
|
|
|
Feb 22 2010, 17:33
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 20-09-08
Пользователь №: 40 347

|
Цитата(TigerSHARC @ Feb 22 2010, 20:23)  как это при ресемплинге происходит? Если частота понижается, то для сохранения количества отсчетов ПОСЛЕ ресамплинга надо уведить ИСХОДНОЕ количество отсчетов, потом применить рэсамплер. Код #include <stdio.h> #include <stdlib.h> #include <math.h> #define M_PI 3.14159265358979323846
// Функция сохранения результатов анализа в текстовый файл для // построения графиков. void saveToTXT(double* t, double* s, int n, char* fileName){ FILE *file = fopen(fileName, "w"); if(!file) return; for(int i = 0; i < n; i++) fprintf(file,"%e\t%e\n",t[i],s[i]); fclose(file); }
// Функция расчета кубического полинома // на основе модифицированного фильтра Фарроу double farrow3(double *y, double x){ double a3 = (y[3]-y[0])/6.0+(y[1]-y[2])/2.0; double a1 = (y[3]-y[1])/2.0-a3; double a2 = y[3]-a3-a1-y[2]; return x*(x*(x*a3+a2)+a1)+y[2]; }
int main(){ double Fs0 = 16E3; // исходная частота дискретизации double Fs1 = 12E3; // частота дискретизации после ресэмплинга int K = 128;// количество отсчетов после ресэмплинга int N = (int)K*Fs0/Fs1;// количество исходных отсчетов // выделяю память под исходный сигнал double* y0 = (double*) malloc(N*sizeof(double)); double* t0 = (double*) malloc(N*sizeof(double)); // выделяю память под результат ресэмплинга double* y1 = (double*) malloc(K*sizeof(double)); double* t1 = (double*) malloc(K*sizeof(double)); // формирую исходный сигнал for(int i = 0; i<N; i++){ t0[i] = double(i)/Fs0; y0[i] = cos(2*M_PI*3E3*t0[i]); // гармоническое колебание на частоте 3 кГц. } // произвожу ресэмплинг for(int i = 0; i<K; i++){ t1[i] = (double)i/Fs1; // текущий момент дискретизации int j = int((double)i*Fs0/Fs1)-2; // пересчитываю индекс исходного сигнала if(j<0) j =0; // если индекс отрицателььный то приравниваю его к 0 double x = (t1[i]-t0[j])*Fs0-2; // пересчитываю значение x y1[i] = farrow3(y0+j, x); // фильтр Фарроу t1[i] *= 1E3; // перевожу время результата ресэмплинга в мс } // перевожу исходное время в мс for(int i = 0; i<N; i++){ t0[i] *= 1E3; } // сохраняю результат в файлы saveToTXT(t0, y0, N, "исходный сигнал.txt"); saveToTXT(t1, y1, K, "resampling.txt"); system("Pause"); return 0; } все работает.
Сообщение отредактировал bahurin - Feb 22 2010, 17:40
|
|
|
|
|
Feb 22 2010, 17:42
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(bahurin @ Feb 22 2010, 20:16)  В штате Индиана (США) в 1897 году был выпущен билль (см.: en:Indiana Pi Bill), законодательно устанавливающий значение числа Пи равным 3,2.
Вобще странная ситуация, когда гост запрещает чтото использовать. Почему бы не использовать окна, если они позволяют получить установленные гостом харакетристики? Чудно однако. не хотелось бы чтобы дисскусия ушла в рксло обсуждения гостов, НО...! Там так сказано видимо потому, что частотное разрешение должно быть 5 Гц ( а не 50 как раньше)*, чтобы интергармоники (кратные 5 Гц) содержали полезную информацию, а не информацию о расползаном спектре. А чтобы обеспечить такое разрешние по частоте придётся брать выборку с огромным запасом, что скажется на быстродействии в реальном времени (к тому же предполагается работа сразу 8-ми каналов одновременно по 3 фазы тока и напряжения и нейтраль) Алгоритм с использованием окна, по-моему, на 8 каналов DSP проц не потянет (по моему)... Подход с передискретизацией и прямоуг. окне хорош тем, что позволит при заданной точности обеспечить минимальную выборку сигнала. Я думаю так. * имеется ввиду гост на качество электроэнергии и нововведённые госты на измерение гармоник и интергармоник в электрических сетях. но я не о ГОСТах я о самом алгоритме. Возможно же такое преобразование сигнала, чтобы в окно уместилось целое (с некоторой малой погрешностью) количесвто периодов. НО как!? 1) при интерполяции всегда используется фиксированное число отсчётов с АЦП? 2) количесвто отсчётов(идущих на блок БПФ) после ресемплинга остаётся прежним? (в моём случае 128) ... иными словами я хочу "поджать сигнал" во временной области под окно 0,02с.(даже если его период больше, или меньше этого значения), сохраненив его параметы. При передискретизации происходит этот эффект? но я не о ГОСТах я о самом алгоритме. Возможно же такое преобразование сигнала, чтобы в окно уместилось целое (с некоторой малой погрешностью) количесвто периодов. НО как!? 1) при интерполяции всегда используется фиксированное число отсчётов с АЦП? 2) количесвто отсчётов(идущих на блок БПФ) после ресемплинга остаётся прежним? (в моём случае 128) ... иными словами я хочу "поджать сигнал" во временной области под окно 0,02с.(даже если его период больше, или меньше этого значения), сохраненив его параметы. При передискретизации происходит этот эффект? но я не о ГОСТах я о самом алгоритме. Возможно же такое преобразование сигнала, чтобы в окно уместилось целое (с некоторой малой погрешностью) количесвто периодов. НО как!? 1) при интерполяции всегда используется фиксированное число отсчётов с АЦП? 2) количесвто отсчётов(идущих на блок БПФ) после ресемплинга остаётся прежним? (в моём случае 128) ... иными словами я хочу "поджать сигнал" во временной области под окно 0,02с.(даже если его период больше, или меньше этого значения), сохраненив его параметы. При передискретизации происходит этот эффект?
|
|
|
|
|
Feb 22 2010, 18:00
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(bahurin @ Feb 22 2010, 20:33)  Если частота понижается, то для сохранения количества отсчетов ПОСЛЕ ресамплинга надо уведить ИСХОДНОЕ количество отсчетов, потом применить рэсамплер. Код #include <stdio.h> #include <stdlib.h> #include <math.h> #define M_PI 3.14159265358979323846
// Функция сохранения результатов анализа в текстовый файл для // построения графиков. void saveToTXT(double* t, double* s, int n, char* fileName){ FILE *file = fopen(fileName, "w"); if(!file) return; for(int i = 0; i < n; i++) fprintf(file,"%e\t%e\n",t[i],s[i]); fclose(file); }
// Функция расчета кубического полинома // на основе модифицированного фильтра Фарроу double farrow3(double *y, double x){ double a3 = (y[3]-y[0])/6.0+(y[1]-y[2])/2.0; double a1 = (y[3]-y[1])/2.0-a3; double a2 = y[3]-a3-a1-y[2]; return x*(x*(x*a3+a2)+a1)+y[2]; }
int main(){ double Fs0 = 16E3; // исходная частота дискретизации double Fs1 = 12E3; // частота дискретизации после ресэмплинга int K = 128;// количество отсчетов после ресэмплинга int N = (int)K*Fs0/Fs1;// количество исходных отсчетов // выделяю память под исходный сигнал double* y0 = (double*) malloc(N*sizeof(double)); double* t0 = (double*) malloc(N*sizeof(double)); // выделяю память под результат ресэмплинга double* y1 = (double*) malloc(K*sizeof(double)); double* t1 = (double*) malloc(K*sizeof(double)); // формирую исходный сигнал for(int i = 0; i<N; i++){ t0[i] = double(i)/Fs0; y0[i] = cos(2*M_PI*3E3*t0[i]); // гармоническое колебание на частоте 3 кГц. } // произвожу ресэмплинг for(int i = 0; i<K; i++){ t1[i] = (double)i/Fs1; // текущий момент дискретизации int j = int((double)i*Fs0/Fs1)-2; // пересчитываю индекс исходного сигнала if(j<0) j =0; // если индекс отрицателььный то приравниваю его к 0 double x = (t1[i]-t0[j])*Fs0-2; // пересчитываю значение x y1[i] = farrow3(y0+j, x); // фильтр Фарроу t1[i] *= 1E3; // перевожу время результата ресэмплинга в мс } // перевожу исходное время в мс for(int i = 0; i<N; i++){ t0[i] *= 1E3; } // сохраняю результат в файлы saveToTXT(t0, y0, N, "исходный сигнал.txt"); saveToTXT(t1, y1, K, "resampling.txt"); system("Pause"); return 0; } все работает. у них там да. А вы задайте частоту дискретизации 6400 для синуса c частотой f0 = 45,35Гц. при выборке N = 1024 (такое соотношение частоты дискретизации и количества выборок дают верный спектр лишь при f0 = 50Гц, так как тогда в окне ровно 8 периодов), а мы же для f0 = 45,35Гц здесь видим нецелое число периодов в окне. затем попробуйте передискретизировать этот синус на на частоту 5804.8 (заметьте дробная частота получается как N/8*f0) и должны увидеть целое количесвто периодов в окне. Но в моих экспериментах с этим кодом получается ерунда при передискретизации. Ну бог с ним, с эти кодом С-шным. Хотябы в MATLAB бы увидеть положительный результат.
|
|
|
|
|
Feb 22 2010, 18:07
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 20-09-08
Пользователь №: 40 347

|
Цитата(TigerSHARC @ Feb 22 2010, 21:00)  Но в моих экспериментах с этим кодом получается ерунда при передискретизации. ставьте Код
double Fs0 = 6400; // исходная частота дискретизации double Fs1 = 5804.8; // частота дискретизации после ресэмплинга int K = 1024;// количество отсчетов после ресэмплинга int N = (int)K*Fs0/Fs1;// количество исходных отсчетов а также сигнал: Код
// формирую исходный сигнал for(int i = 0; i<N; i++){ t0[i] = double(i)/Fs0; y0[i] = cos(2*M_PI*45.35*t0[i]); // гармоническое колебание на частоте 3 кГц. } все замечательно работает. Количество входных отсчетов 1128 выходный 1024. На выходе ровно 8 периодов колебания
|
|
|
|
|
Feb 23 2010, 13:12
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(bahurin @ Feb 22 2010, 21:07)  ставьте Код
double Fs0 = 6400; // исходная частота дискретизации double Fs1 = 5804.8; // частота дискретизации после ресэмплинга int K = 1024;// количество отсчетов после ресэмплинга int N = (int)K*Fs0/Fs1;// количество исходных отсчетов а также сигнал: Код
// формирую исходный сигнал for(int i = 0; i<N; i++){ t0[i] = double(i)/Fs0; y0[i] = cos(2*M_PI*45.35*t0[i]); // гармоническое колебание на частоте 3 кГц. } все замечательно работает. Количество входных отсчетов 1128 выходный 1024. На выходе ровно 8 периодов колебания странно, когда я пробовал не выходило. после праздников просмотрю ещё раз. Наверно конкретно в моём коде косяк какойто... Скажите, а для повышения частоты дискретизации такой метод подойдёт? Скажем нужно 6400 пересчитать на 7360 гц. просто соответствующие значения вставить? Да и почему то исходное количесвто отсчётов разное всегда... наверно исходное число должно быть постоянным а выходное менятся в зависимости от соотношения F0/F1. Так? Да и скажите где вы этот код взяли. тот что у меня с того же сайта: int main() { int N = 64; // количество исходных отсчетов double Fs0 = 20E3; // исходная частота дискретизации double Fs1 = 15E3; // частота дискретизации после ресэмплинга int K = (int)(N*Fs1/Fs0); // количество отсчетов после ресэмплинга // выделяю память под исходный сигнал ....... вот тут как раз исходное количесвто отсчётов постоянно(как и должно быть), а на выходе меняется... странно
Сообщение отредактировал TigerSHARC - Feb 23 2010, 13:32
|
|
|
|
|
Feb 23 2010, 18:58
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(Andron_ @ Feb 23 2010, 21:49)  вы не можете его "поджать" под временное окно. Не, при желании, конечно, можно, но при этом спектр изменится. Сигнал можно только _обрезать_ под временное окно. О целом числе периодов сигнала на данном временном окне речи не идет. Можно подогнать сигнал определенной длительности под нужное число отсчетов изменением частоты дискретизации. Ну так я и хочу всего лишь навсего чтобы частота чигнала точно легла на бины Фурье. хочу добиться того, чтобы соотношение частоты дискретизации и длинны выборки - (т.е. частотное разрешение фурье), позволило увидеть спектр сигнала в виде одной палки, а не гребёнки от растекания. P.S. Окна не предлагать. Рочему? См. выше.
|
|
|
|
|
Feb 23 2010, 19:40
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(Andron_ @ Feb 23 2010, 22:15)  тью... "вон оно че, Михалыч"...
тогда, как я понимаю, 2 этапа. 1. выбрать длительность сигнала, на которую уложится целое число периодов сигнала. 2. выбрать новую частоту дискретизации таковой, чтобы на выбранное время приходилось 2^n отсчетов.
а, ну и третий - в матлабе применить resample на подсчитанную частоту дискретизации. resample не канает((( пример Fs = 6400; N = 128; Ts = 1/Fs; T = Ts*N; f = 45; t = 0:Ts:T-Ts; A = 10; df = Fs/N; f1 = 0:df:Fs-(Fs/N); Y = A*sin(2*pi*f*t)+ A*sin(2*pi*2*f*t)+ A*sin(2*pi*3*f*t); X = fft(Y)/length(t); Yr = resample(Y, 9,10); subplot(2,1,1), stem (t,Y), grid subplot(2,1,2), stem (t, Yr), grid Дело в том, что когда меняю частоту "руками": Fs = 5760; N = 128; Ts = 1/Fs; T = Ts*N; f = 45; t = 0:Ts:T-Ts; A = 10; df = Fs/N; f1 = 0:df:Fs-(Fs/N); Y = A*sin(2*pi*f*t)+ A*sin(2*pi*2*f*t)+ A*sin(2*pi*3*f*t); X = fft(Y)/length(t); >> stem(f1, abs(X)), grid получается красивый спектр, отражающий верную информацию об амплитудах сигнала. Пробовал для передискреизации функцию resample, но она выдаёт меньшее число отсчётов и спектр искажён... функцию resample, но она выдаёт меньшее число отсчётов и спектр искажён...
Сообщение отредактировал TigerSHARC - Feb 23 2010, 19:40
|
|
|
|
|
Feb 23 2010, 21:07
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 20-09-08
Пользователь №: 40 352

|
Здравствуйте! Может быть вот такой вариант Вас устроит: % variant % накапливаем сигнал на исходной частоте Fs = 6400; N = 143; Ts = 1/Fs; T = Ts*N; f = 45; t = 0:Ts:T-Ts; A = 10; df = Fs/N; f1 = 0:df:Fs-(Fs/N); Y = A*sin(2*pi*f*t)+ A*sin(2*pi*2*f*t)+ A*sin(2*pi*3*f*t); X = fft(Y)/length(t); % интерполяция и БПФ N2 = 128 Fs2 = 5760 Ts2 = 1/Fs2 ti = [0:Ts2:(N2-1)*Ts2] Yi = interp1(t,Y,ti,'spline');% интерполяция методом сплайнов, можно и другие методы, например, полиномиальную интерполяцию 2 и 3 порядка
figure plot(t,Y,'b- x'),grid on,hold on plot(ti,Yi,'r- o') Xi = fft(Yi)/length(ti); df2 = Fs2/N2; f2 = 0:df2:Fs2-(Fs2/N2); figure stem(f1, abs(X)), grid on,hold on figure stem(f2, abs(Xi),'g o'), grid
%>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Если вы хотите изменить частоту дискретизации с 6400 на 5760 так, чтобы на частоте 5760 у Вас оказалось 128 отсчетов, то для интерполяции с частоты 6400 вам понадобится кусок сигнала длительностью 128*6400/5760 ~= 143 отсчета. Взять 128 отсчетов на частоте 6400 и переделать их в 128 отсчетов на частоте 5760 невозможно, так как длительность вашего сигнала на частоте 6400 равна 128/6400 = 0.0200 сек, а длительность сигнала в 128 отсчетов на частоте 5760 равна 0.0222 секунды. Где взять недостающих отсчетов сигнала на 0.0022 секунды? 2 варианта: 1 - накопить на частоте 6400 (скрипт выше в этом посте). 2 - заниматься экстраполяцией, то есть пытаться продолжить сигнал в будущее на основе имеющихся отсчетов. Успех такой операции зависит от метода экстраполяции и самого экстраполируемого сигнала. Первый способ я думаю проще и надежнее.
Сообщение отредактировал leksa - Feb 23 2010, 21:09
--------------------
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away (Antoine de Saint-Exupery)
|
|
|
|
|
Feb 23 2010, 21:35
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 20-09-08
Пользователь №: 40 352

|
Цитата(TigerSHARC @ Feb 24 2010, 00:28)  на самом деле нужно просто передискретизировать сигнал так, чтобы частота дискретизации была кратна частоте синуса. И при этом частота точно ляжет на бины фурье. вот и всё. Я знаю, что для этих целей применяется фильтр Фарроу или полифазные КИХ фильтры (или просто фильтры дробной задержки). На С пробовал фильтр фарроу - результата нет. Спектр тот же примерно получается после передискретизации. А нужно так - получили синус число периодов которого не уместилось во временном окне, а спектр вместо одной палки на частоте синуса содержит гребёнку на всех частотах. Затем произвели передискретизацию. И вот число периодов целое во временном окне, а спектр уже одна палка на частоте синуса, а его амплитуда известна с какой-то малой погрешностью... Я понял что вы это хотите сделать. Приведенный мной выше код позволяет это сделать, с одним условием накапливать на более высокой частоте отсчетов нужно больше, чем их должно быть на низкой. Какой конкретно интерполятор использовать - не так важно, имхо. Но полифазные КИХ работают только если изменение частоты выражается соотношением целых чисел, 5760/6400=47/80 - несократимая дробь, имхо, при таком соотношении полифазная структура не очень эффективна, хотя точно сейчас не скажу.
--------------------
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away (Antoine de Saint-Exupery)
|
|
|
|
|
Feb 23 2010, 22:41
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 20-09-08
Пользователь №: 40 352

|
За код - пожалуйста, тем более это ваш код в общем то с небольшими изменениями. По полифазным КИХ я выше написал неверно - вполне их тоже в этой ситуации можно использовать. Извините, 5760/6400 = 9/10 конечно. В матлабе факторизовал, забил 3760 вместо 5760 - по ночам наверно лучше спать! )
вот вариант с полифазными КИХ % variant Fs = 6400; N = 142; Ts = 1/Fs; T = Ts*N; f = 45; t = 0:Ts:T-Ts; A = 10; df = Fs/N; f1 = 0:df:Fs-(Fs/N); Y = A*sin(2*pi*f*t)+ A*sin(2*pi*2*f*t)+ A*sin(2*pi*3*f*t); X = fft(Y)/length(t);
N2 = 128 Fs2 = 5760 Ts2 = 1/Fs2 ti = [0:Ts2:(N2-1)*Ts2] Yi = resample(Y,9,10);%interp1(t,Y,ti,'spline');
figure plot(t,Y,'b- x'),grid on,hold on plot(ti,Yi,'r- o') Xi = fft(Yi)/length(ti); df2 = Fs2/N2; f2 = 0:df2:Fs2-(Fs2/N2); figure stem(f1, abs(X)), grid on,hold on figure stem(f2, abs(Xi),'g o'), grid
Сообщение отредактировал leksa - Feb 23 2010, 22:53
--------------------
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away (Antoine de Saint-Exupery)
|
|
|
|
|
Feb 24 2010, 02:14
|
.NET developer
  
Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532

|
Цитата resample не канает(((
пример
Fs = 6400; N = 128; ... вы иногда думайте над тем, что вам советуют. КАК вы собрались из 128-ми отсчетов исходного сигнала на более высокой частоте дискретизации получить столько же, но на более низкой? Законы мироздания таковы, что это слабо выполнимая задача. Считайте. 128 отсчетов. частота дискретизации 5760. Длительность сигнала 128/5760 = 0,022(2) Число отсчетов, необходимое для такой длительности сигнала при частоте дискретизации 6400: 6400 * 0,022 = 142,22(2) ~ 143 отсчета. Соответственно и в коде своем пишите: Цитата Fs = 6400; N = 143; %!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 Ts = 1/Fs; T = Ts*N; f = 45; t = 0:Ts:T-Ts; A = 10; df = Fs/N; f1 = 0:df:Fs-(Fs/N); Y = A*sin(2*pi*f*t)+ A*sin(2*pi*2*f*t)+ A*sin(2*pi*3*f*t); X = fft(Y)/length(t); Yr = resample(Y, 9,10); subplot(2,1,1), stem (t,Y), grid subplot(2,1,2), stem (t, Yr), grid
|
|
|
|
|
Feb 24 2010, 14:09
|
Частый гость
 
Группа: Участник
Сообщений: 161
Регистрация: 22-06-09
Из: Москва
Пользователь №: 50 531

|
Реализуется с помощью фарроу-фильтра.
[/quote] А сколько гармоник надо? И какая точность? Если всего 3, тогда DFT любой FFT обгонит в несколько раз даже без Фарроу. И в несколько раз по точности. И никакого ресемплинга не требуется. А если много и уровни маленькие, тогда Фарроу там такое наделает... Попробуйте подставить реальные уровни гармоник, погрешность у Фарроу может ползти от уровня основной гармоники. Я делал так: 1. Начало измерений от прохождения сигнала через 0. 2. Конец измерений до прохождения сигнала через 0 после требуемого числа периодов. 3. Произвести требуемые DFT на столько точек, сколько попадет в период измерения. Какое-нибудь окно, Ханна например, повысит точность. Измерять частоту не надо. Можно в реале через период, если проц быстрый. Попробуйте, гармоники должны быть реальные не более 5-10%. Интересно какой ГОСТ допускает ресэмплинг?
--------------------
Ты можешь знать все что угодно, но пока ты не доказал это на практике, ты не знаешь ничего!© Ричард Бах
|
|
|
|
|
Feb 24 2010, 15:07
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Да, то что у меня получилось выше просто вырезает период сигнала. Интрвал неопределённости в моём случае (если основная гармоник пляшет 42,5....57,5Гц) составит порядка 0,006 с. (разность периодов) Если применить окно ханна получается супер точно... но его прменять нельзя!!!!! Давайте расскажу всё как есть, дабы прояснить ситуацию. Создаётся алгоритм по ГОСТ МЭК 61000-4-7. Аппаратно частоту дискретизации менять нельзя. Ресемплинг применяется уже в разработанном устройстве вот ссылка: http://powerdsp.narod.ru/analizatorkachestva/measpar.pdf если не лень прочитайте. Там применяется большая частота дискретизации и выборка длиннее. Цитирую разработчика: "... количество отсчетов фурье фиксировано но на него приходится строго один период, интерполятор работает так что берет такое количество отсчетов что в них содержится ровно один период, независимо от частоты." Общался с разработчиком - для 6400Гц и 128 выборок ресемплинг тоже вполне уместен. Я пишу алгоритм на С. Получается тольуо "вырезать" сигнал как в коде выше...(((
Сообщение отредактировал TigerSHARC - Feb 24 2010, 15:13
|
|
|
|
|
Feb 24 2010, 15:36
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 20-09-08
Пользователь №: 40 352

|
Я прочитал документ по ссылке. Из того что вы писали все равно не ясно, чего вы хотите добиться. В приведенном вами документе сначала производится оценка частоты первой гармоники сигнала путем подсчета переходов через ноль фильтрованного режекторным фильтром сигнала. Затем используя эту оценку, интерполятор выдает отсчеты сигнала так, чтобы на размер ДПФ пришлось целое число периодов, тогда все гармоники тоже "лягут" целое число раз. Делайте также. Или что вас не устраивает?
--------------------
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away (Antoine de Saint-Exupery)
|
|
|
|
|
Feb 24 2010, 16:58
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(thermit @ Feb 24 2010, 19:40)  Дык, пауз во времени и не будет. Меняться будет число отсчетов в окне. уменя выходит, что например в исходном сигнале за периодом основной частоты наблюдается сильный всплеск. если в овно умещается ровно период и ещё кусок этого всплеска, то после интерполяции получаю просто период, а о всплеске за периодом информация теряется... И число отсчётов в окне изначально у меня фиксированно а после ресемплинга всегда равно 128 (но соответсвенно для разной частоты дискретизации).... Вобщем получается что после ресемплинга вырезаю просто период. Довольно трудно объяснить такие вещи, но думаю у меня получилось) расскажите в чём неправ...
|
|
|
|
|
Feb 24 2010, 20:25
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 20-09-08
Пользователь №: 40 352

|
TigerSHARC Извините, но мне все-таки не до конца ясны все условия вашей задачи, да и потом предлагать какие-то конкретные решения - их нужно проверять на практике применительно к вашей задаче, то есть сделать, а это время. Но все же, вот какие моменты мне до сих пор не ясны - 1) Какой интервал наблюдения, за который вы должны получить оценку уровня сигнала? 2) Требуется оценить уровень первой гармоники, или еще какие-то параметры? 3) Какой период обновления полученных оценок? То есть через какой интервал времени нужно обновлять полученные оценки? Если интервал наблюдения - это один период первой гармоники, то может быть делать так: Предположим на вход алгоритма поступают отсчеты с частотой дискретизации 6400 Гц. Алгоритм отслеживает переходы во входном сигнале через ноль, причем при переходе от отрицательного уровня к положительному, запускается накопление сигнала в некий буфер. При следующем переходе через ноль от отрицательного уровня к положительному, накопление в буфер заканчивается. На этот момент у вас в буфере 1 период синуса. По числу накопленных отсчетов можно оценить частоту первой гармоники, правда довольно грубо так как погрешность оценки периода у вас +/- 1 отсчет. Может быть, оценку можно улучшить, если момент перехода через ноль уточнять линейной интерполяцией. То есть у вас один отсчет был ниже нуля, следующий выше. Так как их уровни вам известны, то можно построить уравнение прямой линии через эти два отсчета и определить в какой момент линия пересекает нулевой уровень. Так нужно делать два раза в начале и конце периода. Потом период вычислите как разницу моментов перехода через ноль. Теперь период сигнала известен. Вычисляем массив времени t=0:T1/N:(T1/N)*(N-1), где T1 - оценка периода первой гармоники, а N - размерность ДПФ, 128 например. Используя этот массив времени и накопленный в буфере сигнал интерполятором получаем те N отсчетов одного периода, которые вам нужны для вычисления ДПФ, чтобы на интервал ДПФ попал точно 1 период. По уровню первой гармоники ДПФ получаем искомую оценку уровня сигнала с частотой первой гармоники. Сбрасываем содержание буфера и начинаем накопление заново, до нового перехода через ноль сигнала по направлению от отрицательных значений к положительным. В таком варианте, оценка будет обновляться периодически, но не через 128 отсчетов входного сигнала, а через 1 период первой гармоники. Будет гармоника 45 Гц - будет реже обновляться, 52 Гц -чаще. Данная схема чисто из головы, так что я не претендую на то что это наилучший способ. Чтобы такое в матлабе набросать требуется время, а его мало.
Да, и при высоком уровне помех/искажений, моменты перехода через ноль будут "дрожать" слишком сильно, то есть оценка периода будет не точной, тогда и оценка уровня первой гармоники будет искажена. Как быстро может меняться частота первой гармоники? Если скажем на доли Гц в минуту, то тогда может быть все-таки накапливать побольше периодов, по переходам через ноль определять частоту первой гармоники. Такая оценка будет менее подвержена влиянию дрожания переходов через ноль.
Сообщение отредактировал leksa - Feb 24 2010, 20:46
--------------------
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away (Antoine de Saint-Exupery)
|
|
|
|
|
Feb 25 2010, 10:53
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Всё теперь стало ясно. Объясняю суть проблемы. необходимо узнать все гармоники , которые можно полусчить с частотой дискретизации 6400. Гармоники кратны основной частоте (которая меняется от 42.5 до 57.5). Я подаю всего лишь три - такак это просто модель, что бы суть пока уловить. Дело вот в чём - раньше я полагал, что выборка должна быть фиксирована по количеству отсчётов (жестко 128 например). Теперь понятно что происходит так : 1) Получаем частоту (fосн.), по некоторому алгоритму (давайте договоримся что частота известна с абсолютной точностью, так как частотный алгоритм - это отдельный разговор). 2) затем интерполятор на основе данных о частоте забирает выборку АЦП из кольцевого буфера (о буфере ниже). Причём забирает столько выборок сколько ему надо (в зависимости от частоты сигнала) - если частота изменяется от 42.5 до 57.5, то кол выборок может быть от 111 до 150. 3) Затем интерполятор выдаёт ровно 128 выборок (всегда!) на новой частоте дискретизации равной 128*fосн. 4) по этим выборкам получаем спектр. _____________________________________
КОЛЬЦЕВОЙ БУФЕР
теперь главный вопрос:
Данные с АЦП поступают в кольцевой буфер. Буфер заполняется постоянно со скоростью, которая зависит от периода дискретизации (в моём случае 1/6400). Допустим частота сигнала найдена и равна 43Гц. Интерполятору требуется 148 выборок для данного временного окна и он забирает первые 148 выборок из буфера, 149 выборка уже является первой для следующего временного окна, потом частота изменилась и скажем равна 45 Гц, тогда интерполятор берёт по 142 выборки на временное окно и так далее... Кольцевой буфер должен быть такого размера что бы хранит предысторию сигнала за некоторое время и должен выдавать её при запросе. Буфер заполняется постоянно и циклически. так вот проблема в том что скорее всего буфер заполняется быстрее, чем выборки извлекаются из него. Получается что, какого бы размера не был буфер, рано или поздно вершина буфера настигнет его хвост(где храняться полезные данные)... как этого избежать при работе с кольцевым буфером.
|
|
|
|
|
Feb 25 2010, 11:52
|
.NET developer
  
Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532

|
Цитата Получается что, какого бы размера не был буфер, рано или поздно вершина буфера настигнет его хвост(где храняться полезные данные)...
как этого избежать при работе с кольцевым буфером. взять кольцевой буфер бесконечного размера, применив бесконечное число микросхем памяти.
|
|
|
|
|
Feb 25 2010, 12:09
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата TigerSHARC: уфер заполняется постоянно и циклически. так вот проблема в том что скорее всего буфер заполняется быстрее, чем выборки извлекаются из него. Получается что, какого бы размера не был буфер, рано или поздно вершина буфера настигнет его хвост(где храняться полезные данные)...
как этого избежать при работе с кольцевым буфером. Вопрос из области "как сделать так, чтоб 2*2 равнялось бы 5?" Ответ очевиден - никак. Чтобы буфер не переполнялся нужно забирать данные из него с той же средней скоростью, с которой они в буфер кладутся. Храните тада передискретизированные данные...
|
|
|
|
|
Feb 25 2010, 12:54
|
Знающий
   
Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195

|
Цитата(thermit @ Feb 25 2010, 15:47)  Если ориетироваться на число отсчетов связанное с частотой 1-й гармоники - то никаких проблем не будет. Советую почитать что-нибудь про системы автоматической подстройки частоты. Именно она у Вас и получается. Если бы можно было ФАПЧ использовать аппаратно... то проблем бы не было... А тут так альтернатива - программная подстройка... Короче надо как то проблему с циклическим буфером решить... и непонятно причем тут 1-я гармоника (выборка есть выборка) берём от 120 до 150 отсчётов в зависимости от обстоятельств(хоть там 50 гармоник). Может так: БПФ успевает выполниться, скажем к тому времени пришло 90 отсчётов след. окна. Тогда ждём пока не будет нужного количесвта выборок, которые "запрашивает" интерполятор. Выборка пришла - опять БПФ... итак по кругу... не выйдет так? Причём "окна " не должны перекрываться. Каждая выборка участвует в БПФ только со своей группой выборок (это так для справки)
Сообщение отредактировал TigerSHARC - Feb 25 2010, 12:55
|
|
|
|
|
Feb 25 2010, 12:59
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата Тогда ждём пока не будет нужного количесвта выборок, которые "запрашивает" интерполятор. Выборка пришла - опять БПФ... итак по кругу... не выйдет так? Выйдет.
|
|
|
|
|
Feb 26 2010, 15:37
|

Знающий
   
Группа: Свой
Сообщений: 597
Регистрация: 24-05-06
Из: г. Чебоксары
Пользователь №: 17 402

|
1. Время обработки всегда примерно одинаково, т.к. функции ресемплинга в любом случае надо сформировать 128 точек, выполнив 128*M математических операций (M - число математических операций на формирование одной выходной точки). 2. Время выполнения БПФ одинаково всегда 3. Если пропуски в наблюдении недопустимы, то суммарное время п.1 и п.2 не должно превышать время набора исходных данных для максимальной частоты основной гармоники, т.е. не должно быть больше, чем время набора 111 точек на частоте 6400 4. Если п.3 выполняется, то глубина буфера не должна быть меньше, чем число точек на минимальной частоте основной гармоники (150 точек) + число точек на максимальной частоте (111 точек), тогда пока выполняется обработка набранного окна, новые данные не затрут его.
--------------------
Почему разработчики систем повышенной надёжности плохо справляются с простыми проектами? :)
|
|
|
|
|
May 30 2013, 15:42
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
хоть тема и древняя, но нужная всегда. В аттаче пример на студии10 передескритизации WAV-файла на основе исходника от bahurin`а Когда наглядно, и можно по шагам пройтись по алгоритму, то будет проще понять.
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|