Easyelectronics.ru

Электроника для всех
Текущее время: 22 апр 2019, 07:26

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
 Заголовок сообщения: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 03 июл 2015, 16:41 
Старожил

Зарегистрирован: 21 мар 2012, 14:33
Сообщения: 542
Беру сначала arm_cfft_q15(&arm_cfft_sR_q15_len1024, (q15_t *) lrBuffer, ifftFlag, doBitReverse);
комплексный спектр выглядит идеально, в сравнении с компьютерной реализацией на спектре различий очень мало.

Далее рассчитываю амплитудный спектр
arm_cmplx_mag_squared_q15((q15_t *) lrBuffer, (q15_t *)testOutput, fftSize);
на выходе не то что шума не видно. Одни нули и посреди одна палка! Как буд-то идёт сильная потеря точности, как если бы отбросили 8 младших бит. Но я помню на старинном 16-битном процессоре спектр выглядел и то лучше, с блочной запятой и задействованными только 13-битами.

Для перепроверки опять беру arm_cfft_q15(&arm_cfft_sR_q15_len1024, (q15_t *) lrBuffer, ifftFlag, doBitReverse);
и на компьютере считаю из её выхода амплитудный спектр - всё идеально, шумы от импульсного преобразователя питания на месте, и в окрестности пика от тестового сигнала 1кГц спектр приподнят. Значит arm_cfft_q15 работает корректно. А вот для arm_cmplx_mag_squared_q15 нужно писать замену?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 03 июл 2015, 19:42 
Старожил

Зарегистрирован: 31 янв 2013, 03:01
Сообщения: 219
почему бы не протрассировать arm_cmplx_mag_squared_q15, предварительно положив в буфер хардкордно забитые данные?
сорцы ведь доступны


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 04 июл 2015, 11:28 
Старожил

Зарегистрирован: 21 мар 2012, 14:33
Сообщения: 542
Вот где потеря точности:
*pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17);
Код:
 
q15_t real, imag;                              /* Temporary variables to store real and imaginary values */
  119
  120   while(numSamples > 0u)
  121   {
  122     /* out = ((real * real) + (imag * imag)) */
  123     real = *pSrc++;
  124     imag = *pSrc++;
  125     acc0 = (real * real);
  126     acc1 = (imag * imag);
  127     /* store the result in 3.13 format in the destination buffer. */
  128     *pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17);
  129
  130     /* Decrement the loop counter */
  131     numSamples--;
  132   }


допустим real=1, imag=1
acc0=1
acc1=1
1+1 =2
и теперь сдвиг числа 2 вправо на 17 бит... разумеется результатом будет 0
то есть мелкие числа попросту исчезают

Смотрю в обратном направлении. Чтобы на выходе появилась хотя бы единица должно быть:
1 << 17 = 131072
131072/2= 65536
sqrt(65536)=256

т.е. все числа <256 вообще исчезают. Из 15 бит 8 попросту выброшены.
Либо я что-то не понимаю, либо эта функция такая.

Кстати, что-то похожее здесь http://community.arm.com/thread/8059
Цитата:
Don't we loose about half of the precision by squaring and shifting the intermediate result by 33 bits?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 04 июл 2015, 14:07 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1578
Откуда: Киев
Цитата:
The function implements 1.15 by 1.15 multiplications and finally output is converted into 3.13 format.


поэтому real=1 - это даже не шум ))

PS. на всякий случай:

Цитата:
In the 1.15 format, there is one sign bit (the MSB) and fifteen fractional
bits representing values from -1 up to one LSB less than +1.

To convert a negative decimal number, say -0.242146, to 1.15 format:

Multiply the positive, ie. 0.242146 by 2^15 and convert to HEX, which gives
you 1EFE. Take the two's compliment of the number, which will give you
correct value in 1.15 format, i.e. 0xE101 in this example.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 20 авг 2015, 17:01 
Заглядывает иногда

Зарегистрирован: 18 апр 2010, 12:04
Сообщения: 32
tmtlib Столкнулся с такой же проблемой. Вам удалось как то её решить? Буду признателен, если подскажете правильно ли я все делаю.

1) Набираю 1024 точки с частой дискретизации 1024

Код:
static u32 dataIsReady = 0;
static q15_t input [2048];
static q15_t output [1024];


/**
* @brief Обработчик прерывания от таймера, тактирующего измерения
*
* @return
*/
extern "C" void timerInterrupt (void)
{
   input[curInputCursor++]=uhADCxConvertedValue; /**< Действительная часть - это мои текущие показания АЦП */
   input[curInputCursor++] = 0; /**< Мнимую часть прирваниваю к нулю */
   if (curInputCursor>=1024)
   {
      curInputCursor = 0;
      dataIsReady = 1;
      HAL_TIM_Base_DeInit(&htim1);
   }
   invertLed();
}


2) Далее, как только они набрались отправлю эти точки в arm_cfft_q15() и следом arm_cmplx_mag_q15(), чтобы получить амплитуды:
Код:

static void runFft (TimerFrequencyType frequency, const char *fileName)
{
   timInit(frequency);
   while (dataIsReady == 0) taskYIELD();
   dataIsReady = 0;
   arm_cfft_q15(&arm_cfft_sR_q15_len1024, input, 0, 1);
   arm_cmplx_mag_q15 (input, output, 1024);
   saveFft(frequency, fileName);

}

Кстати, что вообще означает параметр arm_cfft_sR_q15_len1024? Что означает параметр bitReverseFlag и чему его нужно прирвнивать (у меня он в 1)?

В output[] я ожидаю частотную характеристку с шаго 1 Гц. А получаю одну палку в output[1], все остальное нули.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 21 авг 2015, 11:21 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1578
Откуда: Киев
yanvasilij писал(а):
tmtlib Столкнулся с такой же проблемой. Вам удалось как то её решить? Буду признателен, если подскажете правильно ли я все делаю.
...
В output[] я ожидаю частотную характеристку с шаго 1 Гц. А получаю одну палку в output[1], все остальное нули.


uhADCxConvertedValue - какой диапазон значений?
и правильно понимаешь модификатор q15?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 24 авг 2015, 09:11 
Заглядывает иногда

Зарегистрирован: 18 апр 2010, 12:04
Сообщения: 32
Steel.ne писал(а):
yanvasilij писал(а):
tmtlib Столкнулся с такой же проблемой. Вам удалось как то её решить? Буду признателен, если подскажете правильно ли я все делаю.
...
В output[] я ожидаю частотную характеристку с шаго 1 Гц. А получаю одну палку в output[1], все остальное нули.


uhADCxConvertedValue - какой диапазон значений?
и правильно понимаешь модификатор q15?


uhADCxConvertedValue 12 бит (0-4095). q15 это просто int16_t или тут есть ньюансы?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 24 авг 2015, 12:59 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1578
Откуда: Киев
yanvasilij писал(а):
Steel.ne писал(а):
yanvasilij писал(а):
tmtlib Столкнулся с такой же проблемой. Вам удалось как то её решить? Буду признателен, если подскажете правильно ли я все делаю.
...
В output[] я ожидаю частотную характеристку с шаго 1 Гц. А получаю одну палку в output[1], все остальное нули.


uhADCxConvertedValue - какой диапазон значений?
и правильно понимаешь модификатор q15?


uhADCxConvertedValue 12 бит (0-4095). q15 это просто int16_t или тут есть ньюансы?


это фиксированная точка 15 бит. Поэтому входящие значения надо приводить к диапазону -1..1. И выходящие значения трактовать также


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 24 авг 2015, 13:25 
Заглядывает иногда

Зарегистрирован: 18 апр 2010, 12:04
Сообщения: 32
Steel.ne писал(а):
это фиксированная точка 15 бит. Поэтому входящие значения надо приводить к диапазону -1..1. И выходящие значения трактовать также



Можно Вас попросить на примере показать, как это делается? Например пришло мне с АЦП значение 0xAA, то в каком виде его ложить в массив input[], и как преобразовавывать данные из массива output[], чтобы получить амплитуды гармоник?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 24 авг 2015, 20:15 
Старожил

Зарегистрирован: 31 янв 2013, 03:01
Сообщения: 219
yanvasilij писал(а):
Например пришло мне с АЦП значение 0xAA, то в каком виде его ложить в массив input[]

повбивайте константы и поглядите в отладчике что выдает arm_float_to_q15
есть и обратная arm_q15_to_float


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 08 сен 2015, 13:28 
Старожил

Зарегистрирован: 21 мар 2012, 14:33
Сообщения: 542
Нужно понять, сколько максимально бит может быть задействовано на выходе комплексного спектра при подаче на вход сигнала синала с максимально задействованными 12 битами. По задумке там на входе максимум 16бит, а у нас только 12 бит с АЦП. Тогда можно будет понять сколько бит будет задействованно после умножения /* out = ((real * real) + (imag * imag)) */
Там задумано, что real*real = 16 бит * 16 бит = 32 бит, потом сдвиг вправо на 17 бит.
Можно заменить на что-то вроде 12 бит * 12 бит = 24 бит, и тогда сдвиг впарвао на 8 или 9 бит, не уверен. Либо можно вход сдвинуть влево. Либо натравить arm_q31_to_float на результат умножения, но это будет медленно, и далнейшие действия тоже тормозные.

arm_cfft_sR_q15_len1024 это длина исходных данных,
параметр bitReverseFlag оставляйте =1, тогда вывод будет в нормальном виде. Бит реверсинг это часть реализации БПФ на микропроцессорах, позволяет быстро получать правильные индексы для бабочек.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 09 сен 2015, 09:04 
Старожил

Зарегистрирован: 21 мар 2012, 14:33
Сообщения: 542
Ещё раз сравнил выход FFT с простой реализацией на компьютере. Судя по всему выход arm_cmplx_mag_q15 нормализуется делением на количество точек в преобразовании. В данном случае на 1024. При подаче на вход 12-битной синусоиды, на выходе наблюдаю амплитуду максимум 12 бит. Т.е то же самое, что в компьютерном варианте / 1024.

Для анализа фазы задействовал следующую вещь:
Код:
#define MULTIPLY_FP_RESOLUTION_BITS   15

int16_t atan2_fp(int16_t y_fp, int16_t x_fp)
{
   int32_t coeff_1 = 45;
   int32_t coeff_1b = -56;   // 56.24;
   int32_t coeff_1c = 11;   // 11.25
   int16_t coeff_2 = 135;

   int16_t angle = 0;

   int32_t r;
   int32_t r3;

   int16_t y_abs_fp = y_fp;
   if (y_abs_fp < 0)
      y_abs_fp = -y_abs_fp;

   if (y_fp == 0)
   {
      if (x_fp >= 0)
      {
         angle = 0;
      }
      else
      {
         angle = 180;
      }
   }
   else if (x_fp >= 0)
   {
      r = (((int32_t)(x_fp - y_abs_fp)) << MULTIPLY_FP_RESOLUTION_BITS) /
((int32_t)(x_fp + y_abs_fp));

      r3 = r * r;
      r3 =  r3 >> MULTIPLY_FP_RESOLUTION_BITS;
      r3 *= r;
      r3 =  r3 >> MULTIPLY_FP_RESOLUTION_BITS;
      r3 *= coeff_1c;
      angle = (int16_t) (     coeff_1 + ((coeff_1b * r + r3) >>
MULTIPLY_FP_RESOLUTION_BITS)   );
   }
   else
   {
      r = (((int32_t)(x_fp + y_abs_fp)) << MULTIPLY_FP_RESOLUTION_BITS) /
((int32_t)(y_abs_fp - x_fp));
      r3 = r * r;
      r3 =  r3 >> MULTIPLY_FP_RESOLUTION_BITS;
      r3 *= r;
      r3 =  r3 >> MULTIPLY_FP_RESOLUTION_BITS;
      r3 *= coeff_1c;
      angle = coeff_2 + ((int16_t)   (((coeff_1b * r + r3) >>
MULTIPLY_FP_RESOLUTION_BITS))   );
   }

   if (y_fp < 0)
      return (-angle);     // negate if in quad III or IV
   else
      return (angle);
}

взял отсюда http://www.dsprelated.com/showthread/co ... 8979-1.php
работает очень быстро (stm32f103), выдаёт угол фазы в градусах с учётом квадрантов (т.е. полный диапазон, а не простой arctan 0..90deg).
Единственная медленная часть - это квадратный корень для подсчёта финальной амплитуды. Пока что не нашёл удовлетворительного по скорости решения.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FFT:Что же это за точность такая низкая у arm_cmplx_mag_q15?
СообщениеДобавлено: 05 окт 2015, 12:59 
Старожил

Зарегистрирован: 21 мар 2012, 14:33
Сообщения: 542
А где реализована эта нормализация? Это деление на 1024 (в случае 1024-точечного преобразования). Или это зашито в бабочки, чтобы не было переполнения? Максимальную целочисленную точность можно получить убрав нормализацию и прочие сдвиги. Либо нужно входные данные сдвигать вправо, но там максимум 16 бит.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB