Оцифровка сигнала [под управлением atmega]

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Оцифровка сигнала [под управлением atmega]

Сообщение zi4rox »

ATMega16 управляет внешним АЦП TLV1570 по встроенному SPI и пытаемся оцифровать гармонический сигнал с частотами до 20кгц.

Немного о [url="http://focus.ti.com/lit/ds/symlink/tlv1570.pdf"]TLV1570[/url] - 8ми канальный 10ти разрядный последовательный АЦП 1.25MSPS. Входные напряжения: 0 .. 5В

По теореме Котельникова, частота дискретизации: Fдиcкр > 2Fmax
В моём случае 2Fmax = 40кГц, а частота дискретизации АЦП по даташиту считается так: Fдискр = 1/16*Fsclk (на каждую выборку нужно передать 2 байта) (в обвязке к ATMega стоит резонатор на 16МГц, при настройках SPI получил: Fsclk = 4Mhz ) => Fдиск = 1\16*4Mhz = 250кГц

Т.е. мы укладываемся с головой. Частота дискретизации 250 кГц, а сигнал 20кГц

Код прошивки такой:

Код: Выделить всё

while (1) {     
for (i=0;i<100;i++) {     
ADC_CS = 0;
adc_result_hi[i] = spi(0x00);
adc_result_low[i] = spi(0x60);   
ADC_CS = 1;       
}               

for (i=0;i<100;i++){
putchar(adc_result_hi[i]);       
putchar(adc_result_low[i]);       
}
}

* я сначала собираю отсчеты по 100 точек и сохраняю их в буффер, а затем отправляю по UART на COM порт в ПК. (так быстрее производительность, т.к. отправка по уарту занимает значительное время)

Просимулировал этот код в VMLAB, получил следующие тайминги:

Изображение

С учетом всех погрешностей на запись в переменные и т.п - получил, что снятие одного отсчета займет 10мкс - т.е. частота дискретизации 100кГц - все равно укладываемся.

Итак, на практике вот что я получаю:

Оцифровка сигнала частотой 10кГц амплитуда около 1В:
Изображение
Здесь около 10ти точек на период. Качество оцифровки неудовлетворительное.

Сразу же в настройках SPI выставил галочку SCLK x2 Rate - т.е. удвоили частоту тактирующего импульса (я предполагал что и качество оцифровки увеличится в 2 раза)

Вот как получилось с этой настройкой:

Оцифровка сигнала частотой 10кГц амплитуда около 1В (SPI SCLK x2 rate):

Изображение
Получилось 13 точек на период - совсем небольшой прирост =(

Мучил код, пробывал и так и сяк, симулировал.
Вот как получается, если после получения отсчета от АЦП - сразу выплевывать его на UART:

Код: Выделить всё

while (1) {     

ADC_CS = 0;       
putchar(spi(0x00));
putchar(spi(0x60));
ADC_CS = 1;     

}

Изображение
Совсем не так как хотелось бы.

* Сигнал с меньшей частотой оцифровывает прелестно. Вот пример оцифровки синуса с частотой 1кГц:
Изображение
Здесь меня всё устраивает. Около 90 точек на период. Качество отличное

Прошу помощи - оцифровкой занимаюсь в первый раз, как быть, вроде бы всё правильно - а на деле выходит совсем не то. Возможно код можно ещё как то более оптимизировать, или ещё где ошибку сделал? Прошу совета.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

1.Для красивой синусоиды 10 точек на период маловато будет.
2.Вижу на графиках параллельно с основным сигналом присутствие еще нескольких. Схема случаем не на макетке собрана? Присутствует ли разделение аналоговой и цифровой земли? Имеется ли хорошая фильтрация и стабилизация цепей питания аналог. части?
3. Что является источником сигнала? Уверены ли вы в его синусоидальности(смотрели ли вы его осцилом)?
mackerel
Открыл глаза
Сообщения: 70
Зарегистрирован: Пт янв 30, 2009 18:02:40

Сообщение mackerel »

А чем не устраивает результат? По теореме т. Котельникова для восстановления Вашего сигнала (одна-единственная синусоида) достаточно чуть-чуть-чуть больше двух выборок на период (и это действительно так, доказано вековой практикой человечества!). У Вас, как Вы говорите, их 13. В чём проблема-то?
Да, вдогонку: спектр входного сигнала действительно ограничен? Т.е. это действительно "чистый" синус? Если нет - частота выборок должна быть больше удвоенной частоты высшей гармоники, не забывайте. Ну, или фильтр прилепить нужно...
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Сообщение zi4rox »

2 uk8amk:

Сигнал там один идет - синус с DDS. Получается как бы наложение - из за того что я по 100 отсчетов беру, и сшиваются они иногда плохо.

Питание разделил на аналоговое и цифровое - а вот земля общая.

2 mackerel

Вы абсолютно правы! Именно сейчас этим и занимаюсь, пытаюсь восстановить сигнал через ряд котельникова. Но вот реализация несовсем получается. Не взгляните пожалуйста? (фильтр на входе стоит - так что всё должно выполнятся)

Пытаюсь сделать интерполяцию синком - не получается немного ...

Вот формула, для восстановления сигнала:
Изображение


x(t) - исходный сигнал
Fmax - частота сигнала, пусть Fmax = 1000 Гц
dt = 1/2Fmax (отсчеты идут через этот интервал времени) dt = 1/2*1000 = 0.0005

При это допустим что ацп выдает нам 13 отсчетов сигнала на период. Сам же период T = 1/f = 0.001. Вот на интервале времени в 1 период я и хочу восстановить сигнал. Тогда суммирование будет идти от n=0 до n=2Fmax*T=2000*0.001=2 // Всего 2 отсчета будет использоваться, а не все 13? //

s(n*dt) - это как раз сами отсчеты которые у меня есть.

Код: Выделить всё

// Это массив с отсчетами, которые у меня есть за 1 период

data_01[0]:= 1.10929;
data_01[1]:= 1.02396;
data_01[2]:= 0.85501;
data_01[3]:= 0.54537;
data_01[4]:= 0.31164;
data_01[5]:= 0.08533;
data_01[6]:= 0.02226;
data_01[7]:= 0.09275;
data_01[8]:= 0.26341;
data_01[9]:= 0.56763;
data_01[10]:= 0.81249;
data_01[11]:= 1.0388;
data_01[12]:= 1.09445;

...

//константы, что обговорили выше:
f_max:=1000;
dt:= 0.0005;
x:= 0.0004;

// вычисление значения восстановленного сигнала x(t) в точке x

  for n:=0 to 2 do begin
   buff:= data_01[n]*sin(2*3.14*f_max*(x-n*dt))/(2*3.14*f_max*(x-n*dt));
   result:= result+buff;
  end;


Я получаю 1,0849 - довольно близкий отсчет. Пробую строить сам график, беру 100 точек интерполяции с шагом в 0.0004

Код: Выделить всё

for j:=1 to 100 do begin
  result:=0; // обнуляю результат вычисления для каждой новой точки
  dx:= j*0.0004; // шаг восстановления: 0.0004, 0.0008, 0.0016 и.т.д.

  for n:=0 to 2 do begin
   buff:= data_01[n]*sin(2*3.14*f_max*(dx-n*dt))/(2*3.14*f_max*(dx-n*dt));
   result:= result+buff;
  end;

  // И добавляю вычесленную точку на график (x,y)
  Series2.AddXY(dx,result,'',clRed);


В результате получаю вот такую картинку:
Изображение

синк он мне рисует ... но это не восстановленный сигнал. Как я понял - тут должна быть сумма синков - и тогда образуется нужное.
Или я ошибаюсь? Помогите пожалуйста разобраться, а то голова кругом уже
mackerel
Открыл глаза
Сообщения: 70
Зарегистрирован: Пт янв 30, 2009 18:02:40

Сообщение mackerel »

В Вашей интерпретации выражение 2Fmax * T ВСЕГДА(!) равно двум, что явно неправильно, как мне кажется. Может, в этом и дело? Сам подобными выкладками не занимался, моё дело было - реализация в железе.
Коты!!! Ведь простая и интересная задача появилась!
Кто поможет решить?
(Самому стало интересно).

О, вот только что нашёл, может, будет полезно?
http://www.radioland.net.ua/contentid-422-page1.html
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Сообщение zi4rox »

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

Изображение
* на рисунке 250 точек на период - это число может быть теоретически любым

Всем спасибо кто помогал!
mackerel
Открыл глаза
Сообщения: 70
Зарегистрирован: Пт янв 30, 2009 18:02:40

Сообщение mackerel »

А не могли бы Вы выложить то же самое, но с 3-5 выборками на период? (Желательно живого сигнала, конечно). Насколько будет близко к оригиналу, интересно.
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Сообщение zi4rox »

mackerel писал(а):А не могли бы Вы выложить то же самое, но с 3-5 выборками на период? (Желательно живого сигнала, конечно). Насколько будет близко к оригиналу, интересно.


Самому интересно, думаю до конца недели оцифрую такую штуку, и выложу сюда.
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

как я понял связь у вас с АЦП и МК идёт по уарту, и частота 8МГц??...
здесь вроде бы всё должно быть нормально, а вот передача в компьютер вы уверены что успеваете передавать всё??... вы используете пинг-понг??


з.ы. сам недавно столкнулся с такой проблемой, и при первом выяснении оказалось что УСАРТ просто не успевает всё передать.
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Сообщение zi4rox »

Mozart писал(а):как я понял связь у вас с АЦП и МК идёт по уарту, и частота 8МГц??...


МК с АЦП связаны по SPI - там все что удается выжать - это 8МГЦ частота клока самого, но если учитывать задержки на запись в переменную - получается в 2 раза медленнее по общему времени - не знаю даже как это улучшить

Mozart писал(а):а вот передача в компьютер вы уверены что успеваете передавать всё??... вы используете пинг-понг??

з.ы. сам недавно столкнулся с такой проблемой, и при первом выяснении оказалось что УСАРТ просто не успевает всё передать.


УАРТ - дико медленный, Вы правы! Я передаю порциями по 100 отсчетов, и сшиваю куски, т.к. - сигнал периодический. Если делать так: Снял отсчет -> передал по уарту - то будет дикая задержка и сигнал оцифровываться будет гораздо хуже.
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

МК с АЦП связаны по SPI - там все что удается выжать - это 8МГЦ частота клока самого, но если учитывать задержки на запись в переменную - получается в 2 раза медленнее по общему времени - не знаю даже как это улучшить

да очепятался просто...

всё равно вы первые 100 порций передали а вторую порцию накопили, пока её накопили первая вся не ушла п уже надо передавать вторую... потом начинаете передавать вторую... первая уже на половину к примеру заполнена...
смутно изъясняюсь??

суть заключается в том что когда вы передали первые 100байт, вторые и третьи 100 байт куда-то записались, когда передаете вторые 100байт, то 4 и 5 записались и так далее...
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Сообщение zi4rox »

Конечно, передавать по 100 отсчетов - тоже не самое лучшее решение. Но это пока лучшее что придумал.

Возможно подкините идейку в этом направлении?
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

идей нет... но если заранее известно что это синусоида, тогда передавать значащие точки... к примеру нули (это будет период), потом "полу амплитуду" и пик синусоиды....

можно так попробовать...
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
zi4rox
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Ср апр 16, 2008 21:13:04
Контактная информация:

Сообщение zi4rox »

Да собственно с синосоидой проблем особо нет, помимо неё есть ещё один, более сложный сигнал. Так что пока борюсь с этим )
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Сообщение DrWatson »

Если МК только передает данные с АЦП в компьютер, почему бы не использовать USB вместо UART - теоретически должен успеть передавать и по одному байту. Расковырять к примеру исходник Отсюда только вместо UARTа использовать SPI.
А если USB использовать нет возможности, а длительность оцифровывания сигнала не более 1,5 сек, можно поставить внешнее ОЗУ для буферизации. В Mega8515, к примеру, есть для этого аппаратные средства.
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»