Перейти к содержанию

    

Коллеги, что порекомендуете для вычисления RMS по выборкам?

Добрый день! тема моего вопроса стара как мир, но всё же... Есть АЦП, 24 разряда, которое с частотой 8 кГц оцифровывает переменный ток 50 Гц. Для вычисления RMS использую классическую формулу с квадратным корнем и интегралом. Для расчётов беру количество выборок, кратное одному периоду. И всё работает в пределах требуемой погрешности. Недавно выяснилось, что нужно алгоритм адаптировать для частот 48 - 62 Гц. Классика уже не работает, по-крайней мере с дискретными данными. Первое, что пришло на ум - взять БПФ, получить частоту и амплитуду первой гармоники, и её использовать. У меня Cortex-M4F, должен успевать. Данные (измеренную частоту, и RMS) нужно выдавать не чаще, чем каждые 0.5 с. Собственно мои вопросы:

1. Я прав, можно ли использовать БПФ? может быть есть подводные камни?

2. Имеется ли в природе другой алгоритм, более быстрый для данной задачи?

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И в чем, интересно, разница между 48-50-62 Hz?

Какая-то магия?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
22 minutes ago, Strong said:

И в чем, интересно, разница между 48-50-62 Hz?

Какая-то магия?

Разное количество выборок за период.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
27 минут назад, haker_fox сказал:

Разное количество выборок за период.

Какая разница в количестве выборок? 480-500-620? 48-50-62?

Вы вопрос правильно сформулируйте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я полагаю, у автора в коде количество выборок для интегрирования жестко забито #define-ом. А хочется автоматически знать, сколько выборок нужно для одного или N периодов. Для этого нужно уметь считать частоту.

haker_fox, схему переделать немного нельзя? Достаточно входной сигнал было бы через делитель/развязку завести на вход захвата таймера и по переходу через 0 определять текущую частоту сети. Конечно, в сети возможны двойные переходы через 0, но это, ИМХО, легко определяется программно, нежели делать БПФ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
1 hour ago, Arlleex said:

Для этого нужно уметь считать частоту

Да, правильно!

1 hour ago, Arlleex said:

схему переделать немного нельзя?

Уже нет.

В общем-то можно и программно посчитать период, а из него частоту. Как компаратором. Собственно говоря, потому-то вопрос об алгоритме и встал)

Хочется без долгих поисков в сети найти ответ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
20 hours ago, haker_fox said:

В общем-то можно и программно посчитать период, а из него частоту. Как компаратором. Собственно говоря, потому-то вопрос об алгоритме и встал)

Хочется без долгих поисков в сети найти ответ.

ИМХО, лучше без цифрового компаратора.

 

Если Вы можете сохранить примерно на период числа в кольцевом буфере и для этого у Вас хватит памяти контроллера, я бы сделал так:

пусть A[0]=0,...,N-1 - сохраненные данные, Вы ищете длину периода M, причем M<N.

Надо посчитать

   int i, j;
   double t1, t2, t3, D;

   for(t1=t2=0, i=0; i<N-1; i++)
   { t1+=A[i]*A[i];
     t2+=A[i]*A[i+1];
   }

   D = t2*t2 - (t1*2.+A[N-1]*A[N-1]-A[0]*A[0]-(double)(N-1))*(double)(N-1);
   t3=(t2+sqrt(D))/(double)(N-1);
   printf("M=%lg\n", 2.*M_PI/acos(t3));

При желании все или почти все можно считать в целочисленной арифметике, а арксинус - кордиком, или таки в лоб через плавающую арифметику.

В общем алгоритм будет работать и при M слегка больше N, но лучше не злоупотреблять.

Если у Вас нет памяти на N чисел (не верю, что в Ваш кортекс не полезет 128 чисел), можно и тут исхитриться, например, предположив, что длина периода не меняется очень быстро, и на первые N чисел вы считаете период, а его длину используете с N+1 шага, одновременно набирая данные о том как во втором периоде поплыла частота. ИМХО, с сетевым это должно работать.

 

EDIT: Единственно, исходные данные надо нормировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
21 час назад, haker_fox сказал:

Есть АЦП, 24 разряда, которое с частотой 8 кГц оцифровывает переменный ток 50 Гц. Для вычисления RMS использую классическую формулу с квадратным корнем и интегралом. Для расчётов беру количество выборок, кратное одному периоду. И всё работает в пределах требуемой погрешности. Недавно выяснилось, что нужно алгоритм адаптировать для частот 48 - 62 Гц.

период оцифровки 125мкс... если частоту нужно посчитать не с десятыми долями, то по количеству выборок между переходами через 0 вроде частота легко считается(а за несколько периодов можно и десятые доли посчитать)... для устранения двойных переходов через 0 делаем простейшее интегрирование, например скользящее среднее

Изменено пользователем stells

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С Фурье возможно будет ровно та же проблема из-за некратности длины выборки целому количеству периодов,

То есть вместо окна можно конечно его два раза посчитать, первый раз для нахождения максимума и определения частоты, потом отрезать нужное количество данных для ровного количества периодов и опять для аккуратной амплитуды. Это если периодов совсем мало (один), если много - оконная функция возможно справится и так.

Возможно лучше будет считать Герцелем для разных частот, используя соответствующее (целому количеству периодов) количество отсчётов для каждой частоты, десяток отдельных частот посчитать будет быстрее всего спектра через БПФ. Хотя нет, отставить Герцеля, вам же RMS нужен, а не амплитуда основной гармоники. А для RMS весь спектр нужен.

Ну и можно вообще без буфера на лету считать RMS (суммировать выборки и квадраты выборок), и заодно на лету же оценивать частоту, считая точно таким же образом RMS от производной сигнала . Отношение RMS производной и RMS сигнала даст частоту. И тогда надо просто вовремя остановиться когда количество накопленных отсчётов попадёт в целое количество периодов сигнала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
2 hours ago, stells said:

для устранения двойных переходов через 0 делаем простейшее интегрирование, например скользящее среднее

Я ещё почитал, что можно добавить гистерезис.

1 hour ago, _pv said:

вам же RMS нужен, а не амплитуда основной гармоники.

Ну вообще этого должно быть как раз достаточно, ведь у нас частота основной гармоники одна (например, либо 48, либо 57 Гц). Т.е. нет задачи считать для проивольной формы тока. Там всегда синус и один (ну я знаю, что в сети есть всякая гадость).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
3 hours ago, _pv said:

Отношение RMS производной и RMS сигнала даст частоту.

так верно, то что я выше привел как раз и использует этот факт - просто и элегантно. Если по L2 норме остальные гармоники в этом окне меньше основной хотя бы в два раза, то частота будет вычисляться очень точно. Просто попробуйте на реальных данных и радуйтесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

haker_fox

Частоту нет нужды считать, нужно получить комплексный сигнал с помощью преобразователя Гильберта или квадратурного демодулятора или комплексного фльтра полосового и найти его модуль.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
11 hours ago, iiv said:

EDIT: Единственно, исходные данные надо нормировать.

Простите, не совсем понимаю. Буду признателен за объяснение более подробно.

11 hours ago, iiv said:

ИМХО, лучше без цифрового компаратора.

Можно узнать, почему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

haker_fox

БПФ тебе не даст высокой точности определения частоты. 

Есть другой алгоритм определения периода, не использующий операций умножения. 

Смысл алгоритма в том что ты в определённом диапазоне периодов считаешь сумму  дельт всех значений выборки. Минимальная сумма и будет соответствовать искомому периоду. 

У алгоритма есть ограничение, появление дополнительных минимумов на кратных частотах.

но утилитарно, для промежутка частот 48...62Гц подойдёт.

.

PS

Не могу вспомнить кто из великих этот алгоритм первым придумал, помню на уроках математического моделирования использовали. Хотя может мне всё приснилось. Сейчас не могу вспомнить как квант магнитного поля назывался, даже название книжки в которой об этом прочитал. Склероз проклятущий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти