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

Замер амплитуды у синуса

6 minutes ago, jcxz said:

С АЦП только так и можно сделать. А как ещё?

Соорудить аналоговый пиковый детектор и считать показания. Или считать несколько точек синусы и далее по формулам. И да, можно просто считывать на большой скорости весь сигнал синуса и оттуда получать максимальное значение. Вот и надо бы понять, по какому пути идти, какой лучше подходит под требования и т.д.

6 minutes ago, jcxz said:

А у XMC4xxx частота преобразования в ~4 раза выше, и почему-то говорите что её не хватит.

У меня просто есть сомнения, что можно получить повторяемые цифры для фиксированной амплитуды сигнала. Например, запустили АЦП у XMC4xxx на некоторое время с получением максимального числа. Получили это число. Пусть оно будет 2304. Затем, ничего не меняя, снова запустили АЦП. И уже получили 2307 просто потому что АЦП не попал в ту же фазу, что делал на предыдущем замере. Это уже выходит за рамки допустимого. Если этого не будет, то остаётся проблема добывания XMC4xxx по доступной цене - бюджет, можно считать, ограничен 500 рублями. Если и это не проблема, то всё ок.

14 minutes ago, jcxz said:

Так важна точность или нет?

Да, я плохо написал пункт про точность. Лучше бы я его не писал вовсе :) Сейчас поправлю пункт. Важна повторяемость результатов при одной и той же амплитуде.

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


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

41 минуту назад, DisplayName сказал:

Пусть оно будет 2304. Затем, ничего не меняя, снова запустили АЦП. И уже получили 2307 просто потому что АЦП не попал в ту же фазу, что делал на предыдущем замере.

Можно добавить псевдослучайный джиттер в сигнал запуска АЦП и на большой выборке получить множество замеров с разными фазами - таким образом получить повторяемость.

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


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

1 hour ago, jcxz said:

Если точности получаемой от 4MS/s АЦП мало, можно найти более шустрые АЦП. Тот же LPC4370 с 80 MS/s. Только там экстремумы придётся искать программо.

если тупо брать максимум без интерполяции, то даже 80Мспс не сильно помогут, log2(1-cos(2*Pi*500e3/80e6)) это всего около 10 разрядов а ТС хочет 12.

за 100мкс оно конечно усреднится как-то, но ведь это для идеального АЦП, просто ошибка из-за того что реальный максимум может между двумя отсчётами АЦП попасть, а если ещё и реальный ENOB встроенных АЦП добавить получится грустно.

 

раз частота известна, считайте Герцеля.

только если фаза какая попало окнонную функцию какую-нибудь ещё добавить надо.

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


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

Если известна частота синуса, то целесообразно применить CORDIC (алгоритм Волдера или алгоритм Меджита). Для этого нужно произвести два измерения со сдвигом в 90 или 270 градусов по известной частоте. Одновременно с вычислением амплитуды здесь же вычисляется и фаза.

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


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

3 hours ago, _pv said:

раз частота известна, считайте Герцеля.

только если фаза какая попало окнонную функцию какую-нибудь ещё добавить надо.

Нашлась реализация на питоне. Но из-за какой попало фазы невозможно оценить насколько хорошо оно подходит. Да, что-то считает. Да, когда плюс-минус считывается одинаковый сигнал, то и значения амплитуды получаются близкими, но недостаточно.

Для таких исследований, похоже, надо сначала сделать аппаратную синхронизацию АЦП и сигнала.

2 hours ago, Serhiy_UA said:

Если известна частота синуса, то целесообразно применить CORDIC (алгоритм Волдера или алгоритм Меджита). Для этого нужно произвести два измерения со сдвигом в 90 или 270 градусов по известной частоте. Одновременно с вычислением амплитуды здесь же вычисляется и фаза.

Хм, интересно, да. На словах выглядит просто :)

Интересно, что даже есть STM32G4 с CORDIC accelerator.

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


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

1 hour ago, DisplayName said:

Для таких исследований, похоже, надо сначала сделать аппаратную синхронизацию АЦП и сигнала.

не надо,

вот 10 синусов из 100 точек (мкс)  со случайной фазой и частотой от 50 до 200(кГц), амплитуда посчитанная через среднеквадратичное отклонение (*1.41) без окна даёт разброс 0.004,

а с косинусным окном - уже 1ppm.

 

 

stdev.png

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


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

2 hours ago, _pv said:

не надо,

вот 10 синусов из 100 точек (мкс)  со случайной фазой и частотой от 50 до 200(кГц), амплитуда посчитанная через среднеквадратичное отклонение (*1.41) без окна даёт разброс 0.004,

а с косинусным окном - уже 1ppm.

 

 

stdev.png

Воспроизвёл это на питоне:

window = 0.5 * (1 - np.cos(2 * np.pi * np.arange(0, 100) / 100))

for i in range(0, 10):
    A = 2048 * np.random.rand(1)
    phi = 2 * (np.random.rand(1) - 0.5) * np.pi
    noise = (np.random.rand(1) - 0.5) * 0
    f = (A + noise) * np.sin(2 * np.pi * 0.05 * np.arange(0, 100) + phi)
    res = 2 * np.pi / np.e * np.std(window * f)
    res2 = np.sqrt(2) * np.std(f)
    print(A, res, res2, res - A, res2 - A)

Для амплитуды 1 для косинусного окна (res) получились схожие результаты. А вот без окна (res2) у меня наоборот - наилучший результат, почти идеально точное (ну прямо совсем реально почти идеальное, лучше чем с косинусным окном) попадание в исходную амплитуду. Не понимаю, в чём разница между wolfram'ом и питоном.

Если начать подавать амплитуду как будто бы с 12-ти битного АЦП для центрированного сигнала, тогда с косинусным окном разность с эталонным ответом достигает 1.8, в то время как без косинусного окна снова почти идеальное попадание в ответ.

А вот если включить шум на амплитуду (+- 2), а ещё если амплитуду сделать типом int, то оба метода уже достаточно сильно начинают отклоняться от эталонного результата - на 2 или даже на 3. Ну, наверное, ничего удивительного, ведь при расчётах никакого знания про синусоподобный сигнал вообще нет.

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

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


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

А, так я неправильно шумы подаю...

Ну вот, если начать правильно генерировать шумы:

-    noise = (np.random.rand(1) - 0.5) * 0
+    noise = (np.random.rand(100) - 0.5) * 0

Тогда случай "без окна" даёт лучше результат, чем с косинусным окном. Косинусное, например, окно даёт отклонение в 1.49, в то время как без окна отклонение всего 0.31.

 

PS. Конечно, * 0 в шумах надо убрать, если надо генерировать шум.

14 minutes ago, DisplayName said:

Тогда случай "без окна" даёт лучше результат, чем с косинусным окном. Косинусное, например, окно даёт отклонение в 1.49, в то время как без окна отклонение всего 0.31.

Хотя бывает и в обратную сторону, когда косинусное окно даёт результат лучше, чем без окна.

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

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


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

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

Вариант с косинусным окном, бывает, даёт отклонение аж в 2. В то время как вариант без окна не даёт отклонения > 1. Герцель по результатам, в целом, схож с вариантом без окна (хоть иногда и даёт на порядок лучше результат, но иногда и несколько хуже).

Так что для решения изначальной задачи можно попроовать обойтись вычислением среднеквадратичного отклонения.

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


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

12 часов назад, DisplayName сказал:

Важна повторяемость результатов при одной и той же амплитуде

Тогда стробированный пиковый детектор, в дополнение к вышеописанному,— по компаратору нуля, в начале отрицательного полупериода первый триггер фиксирует разрешающую "1" от МК, которая подаётся на аналоговый ключ, подключающий сигнал ко входу пикового детектора, а также на второй триггер, который фиксирует её в начале следующего отрицательного полупериода и сбрасывает первый триггер, после чего МК видит сработавший второй триггер, сбрасывает его и оцифровывает результат.

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


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

11 hours ago, DisplayName said:

Воспроизвёл это на питоне:


window = 0.5 * (1 - np.cos(2 * np.pi * np.arange(0, 100) / 100))

for i in range(0, 10):
    A = 2048 * np.random.rand(1)
    phi = 2 * (np.random.rand(1) - 0.5) * np.pi
    noise = (np.random.rand(1) - 0.5) * 0
    f = (A + noise) * np.sin(2 * np.pi * 0.05 * np.arange(0, 100) + phi)
    res = 2 * np.pi / np.e * np.std(window * f)
    res2 = np.sqrt(2) * np.std(f)
    print(A, res, res2, res - A, res2 - A)

Для амплитуды 1 для косинусного окна (res) получились схожие результаты. А вот без окна (res2) у меня наоборот - наилучший результат, почти идеально точное (ну прямо совсем реально почти идеальное, лучше чем с косинусным окном) попадание в исходную амплитуду. Не понимаю, в чём разница между wolfram'ом и питоном.

шумы надо добавлять к каждому отсчёту, а не множить целиком, A и так случайная.

что-то не так, разницы быть не должно,

для округлённой до целочисленной амплитуды от 0 до 2048 и без дополнительных шумов: без окна ошибка амплитуды ~5LSB c окном на порядок луше,

если добавить равномерный шум в 10LSB без окна почти те же 5LSB, с окном становится раза в два хуже, около 1LSB.

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


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

14 hours ago, Plain said:

Тогда стробированный пиковый детектор, в дополнение к вышеописанному,— по компаратору нуля, в начале отрицательного полупериода первый триггер фиксирует разрешающую "1" от МК, которая подаётся на аналоговый ключ, подключающий сигнал ко входу пикового детектора, а также на второй триггер, который фиксирует её в начале следующего отрицательного полупериода и сбрасывает первый триггер, после чего МК видит сработавший второй триггер, сбрасывает его и оцифровывает результат.

Если честно, то не очень понятно картину в целом с двумя триггерами. Разве не достаточно иметь компаратор, один D-триггер и МК (ну и аналоговый ключ)? Компаратор работает по пересечению условного нуля и задаёт клок D-триггеру. МК подключен к D входу триггера и задаёт значение для фиксации. Когда МК выставляет, например, 0, аналоговый ключ отключает сигнал от пикового детектора. Когда МК выставляет 1, сигнал подключается к пиковому детектору. Эти все переключения сигнала происходят по фазе сигнала.

9 hours ago, _pv said:

что-то не так, разницы быть не должно,

для округлённой до целочисленной амплитуды от 0 до 2048 и без дополнительных шумов: без окна ошибка амплитуды ~5LSB c окном на порядок луше,

если добавить равномерный шум в 10LSB без окна почти те же 5LSB, с окном становится раза в два хуже, около 1LSB.

Попробовал поиграть с окнами на ардуине с генератором сигналов. Да, без окна дела хуже обстоят, чем с окнами типа косинусного или окном Гаусса.

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


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

7 часов назад, DisplayName сказал:

Разве не достаточно ... один D-триггер

Для подлинно аппаратного решения — нет. Задвинуть абсолютно все другие задачи, чтобы стоять и ждать целый период произвольного сигнала? А если завтра заказчик захочет 1 Гц?

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


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

On 4/29/2021 at 10:13 PM, DisplayName said:

Хм, интересно, да. На словах выглядит просто :)

Интересно, что даже есть STM32G4 с CORDIC accelerator.

Алгоритм CORDIC точный и надежный, рекомендую. А акселераторы на STM32 это конечно сила, хотя и ПЛИС с этим хорошо справляется.  

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


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

Простейший и ненадежный алгоритм.
Если нет шума, то найти максимум и минимум. Вычесть из максимума мунимум и поделить на два.

Надежный алгоритм 1 
Посчитать дисперсию, которая равна RMS и умножить на корень из двух. Окно измерения должно помещать целое число периодов.

Надежный алгоритм 2
Получить из синуса косинус вычитанием последовательных значений. Там где косинус меняет знак будет максимум (или минимум) синуса. в одном случае с + на -, а в другом наоборот. Опять получите максимум и минимум. Вычтете и поделите на 2.

 

Надежный алгоритм 3
Если известна частота, то считаете за период корреляцию с синусом и косинусом. Арктангенс их отношения даст вам сдвиг фазы. Опять знаете где максимум и минимум и берете значения.

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...