Jamy, суть в том, что Ардуина 10 тыс. раз в секунду посредством своего АЦП снимает показания амплитуды I и Q.
Код: Выделить всё
I_input = (analogRead(A0) -1880 ) ; //Читаем I DC Ofset -1880
Q_input = (analogRead(A1) -1880 ) ; //Читаем Q DC ofcet -1880
Затем фильтрует их через простенький цифровой фильтр.
Код: Выделить всё
I_input_filter = (1-K)*I_input_filter + K*I_input; // фильтруем I
Q_input_filter = (1-K)*Q_input_filter + K*Q_input; // фильтруем Q
При амплитудной модуляции для получения мгновенной амплитуды исходного сигнала нужно извлечь корень из суммы квадратов I и Q :
Код: Выделить всё
DAC_output = (sqrt(sq(I_input_filter)+sq(Q_input_filter))); // АМ демодуляция
Тут всё просто и работает.
Для частотной модуляции всё сложнее. Нужно взять производную от арктангенса отношения I к Q.
У меня так:
Код: Выделить всё
NFM_temp = atan(Q_input_filter / I_input_filter); // Считает арктангенс
NFM_delta = NFM_temp - NFM_temp2 ; // Считаем производную
NFM_temp2 = NFM_temp; // Запоминаем предыдущее значение для следующего рассчета
DAC_output = NFM_delta * 100 ; // Умножаем на коэффициент
В итоге получается какая-то хрень на выходе. Беда ещё в том, что у меня нет стабильного источника NFM сигнала.
Я не знаю, сколько времени у Ардуины уходит на выполнение последнего кода. Может просто не успевает и её "выдёргивает" из этого кода прерывание по таймеру для считывания АЦП. Посчитал время выполнения Амплитудной и Частотной модуляции. С учётом записи и чтения ЦАП и АЦП 17 тыс. циклов в секунду. Хватает.
Информацию взял из
этой статьи.