haker_fox 60 22 декабря, 2018 Опубликовано 22 декабря, 2018 · Жалоба Добрый день! тема моего вопроса стара как мир, но всё же... Есть АЦП, 24 разряда, которое с частотой 8 кГц оцифровывает переменный ток 50 Гц. Для вычисления RMS использую классическую формулу с квадратным корнем и интегралом. Для расчётов беру количество выборок, кратное одному периоду. И всё работает в пределах требуемой погрешности. Недавно выяснилось, что нужно алгоритм адаптировать для частот 48 - 62 Гц. Классика уже не работает, по-крайней мере с дискретными данными. Первое, что пришло на ум - взять БПФ, получить частоту и амплитуду первой гармоники, и её использовать. У меня Cortex-M4F, должен успевать. Данные (измеренную частоту, и RMS) нужно выдавать не чаще, чем каждые 0.5 с. Собственно мои вопросы: 1. Я прав, можно ли использовать БПФ? может быть есть подводные камни? 2. Имеется ли в природе другой алгоритм, более быстрый для данной задачи? Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Strong 1 22 декабря, 2018 Опубликовано 22 декабря, 2018 · Жалоба И в чем, интересно, разница между 48-50-62 Hz? Какая-то магия? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 22 декабря, 2018 Опубликовано 22 декабря, 2018 · Жалоба 22 minutes ago, Strong said: И в чем, интересно, разница между 48-50-62 Hz? Какая-то магия? Разное количество выборок за период. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Strong 1 22 декабря, 2018 Опубликовано 22 декабря, 2018 · Жалоба 27 минут назад, haker_fox сказал: Разное количество выборок за период. Какая разница в количестве выборок? 480-500-620? 48-50-62? Вы вопрос правильно сформулируйте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 22 декабря, 2018 Опубликовано 22 декабря, 2018 · Жалоба Я полагаю, у автора в коде количество выборок для интегрирования жестко забито #define-ом. А хочется автоматически знать, сколько выборок нужно для одного или N периодов. Для этого нужно уметь считать частоту. haker_fox, схему переделать немного нельзя? Достаточно входной сигнал было бы через делитель/развязку завести на вход захвата таймера и по переходу через 0 определять текущую частоту сети. Конечно, в сети возможны двойные переходы через 0, но это, ИМХО, легко определяется программно, нежели делать БПФ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 22 декабря, 2018 Опубликовано 22 декабря, 2018 · Жалоба 1 hour ago, Arlleex said: Для этого нужно уметь считать частоту Да, правильно! 1 hour ago, Arlleex said: схему переделать немного нельзя? Уже нет. В общем-то можно и программно посчитать период, а из него частоту. Как компаратором. Собственно говоря, потому-то вопрос об алгоритме и встал) Хочется без долгих поисков в сети найти ответ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 17 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба 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: Единственно, исходные данные надо нормировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба @iiv, спасибо вам! Изучаю алгоритм! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
stells 9 23 декабря, 2018 Опубликовано 23 декабря, 2018 (изменено) · Жалоба 21 час назад, haker_fox сказал: Есть АЦП, 24 разряда, которое с частотой 8 кГц оцифровывает переменный ток 50 Гц. Для вычисления RMS использую классическую формулу с квадратным корнем и интегралом. Для расчётов беру количество выборок, кратное одному периоду. И всё работает в пределах требуемой погрешности. Недавно выяснилось, что нужно алгоритм адаптировать для частот 48 - 62 Гц. период оцифровки 125мкс... если частоту нужно посчитать не с десятыми долями, то по количеству выборок между переходами через 0 вроде частота легко считается(а за несколько периодов можно и десятые доли посчитать)... для устранения двойных переходов через 0 делаем простейшее интегрирование, например скользящее среднее Изменено 23 декабря, 2018 пользователем stells Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба С Фурье возможно будет ровно та же проблема из-за некратности длины выборки целому количеству периодов, То есть вместо окна можно конечно его два раза посчитать, первый раз для нахождения максимума и определения частоты, потом отрезать нужное количество данных для ровного количества периодов и опять для аккуратной амплитуды. Это если периодов совсем мало (один), если много - оконная функция возможно справится и так. Возможно лучше будет считать Герцелем для разных частот, используя соответствующее (целому количеству периодов) количество отсчётов для каждой частоты, десяток отдельных частот посчитать будет быстрее всего спектра через БПФ. Хотя нет, отставить Герцеля, вам же RMS нужен, а не амплитуда основной гармоники. А для RMS весь спектр нужен. Ну и можно вообще без буфера на лету считать RMS (суммировать выборки и квадраты выборок), и заодно на лету же оценивать частоту, считая точно таким же образом RMS от производной сигнала . Отношение RMS производной и RMS сигнала даст частоту. И тогда надо просто вовремя остановиться когда количество накопленных отсчётов попадёт в целое количество периодов сигнала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба 2 hours ago, stells said: для устранения двойных переходов через 0 делаем простейшее интегрирование, например скользящее среднее Я ещё почитал, что можно добавить гистерезис. 1 hour ago, _pv said: вам же RMS нужен, а не амплитуда основной гармоники. Ну вообще этого должно быть как раз достаточно, ведь у нас частота основной гармоники одна (например, либо 48, либо 57 Гц). Т.е. нет задачи считать для проивольной формы тока. Там всегда синус и один (ну я знаю, что в сети есть всякая гадость). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 17 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба 3 hours ago, _pv said: Отношение RMS производной и RMS сигнала даст частоту. так верно, то что я выше привел как раз и использует этот факт - просто и элегантно. Если по L2 норме остальные гармоники в этом окне меньше основной хотя бы в два раза, то частота будет вычисляться очень точно. Просто попробуйте на реальных данных и радуйтесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
petrov 6 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба haker_fox Частоту нет нужды считать, нужно получить комплексный сигнал с помощью преобразователя Гильберта или квадратурного демодулятора или комплексного фльтра полосового и найти его модуль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба 11 hours ago, iiv said: EDIT: Единственно, исходные данные надо нормировать. Простите, не совсем понимаю. Буду признателен за объяснение более подробно. 11 hours ago, iiv said: ИМХО, лучше без цифрового компаратора. Можно узнать, почему? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость ffilin 23 декабря, 2018 Опубликовано 23 декабря, 2018 · Жалоба haker_fox БПФ тебе не даст высокой точности определения частоты. Есть другой алгоритм определения периода, не использующий операций умножения. Смысл алгоритма в том что ты в определённом диапазоне периодов считаешь сумму дельт всех значений выборки. Минимальная сумма и будет соответствовать искомому периоду. У алгоритма есть ограничение, появление дополнительных минимумов на кратных частотах. но утилитарно, для промежутка частот 48...62Гц подойдёт. . PS Не могу вспомнить кто из великих этот алгоритм первым придумал, помню на уроках математического моделирования использовали. Хотя может мне всё приснилось. Сейчас не могу вспомнить как квант магнитного поля назывался, даже название книжки в которой об этом прочитал. Склероз проклятущий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться