del Prof. Dr. Martin Ossmann
Come costruire un analizzatore di spettro basato su un semplice Raspberry Pi Pico. Con una risoluzione di 12 bit e un tasso di campionamento di 500 kS/s è l’ideale per misurazioni audio. Con un ADC esterno, è possibile raggiungere addirittura i 50 MS/s!
Quando si utilizza il convertitore analogico-digitale (ADC) integrato nel microcontrollore Raspberry Pi RP2040, i segnali analogici vengono campionati fino a 500 kS/s con una risoluzione a 12 bit. Per visualizzare i valori può essere utilizzato un PC. Come passo successivo può essere collegato un display LCD, che consente di ottenere un analizzatore autonomo. Aggiungendo un ADC esterno, si possono raggiungere fino a 50 MS/s, rendendo l’analizzatore adatto per segnali fino a 25 MHz.
500 kS/s e Connessione al PC
Per i primi esperimenti, il Raspberry Pi Pico è cablato come mostrato nella Figura 1.

R2 e R3 innalzano il punto zero dell’ADC a metà della tensione di alimentazione. C1 rimuove i componenti di tensione continua dal segnale in ingresso. L’ingresso utilizzato, ADC2, utilizza il Pin 34 insieme al GPIO28. T1 viene utilizzato insieme a R1 per stabilire un livello TTL per l’output dati al PC tramite l’interfaccia seriale a 115.200 baud. Poiché il circuito è piuttosto semplice, può essere facilmente implementato su una breadboard, come mostrato nella Figura 2.

L’ADC opera inizialmente con il tasso di campionamento predefinito di 500 kHz. Trasferisce i suoi campioni a 12 bit a un’unità FIFO, da dove entrano in un buffer che può memorizzare N valori. N ha tipicamente un valore di 1.024. Ogni volta che il buffer è pieno, i valori vengono inviati in serie al PC.
La trasformata discreta di Fourier (DFT)
Lo spettro viene calcolato utilizzando la trasformata di Fourier discreta (DFT). Questo algoritmo prende N campioni sn (con n = 0 a N-1) del segnale in ingresso per calcolare N valori dello spettro Zk (con k = 0 a N-1). La regola di trasformazione applicata è la seguente:

La DFT consiste in N numeri complessi. Se il segnale in ingresso è reale, come in questo caso, la DFT risultante è simmetrica e si applica quanto segue:

Quindi solo i primi valori N/2 sono rilevanti. Questo è dovuto al teorema del campionamento, secondo il quale si ottengono valori univoci solo fino a metà del tasso di campionamento. Di conseguenza, vengono utilizzati solo i primi valori N/2 dello spettro. Lo spettro calcolato corrisponde a quello del segnale di ingresso S, prolungato con il periodo N.
Come la DFT esegue l’analisi spettrale
Per comprendere perché la DFT effettua effettivamente un’analisi spettrale, consideriamo prima come il segnale in ingresso sn = cos(2 π m n / N) è trasformato, ad esempio, con m = 5 e N = 16. Questo segnale in ingresso è una oscillazione cosinusoidale con la frequenza f = fs m / N. I valori trasformati risultanti sono Zm = Z5 = N/2 = 8, e gli altri valori, Zk, sono tutti zero. Quindi, un’oscillazione di frequenza m diventa notabile esattamente nel valore trasformato di mth. Se invece del segnale cosinusoidale, venisse trasformato un segnale sinusoidale, la parte immaginaria di Zm non sarebbe zero. Ma cosa succede quando si trasforma un segnale composto da oscillazioni di diverse frequenze? Anche questo è semplice: la DFT è una trasformazione lineare, il che significa che la DFT di una somma è anche uguale alla somma delle DFT dei singoli segnali. La formula risultante è:
DFT(u Un + v Vn) = u DFT(Un) + v DFT(Vn)
Linearità e scalatura della DFT
con i prefattori u e v. Se il segnale in ingresso è composto da diverse oscillazioni sn = cos(2 π m n / N) con diverse frequenze m, questo porta esattamente alle oscillazioni individuali nello spettro. Un segnale sn = A cos(2 π m n / N) con ampiezza A porta a un valore Zm = A N / 2 nello spettro. Questo valore dipende dal numero di campioni. Per eliminare questo, la DFT è scalata da un fattore di 2 / N. Lo spettro nuovo avrà quindi i valori Wk = 2 Zk / N. Un segnale cosinusoidale con ampiezza A porta quindi a un valore dello spettro di esattamente A. Il valore di ampiezza A è il valore di picco del segnale cosinusoidale. Per il valore efficace, deve essere diviso per √2.
Tempo di calcolo
Il tempo di calcolo della DFT cresce quadraticamente con il numero N di campioni. Può quindi richiedere molto tempo con un N più grande. Misure con il Raspberry Pi Pico hanno portato all’approssimazione TDFT ≈ 9 N2 µs. Se N è una potenza di due, è possibile utilizzare la trasformata veloce di Fourier (FFT) invece della DFT, poiché calcola gli stessi valori molto più velocemente. Sulla scheda Pico, il tempo di calcolo è TFFT ≈ 4 N log2(N). La Tabella 1 mostra i tempi di calcolo per alcuni valori praticabili di N. Per un’analisi spettrale semplice, N = 1024 è spesso utilizzato. Il tempo di calcolo della DFT sarebbe ancora accettabile qui con circa 9 s, ma la FFT è molto più veloce con 40 ms.

Occasionalmente, viene utilizzato anche N = 16.384, per il quale la DFT richiederebbe già un buon 40 minuti, quindi è inaccettabilmente lenta. La FFT, invece, impiega meno di un secondo! Quindi, N è sempre selezionato come potenza di due a favore della FFT.
Valore RMS
Nell’ingegneria delle comunicazioni, le grandezze sono spesso specificate come valori efficaci. Poiché per questo la grandezza dipendente dal tempo viene elevata al quadrato, mediata e quindi viene presa la radice, il termine radice quadratica media (RMS) è diventato comune per questo concetto. Per un segnale discreto e periodico con lunghezza di periodo N come i nostri segnali DFT, il valore RMS viene calcolato nel seguente modo:

È anche possibile calcolare il valore RMS dei valori spettrali. Otteniamo quindi:

e

Ora vale quanto segue:

o

Livelli in dB e dBm
Ciò significa che il valore RMS può essere calcolato anche nel dominio delle frequenze invece che nel dominio del tempo. Per questo, è necessario considerare solo il prefattore. Questa relazione è anche chiamata identità di Parseval (https://en.wikipedia.org/wiki/Parseval%27s_identity). L’energia nel dominio del tempo è quindi accuratamente riflessa dalla somma delle energie delle singole oscillazioni nel dominio delle frequenze. I rapporti di energia o potenza sono spesso espressi in dB nell’ingegneria delle comunicazioni. Per il rapporto di potenza v = P1 / P0, otteniamo vdB = 10 log10(P1 / P0). Per livelli assoluti, il livello di riferimento P0 = 1 mW è comune. Otteniamo quindi PdBm = 10 log10(P / 1 mW). Se vogliamo specificare tensioni U in dBm, utilizziamo la potenza P su una resistenza di R = 50 Ω, alla quale viene applicata la tensione URMS. Poiché la potenza dissipata dalla resistenza è P = U2 / R, otteniamo UdBm = 10 log10(U2RMS / (R 1 mW). Per l’analizzatore di spettro descritto qui, l’asse Y è scalato in dBm, la rappresentazione logaritmica usuale per gli analizzatori di spettro; ma attenzione, nell’ingegneria audio dBm si riferisce spesso a una carico di 600 Ω.
Il problema del leakage spettrale
Finora abbiamo considerato segnali in ingresso che rientrano esattamente in una finestra di N valori. La frequenza m del segnale sn = A cos(2 π m n / N) era quindi un numero intero. La Figura 3 mostra lo spettro a m = 5.5 e N = 256.

In realtà, ci si aspetterebbe uno spettro a forma di linea perché il segnale contiene una sola frequenza. Invece, si ottiene uno spettro che diminuisce lentamente su entrambi i lati dei valori massimi. Questo è ovviamente inutile per un analizzatore di spettro. Il motivo è che il segnale periodicamente ripetuto (lunghezza di periodo N) contiene un salto ai bordi. Questo è chiaramente visibile nel diagramma ampiezza/tempo di due periodi nella Figura 4: al campione N, il segnale passa da +1 V a -1 V. Questo salto genera componenti ad alta frequenza oltre alla frequenza del segnale.

La finestra di Blackman
Per evitare questi effetti, si applica la tecnica della finestra, che in principio è equivalente a un inviluppo sovrapposto. Questo comporta la moltiplicazione del segnale di ingresso per una funzione finestra, che lo riduce delicatamente ad ampiezza 0 ai limiti della finestra, non cambiando molto il segnale. La Figura 5 mostra la funzione finestra utilizzata. La Figura 6 mostra due periodi del segnale moltiplicati per la funzione finestra.


Si può vedere chiaramente come il segnale sia modulato in ampiezza in modo che non ci siano salti ai bordi del periodo (0, N, 2N…) ma che proceda in modo continuo. Ci sono diverse funzioni finestra in uso, ognuna con vantaggi e svantaggi differenti. La seguente lista C mostra come viene calcolata la finestra di Blackman (a tre termini) utilizzata qui:
double windowFun(int k) {
double alpha=0.16;
double a0=(1-alpha)/2;
double a1=0.5;
double a2=alpha/2;
return a0-a1cos(2PIk/(N-1))+a2cos(4PIk/(N-1));
}
La funzione finestra è composta da due funzioni coseno. Dopo l’applicazione della finestra, la FFT restituisce lo spettro della Figura 7.

Il massimo spettrale ha una larghezza di quattro bin intorno a m = 5.5 e poi diminuisce significativamente. Con valori più grandi per N, l’espansione spettrale è ben accettabile e si ottengono spettri a forma di linea di buona qualità. Tuttavia, dobbiamo considerare che la funzione finestra riduce l’ampiezza del segnale. Come fattore finestra, possiamo approssimare utilizzando il valore medio aritmetico dei valori della funzione finestra, come nel seguente elenco.
float getWindowFactor() {
float mean=0;
for (k=0; k < N ; k++) {
mean += abs(windowFun(k));
}
return mean/N ;
}
Per compensare la riduzione dell’ampiezza, dividiamo lo spettro per il fattore finestra dopo aver calcolato la FFT. Quando si utilizza una funzione finestra, l’identità di Parseval non si applica più.
Configurazione di campionamento e risoluzione
L’analizzatore di spettro offre diverse opzioni configurabili. Nel caso più semplice, il µC campiona il segnale, calcola lo spettro, lo visualizza e ripete questo processo all’infinito. Il tasso di campionamento fs è pari alla frequenza di campionamento. Allo stesso tempo, definisce l’intervallo di frequenza dello spettro perché in principio va da 0 a fs / 2. Quindi, a 500 kS/s, possiamo analizzare componenti di frequenza fino a 250 kHz. La lunghezza del segnale N determina quanti campioni vengono utilizzati per lo spettro e definisce la risoluzione della FFT. Due linee spettrali adiacenti (chiamate bin) hanno una distanza Δ = fs / N. A 500 kS/s e N = 1024, la risoluzione è Δ = 500 kHz / 1024 ≈ 488 Hz. È sufficiente per elaborare i segnali RF trasmessi.
Esempi pratici: DCF77 e la funzione MAXHOLD
Nell’analisi dei segnali con componenti di rumore, gli spettri individuali sono spesso molto irregolari. Questo può essere migliorato facendo la media su spettri successivi. Questa procedura è attivata dall’opzione “MEAN” del software dell’analizzatore, che, tra l’altro, può essere scaricato gratuitamente dal sito Elektor per questo articolo al (https://www.elektormagazine.com/magazine/elektor-312/62150). Lo spettro del trasmettitore del segnale orario DCF77 può essere usato per vedere quanto sia vantaggiosa la media. Qui, la frequenza di campionamento è 250 kHz e N è 16,384. La Figura 8 mostra lo spettro risultante nell’intervallo di ±5 kHz intorno alla frequenza centrale di 77.5 kHz.

La sottile linea bianca mostra uno spettro singolo chiaramente rumoroso. La media (curva verde spessa) mostra che il DCF77 ha uno spettro altrettanto rumoroso. Questo perché il DCF77 trasmette i dati con rumore pseudo-casuale a una frequenza di bit di 77.5 kHz / 120 ≈ 645.8 Hz, oltre alla modulazione di ampiezza (molto stretta in banda). La larghezza di banda di ±645.8 Hz è rappresentata dalle due linee verticali. Successivamente, viene analizzato lo spettro del trasmettitore EFR (129.1 kHz). EFR trasmette dati RTTY con uno spostamento di ±170 Hz e una velocità di trasmissione dati di 200 Bd. Quindi, due linee spettrali dovrebbero essere visibili nello spettro a 128.93 kHz e 129.27 kHz. Tuttavia, poiché vengono inviati solo brevi messaggi con lunghi intervalli tra essi, la frequenza di +170 Hz appare solo raramente ed è quindi difficile da rilevare. A questo scopo, il software offre la funzione MAXHOLD, in cui il massimo degli spettri viene calcolato su molti spettri. In questo modo, i componenti spettrali che si verificano brevemente a 129.27 kHz sono più evidenti (vedi Figura 9).

Rilevare segnali brevi con MAXHOLD
La sottile linea bianca è uno spettro singolo. Poiché al momento non viene inviato alcun messaggio, è visibile solo il picco a 128.93 kHz. Lo spettro MAXHOLD è rappresentato dalla curva verde più spessa. I due picchi a 129.1 kHz ±170 Hz (alle linee verticali tratteggiate) sono chiaramente visibili. Per ottenere uno spettro così finemente risolto, sono necessari molti campioni con N = 16,384. Il tasso di campionamento è 500 kHz e quindi la risoluzione è Δ = 500 kHz / 16,384 ≈ 30.5 Hz. Quindi, le due linee spettrali sono solo a circa 11 campioni di frequenza l’una dall’altra.
Dominio del Tempo (Funzione dell’Oscilloscopio)
Naturalmente, il segnale nel dominio del tempo è informativo, anche solo per controllare quanto è utilizzato l’intervallo di acquisizione dell’ADC. Anche il software può farlo, semplicemente visualizzando il segnale campionato. La Figura 10 mostra una sorta di oscillogramma del segnale DCF77 a 77.5 kHz.

Poiché sono di particolare interesse qui le cadute del portante che avvengono ogni secondo, è consigliabile selezionare un tasso di campionamento più basso e un numero maggiore di campioni. Per la rappresentazione nella Figura 10, sono stati scelti fs = 4 kHz e N = 16,384. La finestra temporale ha quindi una dimensione di Ts = N/fs ≈ 4 s, con conseguenti quattro cadute del portante nella Figura 10. Il segnale a 77.5 kHz è fortemente sottocampionato, ma questo non è un problema, poiché qui è rilevante solo l’ampiezza.
Sottocampionamento e frequenze alias
Secondo il teorema del campionamento, i segnali da analizzare possono contenere frequenze fino a un massimo della metà del tasso di campionamento. È necessario rispettare questa condizione oppure aggiungere un opportuno filtro passa-basso prima dell’ADC. Fino a questo punto, non è stato suggerito alcun filtro adeguato poiché dipende sempre dall’applicazione specifica. È interessante studiare anche le condizioni quando si analizzano frequenze più elevate. Se campioniamo i segnali con impulsi infinitamente brevi (pulsazioni di Dirac), otteniamo uno spettro periodico con una larghezza pari al tasso di campionamento. Le linee spettrali contenute nel segnale vengono quindi periodicamente ripetute con una larghezza fs. Di conseguenza, le frequenze più grandi di fs compaiono anche nello spettro. Vengono “piegate” nell’intervallo fondamentale, per così dire. Se la distanza di campionamento è maggiore, le frequenze più elevate vengono attenuate più fortemente. Le relazioni sono illustrate nell’esempio seguente dove è stato utilizzato un tasso di campionamento fs di 500 kHz per analizzare un segnale a onda quadra con una frequenza di 225 kHz e un ciclo di lavoro del 10%. Nello spettro nella Figura 11, l’onda fondamentale a 225 kHz appare più a destra e ha il livello più alto.

Filtrare le frequenze alias
L’armonica fondamentale (k = 2) ha la frequenza 2 * 225 kHz = 450 kHz, che è già oltre fs / 2. A causa della simmetria, appare quindi a f = 500 kHz – 450 kHz = 50 kHz nello spettro sotto la linea verticale tratteggiata “2” con un’amplitude ancora considerevole. La frequenza per q è pari a 225 kHz * 9 = 2025 kHz. Poiché questo è equivalente a 4 * 500 kHz + 25 kHz, questo picco a 25 kHz appare molto a sinistra dello spettro sotto la linea del cursore etichettata “9”. Gli indici della linea del cursore k = 1…9 rappresentano le posizioni teoricamente attese degli armonici del segnale analizzato con frequenze di k * 225 kHz, note come “frequenze alias”. Anche se le frequenze superano i 2 MHz, dieci picchi compaiono nella finestra fino a 250 kHz. Ciò significa che l’ADC può gestire certamente frequenze più alte di fs / 2. Questo effetto è utilizzato in quello che è noto come sotto-campionamento. Prima del campionamento, il segnale può essere filtrato da un filtro passa-banda con una banda passante di fs / 2 in modo che vengano catturate solo le aree rilevanti dello spettro. A tal fine, potremmo aggiungere una funzione sample-and-hold alla configurazione, per poter comunque elaborare le alte frequenze con l’ADC. Se questo effetto interferisse, tuttavia, il segnale verrebbe filtrato con un filtro passa-basso (filtro anti-aliasing) per sopprimere le componenti del segnale ad alta frequenza prima del campionamento.
Filtro Anti-aliasing
L’effetto di un filtro passa-basso anti-aliasing è illustrato di seguito. Qui, un segnale a onda quadra simmetrica con 225 kHz e un ciclo di lavoro del 50% viene filtrato attraverso il filtro passa-basso mostrato in Figura 12 prima dell’ADC. Il filtro è stato simulato con LTspice (https://www.analog.com/en/design-center/design-tools-and-calculators/ltspice-simulator.html) e costruito con amplificatori operazionali del tipo OPA2350. Si può chiaramente vedere nello spettro del segnale filtrato mostrato in Figura 13 che gli armonici sono fortemente attenuati e che solo l’onda fondamentale a 225 kHz spicca chiaramente sopra i -40 dBm. Tuttavia, il nostro filtro attenua già abbastanza pesantemente a 225 kHz. Quindi, un filtro con pendenze più ripide sarebbe più ideale.


Rumore bianco generato via software
Finora sono stati analizzati solo segnali composti da singole oscillazioni sinusoidali di diverse frequenze e ampiezze. Nella pratica, tuttavia, ci sono anche segnali di rumore con diverse larghezze di banda. Il loro trattamento in termini di ingegneria delle comunicazioni non è esattamente banale, motivo per cui vengono descritti solo casi semplici. Come esempio, vengono generati valori di rumore nk con un’ampiezza di A per il rumore binario con una frequenza di rumore fn. In ogni caso, i determina a caso se applicare sk = +A o sk = -A per il valore successivo. Inizialmente, vale fn = 1 MHz, in modo che i valori vengano generati più velocemente di quanto l’ADC possa campionarli. Di conseguenza, i campioni sono indipendenti l’uno dall’altro e il valore è ±A in ogni caso. Di conseguenza, il segnale di rumore è quasi “bianco”, il che significa che tutte le frequenze si presentano ugualmente nel suo spettro. Il segnale è generato tramite software sul Raspberry Pi Pico. Per consentire a questo compito di funzionare in parallelo con il software dell’analizzatore di spettro, utilizza il secondo core della CPU RP2040. È implementato utilizzando una macchina a stati, che consente di generare fino a 125 Mb/s. Di solito viene utilizzato il valore RMS della tensione di rumore. Poiché il segnale non è periodico, non possiamo utilizzare formalmente la formula per il valore RMS. Tuttavia, per un gran numero di campioni M, il valore RMS può essere approssimato con:

Misurare il livello del rumore nello spettro
Sarà distribuito uniformemente su wk. Per semplicità, si presume che tutti i wk siano uguali per dimensione e pari a w. Mettendo tutto insieme, otteniamo: w2 = 4 RMS2n / N. Qui, w è esattamente la potenza cercata del segnale di rumore nello spettro. Nella Figura 15, questo livello può essere visto come una linea viola spessa.

È effettivamente una buona previsione del reale livello di rumore. Diventa anche chiaro perché questo livello diminuisce con N più grandi: è perché l’energia del rumore è distribuita su più linee spettrali.
Rumore a banda limitata
Nel prossimo esempio, la frequenza di bit della sorgente di rumore è ridotta a fn = 25 kHz. Pertanto, 20 campioni successivi sono sempre uguali, il che equivale a una sorta di filtraggio passa-basso. Lo spettro risultante è mostrato nella Figura 16.

La linea sottile rossa mostra di nuovo una funzione singola. Lo spettro medio è mostrato in verde. Il primo punto di zero dello spettro è a 25 kHz. Lo spettro è proporzionale a H(f) = si(π f / fN); dove si(x) = sin(x) / x è ciò che è noto come funzione gap. Semplificando, si può calcolare il livello intorno a 0 come segue: la larghezza di banda è approssimativamente fBW = 12,5 kHz, che equivale a kBW = N fBW / fs = 25 linee spettrali. Se lo spettro ha una larghezza di banda costante di w, si ottiene l’equazione RMS2w = 2 kBW w2 / N per i valori RMS sommando le linee spettrali all’interno della larghezza di banda. Il fattore 2 è necessario perché la FFT fornisce uno spettro simmetrico con le linee spettrali N – kBW a N. Utilizzando l’identità di Parseval, la potenza spettrale w viene calcolata come segue: w2 = 2 RMS2n / kBW. È mostrato nella Figura 16 dalla linea viola spessa e si adatta abbastanza bene allo spettro attuale.
ENOB e range dinamico
Il prossimo esempio è leggermente più pratico: l’ADC riceve ora il segnale di un generatore di segnali sinusoidali con un’ampiezza di 3 VSS (circa 14 dBm). La frequenza del segnale di fs = 48.828 kHz corrisponde esattamente alla 100a linea spettrale. La Figura 17 mostra lo spettro risultante.

La linea spettrale a fs è evidente e ha anche la dimensione corretta. A 2 fs, possiamo vedere l’armonica causata dal generatore di segnali con un livello di circa 45 dB sotto il segnale. Sono visibili numerose piccole linee spettrali, poiché i componenti non sono ideali e presentano piccole non linearità. Anche il livello di rumore è interessante. Possiamo chiaramente vedere dallo spettro medio (verde) che è di circa -65 dBm. Con la formula data sopra, possiamo convertire il livello nella tensione efficace del rumore di circa 2 mVRMS (circa 5 mVSS). La risoluzione dell’ADC è 3.3 V / 4096 = 0.8 mV. Il rumore quindi copre circa sei livelli di quantizzazione. Più di 2 bit vengono quindi persi a causa del rumore. Tuttavia, i picchi spettrali con -55 dBm spiccano ancora bene rispetto al rumore. Il range dinamico è quindi almeno 14 dBm – (-55 dBm) = 69 dB – un fattore di ≈2800. La reale risoluzione o l’ENOB (numero effettivo di bit) dell’ADC raggiunge più di 11 grazie alla media, il che non è affatto male. A proposito, gli esperimenti sul rumore sono stati fatti senza finestre in modo che i livelli siano mantenuti esattamente e sia applicabile l’identità di Parseval.
Preamplificatore con ingresso da 1 MΩ
Gli oscilloscopi di solito hanno una resistenza di ingresso di 1 MΩ. Questo significa che normalmente non introducono un carico significativo durante la misura e consentono l’uso delle sonde 1:1 e 10:1 abituali. Questa comodità dovrebbe essere offerta anche da un analizzatore di spettro, ecco perché è stato progettato il preamplificatore mostrato nella Figura 18.

L’Opamp IC1A funge da convertitore di impedenza. L’impedenza di ingresso è determinata da R7. IC1B funge da preamplificatore con un guadagno di 1 o 10 selezionabile tramite JP1. IC1A deve avere una bassa corrente di polarizzazione, altrimenti questa corrente a R7 causerebbe una caduta di tensione troppo grande, spostando quindi la linea zero del segnale lontano dal centro della gamma di acquisizione dell’ADC. Ad esempio, il modello AD8042 con la sua corrente di polarizzazione IB = 1.2 µA comporterebbe uno spostamento dell’offset di 1.2 µA * 1 MΩ = 1.2 V. Con C4, può essere realizzata un’adattamento a una sonda, se necessario. La Figura 19 mostra il prototipo realizzato su una breadboard insieme alla scheda Pico e al display.

Clock ADC e frequenza di campionamento
Secondo il datasheet, il clock ADC deve essere di 48 MHz. Questo clock è normalmente generato dalla PLL USB. Il prescaler a 16 bit non è attivo in questo caso (divisione per 1). L’ADC lavora in modalità di free-running, in cui acquisisce e fornisce continuamente i valori. Il timing è generato da un contatore ADC che è triggerato dal clock ADC. Il contatore ADC va in overflow al valore ADCclkDiv e quindi retriggera l’ADC. Poiché una conversione richiede 96 impulsi di clock, deve essere soddisfatta la condizione ADCclkDiv ≥ 96. Al valore più piccolo di ADCclkDiv = 96, otteniamo la massima frequenza di campionamento di fs = 48 MHz / 96 = 500 kHz. Il contatore ADC è un contatore frazionario 16.8: la parte intera è larga 16 bit e si può dividere in frazioni per 8 bit per produrre frequenze di campionamento anche non comuni nel modo più preciso possibile. La frequenza di campionamento più lenta è fs = 48 MHz / 65,536 = 732 Hz.
Campionamento a 1 MHz oltre le specifiche
Nel prossimo esperimento, l’ADC lavora molto al di fuori delle specifiche per una frequenza di campionamento di 1 MHz. Per questo, il clock ADC deve essere di 96 MHz. Il clock PLL USB con i suoi 48 MHz non è sufficiente. L’ADC è quindi sincronizzato dalla PLL per il clock di sistema SYS-PLL. Il tasso di clock generato per il processore è normalmente di 125 MHz. Tuttavia, se è impostato a 96 MHz, può essere usato per sincronizzare direttamente l’ADC e abilitare una frequenza di campionamento di 1 MHz. Sfortunatamente, il processore funziona circa il 23% più lentamente. Tuttavia, questo non è un problema, perché il software non sfrutta completamente la capacità della CPU. Viene utilizzato un segnale sinusoidale a 400 kHz con un’ampiezza di 2 VSS come segnale di test. La Figura 20 mostra lo spettro risultante.

Il segnale utile è mostrato con il livello corretto nella posizione corretta. Tuttavia, l’armonica prima a 800 kHz viene abbassata a 1 MHz – 800 kHz = 200 kHz. Il livello di rumore di -65 dBm non è peggiore rispetto a una frequenza di campionamento di 500 kHz. Quindi, non sembrano esserci obiezioni serie contro il clock dell’ADC a 96 MHz.
LCD
Poiché spesso sono di interesse i dettagli fini negli spettri, è stato scelto il MAR3502 Arduino Shield grazie alla sua risoluzione relativamente alta di 320×480 pixel. È collegato in parallelo alla scheda Pico come mostrato nella Figura 21.

Ciò consente di configurare un analizzatore di spettro come dispositivo stand-alone, ma mancano comunque i controlli. La Figura 20 mostra lo spettro di un segnale audio multiplex FM sul display. Si può chiaramente vedere il segnale mono (L+R) nella gamma a 17 kHz. A 19 kHz, appare la linea spettrale del tono pilota stereo. A 38 kHz, è visibile lo spettro del segnale di differenza stereo (L – R). A 57 kHz, è visibile lo spettro del segnale RDS, che consiste in due bande laterali intorno a 57 kHz.
ADC esterno da 12 bit e 50 MS/s
Per frequenze più basse, il tasso di campionamento di 500 kHz dell’ADC integrato nel RP2040 è sufficiente. Ma per la gamma delle frequenze radio, la scheda Pico può essere estesa con un ADC esterno utilizzando il chip ADS807E. Con questo ADC da 12 bit, è possibile raggiungere fino a 53 MS/s. Per verificare gli spettri, è necessaria molta potenza di calcolo e quindi utilizzeremo alcuni trucchi per raggiungere questa alta frequenza di campionamento. L’ADS807E fornisce una tensione di riferimento integrata. L’ADC è collegato alla scheda Pico come mostrato nella Figura 22.

A causa del collegamento parallelo, molti pin GPIO sono occupati, quindi sfortunatamente non è possibile collegare contemporaneamente l’LCD. Per questo motivo, l’ADS807 utilizza una seconda scheda Pico. Durante i primi esperimenti, i dati vengono elaborati e visualizzati utilizzando il PC come all’inizio. Diversi front-end analogici possono essere collegati a K2, che vengono presentati di seguito. La Figura 23 mostra la configurazione di test di una scheda Pico con un ADS807 e un front-end a trasformatore da 50 Ω.

A proposito: se l’ADS807 è troppo costoso o non hai bisogno dei suoi 12 bit, puoi utilizzare un ADC economico a 8 bit come l’ADS830E, ad esempio; offre frequenze di campionamento fino a 60 MS/s e richiede solo una routine di campionamento adattata.
Campionamento rapido tramite PIO, FIFO e DMA
Il processore RP2040 è normalmente sincronizzato a 125 MHz. Il seguente elenco mostra il ciclo minimo per acquisire N valori di dati con esso:
for (k = 0; k < N; k++) {
sampleBuffer[k] = gpio_get_all();
gpio_put(ADCclock,0);
gpio_put(ADCclock,1);
}
Secondo le mie misurazioni, il processore RP2040 raggiunge al massimo 15 MS/s, ancora molto lontano dai 53 MS/s di un ADS807. Tuttavia, il processore ha un’unità di input-output periferica (PIO), che consiste in otto macchine a stati programmabili. Queste macchine a stati possono essere controllate con il clock del processore e programmate con comandi semplici. Di seguito vengono evidenziati alcuni aspetti dell’applicazione di campionamento. I dettagli completi sono piuttosto complessi, quindi consulta la documentazione RP2040 (https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf) per questo. Il programma PIO consiste solo di due comandi:
.wrap_target
in pins,12 side 0b0
nop side 0b1
.wrap
Le parole chiave .wrap_target e .wrap fanno sì che i due comandi tra di esse vengano eseguiti continuamente uno dopo l’altro. Il loop stesso non comporta alcun overhead nel processo. Il comando in fa sì che 12 bit vengano spostati dall’ADC nel ISR (input shift register). Come sappiamo, l’istruzione nop non fa nulla. Dopo ogni istruzione viene utilizzata l’opzione side. Con questa, è possibile influenzare i pin GPIO in parallelo al comando PIO effettivo. In questo modo, il clock ADC è generato su GPIO14. Poiché ogni istruzione richiede un ciclo, questo programma può, in linea di principio, processare 125/2 MS/s. Questo è sufficiente per l’ADS807.
Configurazione del DMA e prestazioni finali
Oltre al programma effettivo, la configurazione della macchina a stati gioca un ruolo importante. Definisce, ad esempio, quali pin sono influenzati da side-set. Inoltre, è stata configurata in modo che, dopo ogni due campioni (quando sono arrivati 24 bit nel ISR), il valore ISR venga scritto in un FIFO di output. I dati vengono scritti rapidamente nella memoria tramite DMA (direct memory access). Il campionamento effettivo avviene quindi autonomamente. Il processore deve solo recuperare i valori dal buffer dopo ogni trasferimento DMA. In linea di principio, lo stesso software utilizzato per l’ADC ADS807 può essere utilizzato anche per l’ADC integrato. È necessario solo adattare la routine di campionamento. Per raggiungere la massima frequenza di campionamento di 53 MHz, ad esempio, è possibile configurare un clock del processore di 106 MHz e impostare il prescaler PIO su 1. Ora, il programma PIO viene eseguito a 106 MHz. Poiché ogni campione richiede due clock, la frequenza di campionamento è esattamente di 53 MHz. Purtroppo, il processore lavorerà circa il 15% più lentamente. Tuttavia, questo è sufficiente per eseguire senza problemi i compiti necessari. La Figura 24 mostra lo spettro di un segnale di onda quadra con un ciclo di lavoro del 10% a una frequenza di campionamento di 50 MHz.

Le armoniche fino a 25 MHz sono chiaramente visibili. A causa del ciclo di lavoro del 10%, manca la decima armonica. Attraverso il sottocampionamento, è ancora possibile analizzare componenti del segnale fino a circa 200 MHz utilizzando l’ADS807 senza problemi.
Front-end analogici: caratteristiche generali
Gli ingressi differenziali +IN e -IN dell’ADS807E hanno un elevato rapporto segnale-rumore anche a frequenze più elevate. Tuttavia, il chip è leggermente più difficile da gestire rispetto agli ADC con ingresso sbilanciato. I possibili front-end che possono essere collegati a K2 nella Figura 22 sono descritti di seguito. La gamma dinamica dell’ADS807 è di 2 VSS, con una risoluzione di 2 V / 4096 = 480 µV.
Front-end 1: single-ended
Nel caso più semplice, si ignora l’ingresso differenziale, si imposta -IN a CM (Common Mode) e si alimenta semplicemente il segnale a +IN. Si lavora quindi con accoppiamento AC, e l’offset DC di 2,5 V è fornito da CM (Figura 25). Se si desidera avere un’impedenza di ingresso di 50 Ω, è possibile collegare semplicemente un resistore da 50 Ω in parallelo all’ingresso K2.

Front-end 2: accoppiamento a trasformatore con 50 Ω
Utilizzando un trasformatore RF con tre avvolgimenti strettamente accoppiati con lo stesso numero di spire, è possibile ottenere un semplice utilizzo dell’ingresso differenziale. Il prototipo utilizzava un induttore comune di modo comune da 4,7 mH con quattro avvolgimenti, di cui ne vengono utilizzati solo tre (Figura 26).

L’induttore blu della Siemens è chiaramente visibile nella Figura 23. Un avvolgimento alimenta ciascuno degli ingressi +IN e -IN con fasi opposte. Gli avvolgimenti hanno ciascuno una resistenza parallela di 100 Ω. L’accoppiamento 1:1 trasforma queste resistenze in due resistori da 100 Ω collegati in parallelo sul lato primario, con un’impedenza di ingresso di 50 Ω. Poiché l’ADC vede il doppio della tensione di ingresso, questo comporta un fattore di amplificazione di 2. Allo stesso tempo, l’ingresso è isolato elettricamente dall’ADC, evitando interferenze in modo comune. Il circuito è adatto per misurazioni su sistemi a 50 Ω. Se vuoi realizzare il trasformatore L1, dovresti avvolgere i tre avvolgimenti in modo trifilare (cioè un avvolgimento con tre fili avvolti insieme) per ottenere un buon accoppiamento anche a frequenze elevate. Il nucleo dovrebbe avere un’alta permeabilità anche a frequenze fino a 25 MHz.
Front-end 3: preamplificatore da 25 MHz con 1 MΩ
Per determinate misurazioni, anche un analizzatore di spettro veloce richiede un’ingresso ad alta impedenza. Questo consente l’uso delle consuete sonde per oscilloscopi 10:1. La Figura 27 mostra il circuito di un preamplificatore adatto.

L’opamp IC1A funge da convertitore di impedenza con una resistenza di ingresso di 1 MΩ a causa di R5. Il tipo OPA2350 non solo è veloce, ma ha anche una bassa corrente di polarizzazione e un basso rumore di ingresso. IC2A e IC2B fungono da driver bipolari per l’ADC. Poiché l’ingresso unipolare viene convertito in un segnale differenziale, ne risulta un fattore di amplificazione di due. IC2 è stato selezionato considerando l’ampia larghezza di banda in modo che la differenza di fase tra +IN e -IN rimanga il più piccola possibile. R2 e R4 sono utilizzati per la stabilità di questi opamp. IC1B bufferizza la tensione di offset di 2,5 V. La Figura 28 mostra, tra le altre cose, la configurazione del front-end su una breadboard.

Rumore
Certi sorgenti di rumore rendono difficile la vita di un progettista di circuiti. A R5, ad esempio, si verifica una tensione di rumore termico di UN, RMS = √(4 kB T B R), dove kB è la costante di Boltzmann, T è la temperatura assoluta (in Kelvin), B è la larghezza di banda (qui 25 MHz) e R è il valore di R5 (1 MΩ). Questo si traduce in una tensione di rumore effettiva di 6,3 mV. Questo è diverse volte la risoluzione dell’ADC, e il livello di rumore è fortemente evidente nelle misurazioni ad alta impedenza e banda larga. Questo spiega anche perché un sistema a bassa impedenza, ad esempio di 50 Ω, è più vantaggioso per le radiofrequenze. La corrente di ingresso di un OPA2350 ha una densità di rumore di 4 fA / √Hz. Questo si traduce in una tensione di rumore efficace trascurabile di 20 µV a R5 a una larghezza di banda di 25 MHz. Per il rumore di tensione di ingresso, è specificata una densità di 7 V / √Hz. Questo si traduce in una tensione di rumore di 30 µV a 25 MHz, anch’essa trascurabile. Tuttavia, diventa chiaro come i parametri di rumore dell’opamp influenzino il design. Ad esempio, l’AD8042 ha una corrente di rumore di 500 fA / √Hz ed è quindi inadatto come convertitore di impedenza all’ingresso.
Visualizzazione grafica
Come già menzionato, non è possibile collegare contemporaneamente l’ADC esterno e l’LCD a causa della mancanza di pin GPIO. Per un dispositivo autonomo, questa mancanza viene compensata utilizzando due schede Pico separate: una per l’acquisizione di dati dall’ADC esterno e una per l’LCD. Quest’ultima funge da terminale grafico che può eseguire autonomamente varie funzioni di base come disegnare linee e rettangoli, nonché output di testo. Sulla scheda Pico con l’ADS807, sono implementate le funzioni dell’analizzatore di spettro. Per l’output grafico, questa parte invia comandi corrispondenti al terminale grafico tramite l’interfaccia seriale. A un prezzo di pochi dollari per una scheda Pico, questo design a doppia scheda è economicamente giustificato. La Figura 28 mostra come potrebbe apparire questa soluzione con due schede Pico. Il display mostra lo spettro di un segnale di onda quadra da 1 MHz a una frequenza di campionamento di 50 MS/s. Gli armonici diventano rapidamente più piccoli con l’aumentare dell’ordine.


