3. Дискритизація (Вибірка) IQ¶
У цьому розділі розглянемо концепцію IQ-дискретизації або IQ-вибірки (яку також називають комплексною дискретизацією або квадратурною дискретизацією). Ми також торкнемося таких тем, як: теорема частоти дирскретизації Найквіста, комплексних чисел, радіочастотних (РЧ) несучих, пониження частоти та спектральної щільності потужності. IQ-дискретизація це саме той метод дискретизації, який використовують у SDR-системах, а також в багатьох цифрових приймачах (і передавачах). Це дещо складніший варіант за звичайну цифрову дискретизацію, тому ми будемо рухатися поступово — і завдяки практиці ви неодмінно опануєте цю концепцію!
Основні поняття вибірки¶
Перш ніж перейти до вибірки IQ, давайте обговоримо, що насправді означає вибірка або дискретизація. Можливо, ви стикалися із дискретизацією, не усвідомлюючи цього, наприклад при запису звука з мікрофона. Мікрофон — це перетворювач, який перетворює звукові хвилі в електричний сигнал (рівень напруги). Цей електричний сигнал перетворюється аналого-цифровим перетворювачем (АЦП), створюючи цифрове представлення звукової хвилі. Для спрощення, мікрофон вловлює звукові хвилі, які перетворюються на електричний сигнал, а цей електричний сигнал, у свою чергу, перетворюється на цирові дані. АЦП слугує сполучною ланкою між аналоговим і цифровим світами. Пристрої SDR працюють на диво схоже. Однак замість мікрофона в них використовується антена, хоча АЦП застосовуються так само. В обох випадках АЦП здійснює дискретизацію рівня напруги. В SDR цей принцип можна описати так: на вході — радіохвилі, на виході — цифрові дані.
Якщо ми хочемо захопити, обробити або зберегти сигнал у цифровому вигляді незалежно від того, чи ми маємо справу з звуковими, чи з радіо хвилями, ми повинні взяти вибірку. Вибірка може здатися простою, але в ній багато чого є. Технічно цей спосіб дискретизації сигналу реалізован наступним чином, ми вимірюємо значення сигналу в певні визначені моменти часу та зберігаємо ці значення у цифровому вигляді. Скажімо, у нас є якась випадкова функція \(S(t)\), яка може представляти будь-що, і цю неперервну функцію, ми хочемо оцифрувати:
Ми зберігаємо значення \(S(t)\) виміряні через рівні проміжки часу тривалістю \(T\) секунд, ця тривалість називається періодом дискретизації. Частота, з якою ми беремо вибірку, тобто кількість вибірок, взятих за секунду, є просто \(\frac{1}{T}\). Ця величина називається частотою дискретизації, і вона зворотна до періоду дискретизації. Наприклад, якщо ми маємо частоту дискретизації 10 Гц, то період дискретизації становить 0,1 секунди; між кожним двома виборками буде 0,1 секунда. На практиці наші частоти дискретизації будуть в діапазоні від сотень кГц до десятків МГц або навіть більше. Коли ми оцифровуємо сигнали, ми повинні пам’ятати про частоту дискретизації, це дуже важливий параметр.
Для тих, хто віддає перевагу математичному опису: нехай \(S_n\) представляє вибірку \(n\), зазвичай ціле число, більше рівне 0. За такого підходу процес дискретизації можна математично представити як \(S_n = S(nT)\) для цілих значень \(n\). Тобто ми визначаємо значення аналогового сигналу \(S(t)\) у моменти часу, що відповідають інтервалам \(nT\).
Вибірка Найквіста¶
Для заданого сигналу головне питання часто полягає в тому, наскільки швидко ми повинні його дискретизувати? Розглянемо сигнал, який є просто синусоїдою, з частотою f, показаний зеленим кольором нижче. Припустимо, що ми дискретизуємо з частотою Fs (моменти искретизації показані синім кольором). Якщо ми дискретизуємо цей сигнал з частотою, що дорівнює f (тобто Fs = f), ми отримаємо щось подібне:
Червона пунктирна лінія на зображенні вище відтворює ще одну іншу — хибну — функцію, дискретизація якої могла б дати ті самі вибірки. Значить частота дискретизації була обрана замалою так як одні й ті самі виборки могли походити від двох різних функцій, тобто є неоднозначність. Якщо ми хочемо точно відновити початковий сигнал, такої неоднозначності бути не повинно.
Спробуймо дискретизувати трохи швидше, з Fs = 1,2f:
Знову ж таки, існує інший сигнал, який може відповідати цим вибіркам. Ця неоднозначність означає, що якби хтось надав нам цей масив виборок, ми на їх основі не змогли б розрізнити, який сигнал є оригінальним.
А щодо частоти дискретизації Fs = 1.5f:
Все ще недостатньо швидко! Згідно з теорією DSP, в яку ми не будемо занурюватися, вам потрібно робити вибірки з частотою, вдвічі більшою за частоту сигналу, щоб усунути неоднозначність, з якою ми стикаємося:
Цього разу немає іншого неправильного сигналу, оскільки ми дискретизували достатньо швидко так, щоб був тільки один сигнал, який би відповідав вибіркам (але це дійсно у випадку що ми не підвищуємо частоту сигналу який ми дискретизуємо, цей варіант обговоримо пізніше).
У наведеному вище прикладі наш сигнал був простою синусоїдою, більшість реальних сигналів матимуть багато частотних складових. Для точної дискретизації будь-якого сигналу частота дискретизації повинна бути “щонайменше вдвічі більшою за частоту максимальної частотної складової”. Нижче приклад графіку частотної області, зверніть увагу, що завжди існує рівень шуму, тому зазвичай верхня частота має наближене значення:
Зпочатку ми повинні визначити найвищу частотну складову, потім подвоїти це значення та переконатися, що ми дискретизуємо з цією подвоєною частотою або швидше. Мінімальна частота, з якою ми можемо дискретизувати, відома як частота Найквіста. Іншими словами, частота Найквіста - це мінімальна частота, з якою потрібно дискретизувати сигнал (що має кінцеву смугу пропускання), так щоб зберегти всю його інформацію. Це надзвичайно важлива частина теорії DSP та SDR, вона служить для переходу від безперервного до дискретного сигнала.
Якщо частота дискретизації недостатньо висока, виникає явище, що має назву «аліасинг» (або накладання спектрів); ми розглянемо його згодом, але намагаємося уникати за будь-яку ціну. Принцип роботи SDR (як і більшості приймачів загалом) полягає у фільтрації всіх частот, що перевищують Fs/2, безпосередньо перед виконанням дискретизації. Якщо спробувати прийняти сигнал із занизькою частотою дискретизації, цей фільтр відсіче частину сигналу. SDR-пристрої виконують значну роботу, щоб забезпечити отримання відліків, вільних від аліасингу та інших спотворень. Протиаліасинговий фільтр SDR не переходить від смуги пропускання до смуги загородження миттєво — йому потрібний невеликий перехідний проміжок. Тому діє емпіричне правило: прийнято вважати корисною смугою лише центральні 4/5 частоти дискретизації; це правило відоме як «правило 4/5 Шона» (Sean’s 4/5 rule).
Замість того, щоб вірити мені на слово, інтерактивна схема GNU Radio у вашому браузері дозволяє вам самостійно викликати аліасинг, інтерактивною схемою GNU Radio нижче, щоб самостійно створити аліасинг; схема працює повністю у вашому браузері. Косинусна хвиля дискретизується з частотою 100 кГц, тому частота Найквіста становить 50 кГц. Запустіть схему, а потім повільно перетягніть повзунок частоти тону вправо. Для частоти тону 50 кГц пік спекта зміщується праворуч, як і очікувалося, але при перевищені частоти 50 кГц він розвертається та частота піку зменшується, а графік в часової області показує, що семпли повністю вписуються в синусоїду з меншою частотою. Ось той самий «хибний сигнал», що на рисунках вище був проведений червоною пунктирною лінією, — тепер ви бачите його як результат реального вимірювання.
Квадратурна дискретизація¶
Термін «квадратура» має багато значень, але в контексті цифрової обробки сигналів (DSP) та SDR він стосується двох хвиль, зсунутих за фазою на 90 градусів. Чому саме на 90 градусів? Згадайте, що дві хвилі зі зсувом фази 180 градусів — це, по суті, одна й та сама хвиля, де одна з них помножена на -1. Завдяки зсуву фази на 90 градусів хвилі стають ортогональними, а з ортогональними функціями можна виконувати безліч цікавих операцій. Для простоти ми використовуємо синус і косинус як дві синусоїдальні хвилі, зсунуті одна відносно одної на 90 градусів.
Далі призначимо змінні для позначення амплітуди синуса і косинуса. Ми будемо використовувати \(I\) для cos() і \(Q\) для sin():
Це можна побачити наочно, якщо задати значення I та Q рівними 1:
Компонент cos() називають “синфазним”, звідси і назва I (In phase), а компонент sin() з зсувом на 90 градусів - “квадратурний” компонент, звідси і назва Q. Хоча якщо ви випадково переплутаєте їх і віднесете Q до cos(), а I до sin(), це не матиме значення для більшості ситуацій.
Принцип IQ-дискретизації легше зрозуміти, якщо розглянути його з погляду передавача. Розгляньмо завдання передачі радіочастотного (РЧ) сигналу в ефірі на певній частоті \(f\) (у Гц). Ми хочемо взяти синусоїду з частототою \(f\) і керувати її амплітудою \(A\) та фазою \(\phi\):
Знак «мінус» — це суто умовність, яка не має вирішального значення для розуміння концепції. У будь-який момент часу амплітуда й фаза, які ми хочемо передати, можуть змінюватися, тому для більшої формальності ми можемо представити їх як функції часу:
Виявляється, що в радіочастотних схемах керувати амплітудою синусоїди легко, а фазою — складно. Тому ми можемо скористатися тригонометричною тотожністю: \(a \cos(x) + b \sin(x) = A \cos(x - \phi)\), яка свідчить, що сума сигналів cos() і sin() з однакової частототою, і фазою, що дорівнює 0, еквівалентна сигналу cos() з амплітудою \(A\) і фазою \(\phi\). Використовуючи I і Q замість \(a\) і \(b\) та використовуючі ту ж саму частоту \(2 \pi f t\), отримуємо:
де
Завдяки такому підходу з використанням I та Q ми можемо передавати сигнал із будь-якою амплітудою та фазою, застосовуючи схему, що виглядає приблизно так:
Припустимо, у нас є вибірка IQ, тобто одне комплексне число \(I + jQ\). Ми можемо промодулювати цією вибіркою IQ синусоїду; і амплітуда і фаза будуть визначатися цією вибіркою IQ:
Ми вже розглянули математичне обґрунтування, а тепер спробуймо поекспериментувати з додаванням двох синусоїд, зсунутих одна відносно одної за фазою на 90 градусів. В інтерактивному додатку нижче є повзунки для регулювання амплітуд косинуса та синус, відповідно I та Q. На графіку косинус - це червона крива, синус - це синя крива, а їхня сума - зелена.
Важливо запам’ятати: коли ми додаємо cos() і sin(), то отримуємо ще одну чисту синусоїду тієї ж частоти, але з іншими фазою та амплітудою. Крім того, фаза змінюється, коли ми поступово зменшуємо або збільшуємо амплітуду однієї з двох складових (амплітуда результуючого сигналу також змінюється). Це є результатом тригонометричної тотожності: \(a \cos(x) + b \sin(x) = A \cos(x-\phi)\). “Корисність” такої математичної поведінки полягає в тому, що ми можемо керувати фазою і амплітудою результуючої синусоїди, змінюючи амплітуди I і Q (нам не потрібно змінювати фази косинуса або синуса). Наприклад, ми можемо регулювати I і Q таким чином, щоб амплітуда залишалася постійною, а фаза була такою, якою ми хочемо. Для передавача ця здатність надзвичайно корисна, оскільки ми знаємо, що нам потрібно передавати синусоїдальний сигнал, що поширюєтьс в просторі у вигляді електромагнітної хвилі. І набагато простіше змінювати дві амплітуди і виконати операцію додавання, ніж змінювати амплітуду і фазу. Це також дозволяє нам зручніше представляти сигнали основної смуги (baseband signals), роблячи їх незалежними від несучої.
Комплексні числа¶
Зрештою, IQ-представлення — це альтернативний спосіб представлення амплітуди та фази, що приводить нас до комплексних чисел і можливості їх відображення на комплексній площині. Можливо, ви вже стикалися з комплексними числами в інших областях. Розгляньмо як приклад комплексне число 0,7 - 0,4j:
Комплексне число - це просто два числа який розглядаються разом (як наприклад координати точки), одне число - це дійсна частина, інше - уявна. Комплексне число також може мати амплітуду і фазу, що буде зрозуміліше, якщо розглядати його як вектор, проведений з початку координат у точку. Амплітуда - це відстань між початком координат та точкою (іншими словами довжина вектора), а фаза - це кут між вектором і напрямком 0 градусів, напрямок 0 градусів вважається вісь на який ми відкладаємо додатну дійсну складову комплексного числа:
Такий спосіб зображення синусоїди називають «фазовою діаграмою». Це, по суті, побудова графіків комплексних чисел і розгляд їх як векторів. Вияснимо яка ж амплітуда і фаза нашого числа 0.7-0.4j? Для даного комплексного числа, де \(a\) - дійсна частина, а \(b\) - уявна частина:
У Python є функції np.abs(x) і np.angle(x) для визначення амплітуди і фази. На вхід функції подається комплексне число або масив комплексних чисел, а на виході будуть отримуватися дійсні числа (з типом даних float).
Можливо, ви вже зрозуміли, як ця векторна або фазова діаграма пов’язана з нашими позначками IQ: I - це дійсне частина, а Q - уявна. Відтепер, зображуючи комплексну площину, ми позначатимемо осі як I та Q відповідно замість «дійсної» та «уявної» частин. При цьому йтиметься все одно про комплексні числа!
Тепер припустимо, що ми хочемо передати нашу точку 0.7-0.4j. Ми будемо передавати:
Ми можемо використати тригонометричну тотожність \(a \cos(x) + b \sin(x) = A \cos(x-\phi)\), де \(A\) - наша величина, знайдена за допомогою \(\sqrt{I^2 + Q^2}\) а \(\phi\) - наша фаза, яка дорівнює \(\tan^{-1} \left( Q/I \right)\). І вищенаведене рівняння буде:
Хоча ми й почали з комплексного числа, насправді ми передаємо дійсний сигнал із певною амплітудою та фазою; адже неможливо передати щось уявне за допомогою електромагнітних хвиль. Ми просто використовуємо уявні (комплексні) числа для представлення сигналу, який передаємо. Незабаром ми поговоримо про \(f\).
Комплексні числа та ШПФ(FFT)¶
У наведеному вище прикладі розглядалися комплексні числа як відліки сигналу в часовій області, але з ними доводиться мати справу й під час виконання швидкого перетворення Фур’є (FFT). Коли в попередньому розділі ми вивчали ряди Фур’є та FFT, ми ще не заглиблювалися в тему комплексних чисел. Виконання FFT над послідовністю відліків дозволяє отримати представлення сигналу у частотній області. Ми вже говорили про те, що FFT визначає, які саме частоти наявні в цьому наборі відліків (модуль результату FFT вказує на інтенсивність кожної частоти). Однак FFT також визначає затримку (часовий зсув), яку потрібно застосувати до кожної з цих частот, щоб сумування відповідних синусоїд дозволило відтворити вихідний сигнал у часовій області. Ця затримка — це, власне, і є фаза результату FFT. Результатом FFT є масив комплексних чисел: кожне число визначає модуль і фазу, а індекс цього числа вказує на відповідну частоту. Якщо згенерувати синусоїди з такими частотами, модулями й фазами та підсумувати їх, ви отримаєте початковий сигнал у часовій області (або дуже близький до нього; саме тут важливу роль відіграє теорема Найквіста про дискретизацію).
Погляд на IQ-виборки з сторони приймача¶
Тепер давайте подивимось з боку радіоприймача, який намагається прийняти сигнал (наприклад, FM-радіосигнал). З використанням IQ-виборки, схема тепер має наступний вигляд:
На вхід надходить реальний сигнал, отриманий на нашу антену, і він перетворюється на значення IQ. Ми робимо дискретизацію I і Q сигналів окремо, використовуючи два окремих АЦП, а потім об’єднуємо пари отриманих значень і зберігаємо їх у вигляді комплексних чисел. Іншими словами, в один моменти часу ви будете відбирати одне значення I і одне значення Q і об’єднувати їх у вигляді \(I + jQ\) (тобто, одна вибірка IQ це одне комплексне число). Тобто завжди буде існувати “частота семплювання”, тобто швидкість, з якою виконується вибірка значень. Можно сказати: “Є SDR з частотою семплювання 2 МГц”. Це значить, що SDR отримує два мільйони відліків IQ в секунду.
Якщо ви отримаєте набір IQ-відліків, він виглядатиме як одновимірний масив (або вектор) комплексних чисел. Саме до цього — розуміння суті комплексних чисел у цьому контексті — ми йшли протягом усього цього розділу, і нарешті досягли мети.
У цьому підручнику ви детально дізнаєтеся, як працюють IQ-відліки, як приймати й передавати їх за допомогою SDR, як обробляти їх у Python і як зберігати у файлі для подальшого аналізу.
І наостанок важливе зауваження: на рисунку вище показано, що відбувається всередині SDR. Нам не потрібно власноруч генерувати синусоїду, виконувати зсув на 90 градусів, множити чи додавати сигнали — SDR робить це за нас. Ми лише вказуємо SDR несучу частоту, на якій хочемо виконувати дискретизацію сигналу для отримання відліків або на якій хочемо виконати передачу відліків. Від приймача SDR отримуємо IQ-відліки. А на передавач SDR ми, навпаки, передаємо IQ-виборки. Ці виборки будуть представлені комплексними числами, в яких дійсна і уявна частина будуть або цілими або дійсними числами.
Несуча частота та перенос частоти вниз¶
До цього моменту ми не обговорювали частоту, але ми бачили, що в рівняннях, що включають cos() і sin() є \(f\). Ця частота є центральною частотою сигналу, що розповсюджується (частота електромагнітної хвилі). Ми називаємо її “несучою”, тому що вона переносить наш сигнал на певній радіочастоті. Коли ми налаштовуємося на частоту за допомогою SDR і отримуємо відліки, наша інформація зберігається в серії значень I і Q; якщо припустити, що ми налаштувалися на несучу тоді значення несучої не можно вивести з значень I і Q.
Для довідки: радіосигнали, такі як FM-радіо, WiFi, Bluetooth, LTE, GPS тощо, зазвичай використовують частоту (тобто несучу) між 100 МГц і 6 ГГц. Ці частоти дуже добре поширюються в повітрі, та не потребують занадто довгих антен або великої потужності для передачі чи прийому. У вашій мікрохвильовий печі їжа готується за допомогою електромагнітних хвиль на частоті 2,4 ГГц. Якщо дверцята мікрохвильової печі протікають, вона глушитиме сигнали WiFi, і може також обпекти вам шкіру. Іншою формою електромагнітних хвиль є світло. Видиме світло має частоту близько 500 ТГц. Це настільки висока частота, що ми не використовуємо традиційні антени для передачі світла. Ми використовуємо такі методи, як світлодіоди, які є напівпровідниковими пристроями. Вони створюють світло, коли електрони перескакують між атомними орбітами напівпровідникового матеріалу, і колір залежить від того, як далеко вони перескакують. Технічно радіочастотами (РЧ) вважають діапазон від приблизно 20 кГц до 300 ГГц. Це частоти, на яких енергія зміного електричного струму, може випромінюватися з провідника (антени) і поширюватися в просторі. Для більшості сучасних застосувань діапазон від 100 МГц до 6 ГГц є найбільш корисними. Частоти вище 6 ГГц десятиліттями використовувалися для радарів і супутникового зв’язку, а зараз застосовуються в 5G на “міліметрових хвилях” (24 - 29 ГГц) для доповнення діапазонів з меншими частотами і збільшення швидкості.
Коли ми швидко змінюємо значення IQ і передаємо нашу несучу, це називається “модуляцією” несучої (даними або будь-яким іншим сигналом). Коли ми змінюємо I і Q, ми змінюємо фазу і амплітуду несучої. Інший варіант модуляції - змінити частоту несучої, тобто зсунути її трохи вгору або вниз, як це робить FM-радіо. Легко заплутатися між сигналом, який ми хочемо передати (який зазвичай містить багато частотних компонентів), і частотою, на якій ми його передаємо (наша несуча частота). Сподіваємося, це стане зрозумілішим, коли ми розглянемо поняття сигналів у смузі основних частот (baseband) та смугових сигналів (bandpass).
А тепер повернемося на секунду до дискретизації. Замість того, щоб отримувати відліки шляхом множення сигналу з антени на cos() і sin(), а потім збереження значень I і Q, що трапилось, якби ми подавали сигнал з антени напряму один АЦП, як в архітектурі з прямою дискретизацією? Скажімо, несуча частота 2,4 ГГц, як у WiFi або Bluetooth. Це означає, як ми вже знаємо, що нам доведеться робити вибірки на частоті 4,8 ГГц. Це надзвичайно швидко! АЦП, який робить такі швидкі вибірки, коштує тисячі доларів. Замість цього ми “понижуємо” сигнал так, щоб сигнал, який ми хочемо отримати, був зосереджений навколо постійного струму або навколо частоти 0 Гц. Це перетворення відбувається до того, як ми почнемо отримувати відліки. Ми переходимо від
до просто I та Q.
Візуалізуємо перенсо вниз по частоті:
Коли ми відцентрували сигнал навколо 0 Гц, максимальна частота вже не буде дорівнювати 2,4 ГГц, а буде залежити від характеристик сигналу, оскільки ми видалили несучу. Більшість сигналів мають ширину смуги пропускання від 100 кГц до 40 МГц, тому за допомогою перетворення частот вниз ми можемо робити вибірки з набагато нижчою частотою. І B2Xо USRP, і PlutoSDR містять радіочастотну інтегральну схему (RFIC), яка може робити вибірки з частотою до 56 МГц, що достатньо велике значення для більшості сигналів, з якими ми зустрінемося.
Нагадуємо, що процес пониження частоти виконується нашим SDR; як користувачеві SDR нам не потрібно нічого робити, окрім як вказати йому, на яку частоту налаштовуватися. Перетворення вверх і вниз по частоті здійснюється за допомогою компонента, який називається мікшером, що зазвичай зображується на схемах у вигляді символу множення всередині кола. Мікшер приймає сигнал, і виводить вже перетворений вниз/вгору сигнал на вихід, мкшер має третій порт, який використовується для підключення генератора. Частота генератора визначає зсув частоти, що застосовується до сигналу, а мікшер, по суті, є просто функцією множення (нагадаємо, що множення на синусоїду викликає зсув частоти).
Насамкінець, вам може бути цікаво, як швидко сигнали поширюються в повітрі. Згадайте з шкільного курсу фізики, що радіохвилі - це просто електромагнітні хвилі на низьких частотах (приблизно від 3 кГц до 80 ГГц). Видиме світло - це також електромагнітні хвилі, але на значно вищих частотах (від 400 ТГц до 700 ТГц). Всі електромагнітні хвилі поширюються зі швидкістю світла, яка становить близько 3e8 м/с, принаймні, коли вони проходять через повітря або вакуум. Оскільки вони завжди рухаються з однаковою швидкістю, відстань, яку хвиля проходить за одне повне коливання (один повний цикл синусоїди), залежить від її частоти. Ми називаємо цю відстань довжиною хвилі і позначаємо її \(\lambda\). Ви, мабуть, бачили цю залежність раніше:
де \(c\) - швидкість світла, зазвичай дорівнює 3e8, коли \(f\) - у Гц, а \(\lambda\) - у метрах. У бездротовому зв’язку це співвідношення стане важливим, коли ми переїдемо до розгляду антен, тому що для прийому сигналу на певній несучій частоті, \(f\), потрібна антена, яка відповідає його довжині хвилі, \(\lambda\), зазвичай антена має \(\lambda/2\) або \(\lambda/4\) довжину. Однак, незалежно від частоти/довжини хвилі, інформація, що міститься в цьому сигналі, завжди буде рухатися зі швидкістю світла від передавача до приймача. При обчисленні цієї затримки в повітрі можна скористатися емпіричним правилом, що світло проходить приблизно один фут (30см) за одну наносекунду. Ще одне емпіричне правило: час для проходу сигналу вверх до супутника на геостаціонарній орбіті і назад приблизно дорівнює 0,25 секунди.
Архітектура приймачів¶
На малюнку в розділі “Приймач” показано, як вхідний сигнал перетворюється і розділяється на I і Q. Така схема називається “пряме перетворення”, або “нульова ПЧ”, тому що радіочастоти безпосередньо перетворюються до базової смуги частот. Інший варіант - взагалі не перетворювати частоти вниз і робити вибірку так швидко, щоб захопити все від 0 Гц до 1/2 частоти дискретизації. Ця стратегія називається “пряма вибірка” або “пряма ВЧ”, і вона вимагає надзвичайно дорогого чіпа АЦП. Третя архітектура, популярна тому, що саме так працювали старі радіоприймачі, відома як “супергетеродин”. Вона передбачає перетворення вниз, але не до 0 Гц. Він поміщає сигнал, що нас цікавить, на проміжну частоту, відому як “ПЧ”. Підсилювач з низьким рівнем шуму (LNA) - це просто підсилювач, призначений для сигналів надзвичайно низької потужності на вході. Ось блок-схеми цих трьох архітектур, зверніть увагу, що існують також варіації та гібриди цих архітектур:
Сигнали основної та смугових частот¶
Ми називаємо сигнал з центром близько 0 Гц “основною смугою”. І навпаки, “смуговий” означає, що сигнал існує на певній радіочастоті, не близькій до 0 Гц, яка була зміщена вгору з метою бездротової передачі. Поняття “передача в основній смузі частот” не існує, тому що ви не можете передати щось уявне. Сигнал в основній смузі може бути ідеально відцентрований на 0 Гц, як на правій частині малюнка в попередньому розділі. Він може бути близько 0 Гц, як два сигнали, показані нижче. Ці два сигнали все ще вважаються основною смугою. Також показано приклад смугового сигналу з центром на дуже високій частоті, позначеній \(f_c\).
Ви також можете почути термін “проміжна частота” (скорочено ПЧ); поки що уявіть собі ПЧ як проміжний крок перетворення у радіоприймачі між базовою смугою та смугою пропускання/ВЧ.
Ми, як правило, створюємо, записуємо або аналізуємо сигнали в базовій смузі, оскільки можемо працювати з меншою частотою дискретизації (з причин, описаних у попередньому підрозділі). Важливо зазначити, що сигнали базової смуги часто є складними сигналами, в той час як сигнали в смузі пропускання (наприклад, сигнали, які ми фактично передаємо через радіочастоти) є реальними. Подумайте про це: оскільки сигнал, що подається через антену, повинен бути реальним, ви не можете безпосередньо передавати складний/уявний сигнал. Ви знатимете, що сигнал точно є комплексним, якщо від’ємна та додатна частоти сигналу не збігаються в точності. Зрештою, комплексні числа - це те, як ми представляємо від’ємні частоти. Насправді не існує від’ємних частот; це просто частина сигналу нижче несучої частоти.
Якщо в нашому сигналі немає уявної складової, то в нас немає й значень Q (або можна вважати, що всі значення Q дорівнюють нулю). Це, своєю чергою, означає, що ми маємо лише косинусні сигнали без жодного зсуву фази. Сума косинусних сигналів без зсуву фази буде симетричною відносно осі y на графіку в частотній області, оскільки додатні та від’ємні складові однакові.
У попередньому розділі, де ми гралися з комплексною точкою 0,7 - 0,4j, це був, по суті, один відлік у сигналі основної смуги. Більшість часу, коли ви бачите комплексні відліки (IQ-відліки), ви перебуваєте в основній смузі частот. Сигнали рідко представляються або зберігаються в цифровому вигляді в радіочастотному діапазоні через велику кількість даних, а також через те, що нас зазвичай цікавить лише невелика частина радіочастотного спектру.
Налаштування стрибкоподібного та зміщеного постійного струму¶
Як тільки ви починаєте працювати з SDR, ви часто бачите великий пік в центрі БПФ. Це називається “зміщенням постійного струму” або “стрибком постійного струму”, або іноді “витоком LO”, де LO означає локальний осцилятор.
Ось приклад стрибка постійного струму:
Оскільки SDR налаштовується на центральну частоту, ділянка 0 Гц у БПФ відповідає центральній частоті. При цьому стрибок постійного струму не обов’язково означає, що на центральній частоті є енергія. Якщо є лише стрибок постійного струму, а решта БПФ виглядає як шум, то, швидше за все, там, де він вам показує, насправді немає сигналу.
Зміщення постійного струму є поширеним артефактом у приймачах прямого перетворення, які використовують архітектуру SDR, таких як PlutoSDR, RTL-SDR, LimeSDR і багатьох Ettus USRP. У приймачах прямого перетворення генератор, LO, перетворює сигнал з його фактичної частоти в базову смугу. В результаті, витоки від цього генератора з’являються в центрі смуги пропускання, що спостерігається. Витоки LO - це додаткова енергія, створена комбінацією частот. Видалити цей додатковий шум важко, оскільки він близький до бажаного вихідного сигналу. Багато радіочастотних інтегральних схем (RFIC) мають вбудовану функцію автоматичного видалення постійного зсуву, але для її роботи зазвичай потрібен сигнал. Ось чому стрибок постійного струму буде дуже помітним за відсутності сигналу.
Швидкий спосіб впоратися зі зміщенням постійного струму - передискретизувати сигнал і розстроїти його. Для прикладу, скажімо, ми хочемо переглянути 5 МГц спектра на частоті 100 МГц. Замість цього ми можемо зробити вибірку на 20 МГц з центральною частотою 95 МГц.
Синя рамка вище показує, що насправді виділяється SDR, а зелена рамка відображає частину спектру, яку ми хочемо отримати. Наш LO буде встановлено на 95 МГц, тому що це частота, на яку ми просимо SDR налаштуватися. Оскільки 95 МГц знаходиться за межами зеленого квадратика, ми не отримаємо жодного сплеску постійного струму.
Є одна проблема: якщо ми хочемо, щоб наш сигнал був центрований на 100 МГц і містив лише 5 МГц, нам доведеться самостійно виконати зсув частоти, фільтрацію і пониження дискретизації сигналу (про це ми дізнаємося пізніше). На щастя, цей процес розстроювання, так зване застосування LO-зсуву, часто вбудовано в SDR, де вони автоматично виконують розстроювання, а потім зміщують частоту до бажаної центральної частоти. Ми виграємо, коли SDR може робити це самостійно: нам не потрібно передавати вищу частоту дискретизації через USB- або Ethernet-з’єднання, які обмежують можливості використання високої частоти дискретизації.
Цей підрозділ, присвячений зміщенням постійного струму, є гарним прикладом того, чим цей підручник відрізняється від інших. У середньостатистичному підручнику з ЦОС обговорюється дискретизація, але в ньому, як правило, не розглядаються перешкоди при реалізації, такі як зміщення постійного струму, незважаючи на їхню поширеність на практиці.
Схема GNU Radio нижче моделює всю цю ситуацію, зменшену з наведеного вище прикладу на 20 МГц до 1 МГц, щоб вона комфортно працювала в браузері. Верхній спектр - це те, що видає вам SDR: великий сплеск постійного струму на частоті гетеродина і потрібний нам сигнал збоку від нього. Нижній спектр - це те, що виходить після зсуву частоти й фільтрації, які передбачає розстроєне налаштування: сигнал тепер по центру, а сплеску не видно. Опустіть зсув постійного струму до нуля, щоб побачити, як виглядав би приймач без просочування гетеродина.
Семплірування за допомогою нашого SDR¶
Для отримання специфічної для SDR інформації про виконання дискретизації див. одну з наступних глав:
- PlutoSDR на Python Розділ
- USRP на Python Глава
Обчислення середньої потужності¶
У радіочастотному DSP ми часто хочемо обчислити потужність сигналу, наприклад, щоб виявити наявність сигналу перед тим, як намагатися виконати подальшу обробку. Для дискретного складного сигналу, тобто сигналу, який ми дискретизували, ми можемо знайти середню потужність, взявши величину кожного відліку, піднісши її до квадрата і знайшовши середнє значення:
Пам’ятайте, що абсолютне значення комплексного числа - це просто величина, тобто \(\sqrt{I^2+Q^2}\)
У мові Python обчислення середнього степеня буде мати вигляд:
avg_pwr = np.mean(np.abs(x)**2)
Це дуже корисний трюк для обчислення середньої потужності дискретизованого сигналу. Якщо ваш сигнал має приблизно нульове середнє значення - що зазвичай буває в SDR (пізніше ми побачимо чому) - то потужність сигналу можна знайти, взявши дисперсію відліків. За цих обставин ви можете обчислити потужність таким чином у Python:
avg_pwr = np.var(x) # (сигнал повинен мати приблизно нульове середнє)
Причина, чому дисперсія вибірок обчислює середню потужність, досить проста: рівняння для дисперсії має вигляд \(\frac{1}{N}\sum^N_{n=1} |x[n]-\mu|^2\) де \(\mu\) - середнє значення сигналу. Це рівняння виглядає знайомим! Якщо \(\mu\) дорівнює нулю, то рівняння для визначення дисперсії відліків стає еквівалентним рівнянню для потужності. Ви також можете відняти середнє значення від вибірок у вашому вікні спостережень, а потім взяти дисперсію. Просто знайте, що якщо середнє значення не дорівнює нулю, то дисперсія і потужність не рівні.
Обчислення спектральної щільності потужності¶
У попередньому розділі ми дізналися, що можна перетворити сигнал у частотну область за допомогою ШПФ, а результат називається спектральною щільністю потужності (PSD). PSD є надзвичайно корисним інструментом для візуалізації сигналів у частотній області, і багато алгоритмів ЦОС виконуються в частотній області. Але для того, щоб дійсно знайти PSD пачки відліків і побудувати її графік, ми робимо більше, ніж просто беремо БПФ. Для обчислення PSD потрібно виконати наступні шість операцій:
- Беремо БПФ наших відліків. Якщо у нас є x відліків, то за замовчуванням розмір БПФ буде дорівнювати довжині x. Давайте використаємо перші 1024 відліки як приклад для створення ШПФ розміром 1024. На виході ми отримаємо 1024 комплексних числа з плаваючою комою.
- Візьмемо величину виходу ШПФ, яка дає нам 1024 дійсних числа.
- Піднесіть отриману величину до квадрату, щоб отримати потужність.
- Нормалізуємо: ділимо на розмір ШПФ (\(N\)) і частоту дискретизації (\(Fs\)).
- Конвертуємо в дБ за допомогою \(10 \log_{10}()\); ми завжди переглядаємо PSD в логарифмічній шкалі.
- Виконайте зсув ШПФ, описаний у попередньому розділі, щоб перемістити “0 Гц” у центр, а від’ємні частоти - ліворуч від центру.
Ці шість кроків у Python виглядають так:
Fs = 1e6 # скажімо, ми зробили вибірку на частоті 1 МГц
# припустимо, що x містить ваш масив відліків IQ
N = 1024
x = x[0:N] # ми візьмемо ШПФ тільки перших 1024 відліків, див. текст нижче
PSD = np.abs(np.fft.fft(x))**2 / (N*Fs)
PSD_log = 10.0*np.log10(PSD)
PSD_shifted = np.fft.fftshift(PSD_log)
За бажанням ми можемо застосувати вікно, про яке ми дізналися у розділі Частотна область. Вікно з’явиться безпосередньо перед рядком коду з fft().
# додати наступний рядок після виконання x = x[0:1024]
x = x * np.hamming(len(x)) # застосовуємо вікно Хеммінга
Для побудови цієї PSD нам потрібно знати значення осі x. Як ми дізналися з попереднього розділу, коли ми робимо вибірку сигналу, ми “бачимо” лише спектр між -Fs/2 і Fs/2, де Fs - це частота дискретизації. Роздільна здатність, якої ми досягаємо в частотній області, залежить від розміру нашого ШПФ, який за замовчуванням дорівнює кількості відліків, над якими ми виконуємо операцію ШПФ. У цьому випадку наша вісь х - це 1024 рівномірно розташовані точки між -0,5 МГц і 0,5 МГц. Якби ми налаштували наш SDR на 2,4 ГГц, наше вікно спостереження було б між 2,3995 ГГц і 2,4005 ГГц. У Python зміщення вікна спостереження буде виглядати так:
center_freq = 2.4e9 # частота, на яку ми налаштували наш SDR
f = np.arange(Fs/-2.0, Fs/2.0, Fs/N) # старт, стоп, крок. з центром навколо 0 Гц
f += center_freq # тепер додаємо центральну частоту
plt.plot(f, PSD_shifted)
plt.show()
У нас повинен залишитися гарний PSD!
Якщо ви хочете знайти PSD для мільйонів відліків, не робіть ШПФ з мільйонами точок, тому що це займе вічність. Зрештою, це дасть вам на виході мільйон “частотних бінів”, що занадто багато, щоб показати на графіку. Замість цього я пропоную зробити кілька менших PSD і усереднити їх разом або відобразити за допомогою графіка спектрограми. Крім того, якщо ви знаєте, що ваш сигнал не змінюється швидко, достатньо використати кілька тисяч відліків і знайти PSD з них; за цей часовий проміжок у кілька тисяч відліків ви, ймовірно, захопите достатньо сигналу, щоб отримати гарне представлення.
Ось повний приклад коду, який включає генерування сигналу (комплексна експонента з частотою 50 Гц) і шуму. Зверніть увагу, що N, кількість відліків для імітації, стає довжиною ШПФ, оскільки ми беремо ШПФ всього імітованого сигналу.
import numpy as np
import matplotlib.pyplot as plt
Fs = 300 # частота дискретизації
Ts = 1/Fs # період дискретизації
N = 2048 # кількість відліків для моделювання
t = Ts*np.arange(N)
x = np.exp(1j*2*np.pi*50*t) # імітує синусоїду 50 Гц
n = (np.random.randn(N) + 1j*np.random.randn(N))/np.sqrt(2) # комплексний шум з одиничною потужністю
noise_power = 2
r = x + n * np.sqrt(noise_power)
PSD = np.abs(np.fft.fft(r))**2 / (N*Fs)
PSD_log = 10.0*np.log10(PSD)
PSD_shifted = np.fft.fftshift(PSD_log)
f = np.arange(Fs/-2.0, Fs/2.0, Fs/N) # старт, стоп, крок
plt.plot(f, PSD_shifted)
plt.xlabel("Частота [Гц]")
plt.ylabel("Амплітуда [дБ]")
plt.grid(True)
plt.show()
Виведення на екран: