Introduzione
Generatore di segnali con ESP32 e modulo DDS AD9833. Nel nostro precedente progetto descritto dall’articolo Guida alla realizzazione di un semplice generatore di segnali con ESP32, abbiamo costruito un generatore di segnali semplice utilizzando un ESP32, capace di generare onde sinusoidali, quadre e triangolari. Questo progetto ha dimostrato come l’ESP32 possa essere utilizzato per creare segnali variabili utili per testare e sviluppare circuiti elettronici. Tuttavia, il generatore basato solo su ESP32 ha alcune limitazioni, soprattutto in termini di precisione e frequenza massima raggiungibile. Nasce quindi l’esigenza di trovare una alternativa per realizzare un generatore di segnali più performante ed utile nel laboratorio dell’hobbista.
Per superare questi limiti e creare un generatore di segnali più versatile e preciso, utilizzeremo il modulo DDS (Direct Digital Synthesis) AD9833. Il modulo AD9833 è in grado di generare segnali con frequenze molto più alte e con una maggiore precisione rispetto all’ESP32 da solo. Questo ci permetterà di espandere notevolmente le capacità del nostro generatore di segnali, rendendolo adatto a una più ampia gamma di applicazioni, dalla prototipazione di circuiti elettronici al loro test.
In questo articolo, esploreremo come integrare il modulo DDS AD9833 con l’ESP32, illustrando passo passo il processo di configurazione, collegamento e programmazione. Alla fine del progetto, avremo un generatore di segnali avanzato capace di produrre onde sinusoidali, quadre e triangolari con frequenze variabili, superando le limitazioni del progetto precedente. Seguici in questo viaggio per scoprire come costruire un generatore di segnali potente e versatile con ESP32 e DDS AD9833.
Come al solito utilizzeremo l’IDE PlatformIO per scrivere il codice.
Introduzione alla Sintesi Digitale Diretta (DDS)
La Sintesi Digitale Diretta (DDS) è una tecnologia utilizzata per generare forme d’onda analogiche attraverso metodi digitali. È ampiamente utilizzata in applicazioni di radiofrequenza, strumenti di misura, e in dispositivi che richiedono segnali di alta precisione e stabilità. La DDS consente la creazione di segnali con frequenze molto precise, che possono essere facilmente variate tramite controlli digitali.
Principi di funzionamento della DDS
Componenti principali
- Phase accumulator: è il cuore del sistema DDS. Un registro accumula incrementi di fase a ogni ciclo di clock, creando una rampa di fase che determina la frequenza del segnale in uscita.
- Phase-to-Amplitude Converter (Look-Up Table): utilizza la rampa di fase per accedere a una tabella di ricerca (LUT) che converte la fase in un valore di ampiezza corrispondente alla forma d’onda desiderata (ad esempio, sinusoidale).
- Digital-to-Analog Converter (DAC): converte i valori digitali di ampiezza in segnali analogici.
- Low-Pass Filter: utilizzato per rimuovere componenti ad alta frequenza indesiderate dal segnale DAC, producendo un segnale analogico pulito.
Processo di sintesi
- Generazione della fase: il phase accumulator somma costantemente un valore di incremento della fase ad ogni ciclo di clock. Questo valore di incremento determina la frequenza del segnale in uscita.
- Conversione della fase in ampiezza: la fase accumulata viene utilizzata per accedere a una LUT che converte la fase in un valore di ampiezza corrispondente. La LUT è preprogrammata con i valori della forma d’onda desiderata (ad esempio, i valori di una sinusoide).
- Conversione Digitale-Analogica: i valori di ampiezza digitali vengono convertiti in segnali analogici tramite il DAC.
- Filtraggio: un filtro passa-basso rimuove eventuali componenti di alta frequenza, lasciando un segnale analogico pulito e stabile.
Vantaggi della DDS
- Precisione e stabilità: la DDS offre un controllo preciso della frequenza del segnale con una stabilità eccezionale, poiché la frequenza è determinata digitalmente.
- Flessibilità: è possibile generare una varietà di forme d’onda semplicemente modificando la LUT o il valore di incremento della fase.
- Velocità di settling: i cambiamenti di frequenza sono quasi istantanei, rendendo la DDS ideale per applicazioni che richiedono frequenze variabili.
- Basso costo e dimensioni ridotte: i sistemi DDS possono essere implementati in hardware relativamente economico e compatto rispetto ad altre tecniche di generazione di frequenza.
Applicazioni della DDS
- Comunicazioni RF: utilizzata per la modulazione e demodulazione di segnali.
- Strumenti di misura: generazione di segnali di test precisi.
- Sistemi audio: sintesi di suoni in applicazioni musicali e audio.
- Radar e navigazione: generazione di segnali per sistemi radar e di navigazione.
La DDS rappresenta una tecnologia potente e versatile per la generazione di segnali di alta qualità, trovando impiego in una vasta gamma di applicazioni tecnologiche avanzate.
Il Modulo AD9833: caratteristiche e funzionamento
Il modulo AD9833 è un generatore di segnali programmabile DDS (Direct Digital Synthesis) prodotto da Analog Devices. È progettato per generare segnali sinusoidali, triangolari e quadri, ed è ampiamente utilizzato in applicazioni di radiofrequenza, strumenti di misura e sistemi di comunicazione.
Caratteristiche principali
- Frequenza di clock: l’AD9833 può operare con un clock di ingresso fino a 25 MHz, permettendo la generazione di segnali con frequenze fino a circa 12.5 MHz.
- Forme d’onda: è in grado di generare onde sinusoidali, triangolari e quadre, con una semplice selezione tramite comandi digitali.
- Risoluzione di frequenza: ha una risoluzione di 28 bit per la sintesi di frequenza, consentendo una precisione di frequenza molto elevata.
- Interfaccia SPI: utilizza una semplice interfaccia SPI a tre fili per la configurazione e il controllo, facilitando l’integrazione con microcontrollori come l’ESP32.
- Basso consumo energetico: consuma poca energia, rendendolo ideale per applicazioni portatili e a basso consumo.
Funzionamento del modulo AD9833
L’AD9833 funziona utilizzando un accumulatore di fase che somma costantemente un valore di incremento determinato dalla frequenza desiderata. Questo accumulatore di fase fornisce un indirizzo per una tabella di look-up che converte la fase accumulata in un valore di ampiezza corrispondente alla forma d’onda desiderata. Questo valore di ampiezza viene quindi convertito in un segnale analogico tramite un convertitore digitale-analogico (DAC) integrato nel modulo.
Vantaggi dell’AD9833
- Precisione elevata: grazie alla sua risoluzione di 28 bit, l’AD9833 offre una precisione di frequenza molto alta.
- Flessibilità: può generare diverse forme d’onda, rendendolo versatile per molteplici applicazioni.
- Facilità d’uso: l’interfaccia SPI a tre fili semplifica la connessione e la configurazione con microcontrollori.
- Compattezza: le dimensioni ridotte del modulo lo rendono adatto per progetti dove lo spazio è limitato.
Applicazioni tipiche
L’AD9833 trova applicazione in vari campi, tra cui:
- Comunicazioni RF: per la modulazione e demodulazione di segnali.
- Strumenti di misura: per generare segnali di test precisi.
- Sistemi audio: nella sintesi di suoni.
- Radar e navigazione: per la generazione di segnali utilizzati in sistemi radar e di navigazione.
L’AD9833 è un componente versatile e potente che permette di creare generatori di segnali avanzati con alta precisione e flessibilità, rendendolo una scelta ideale per una vasta gamma di applicazioni elettroniche avanzate.
Il generatore di segnali sweepato
Dato che il nostro progetto è in grado di generare onde sia a frequenza fissa che variabile (oscillatore sweepato), spendiamo due parole sulla utilità di questa modalità di funzionamento. Un generatore di segnali sweepato, o generatore di sweep, è un dispositivo che produce un segnale il cui parametro di frequenza varia in modo continuo o discreto all’interno di un intervallo predefinito. Questa variazione della frequenza, detta sweep, può avvenire linearmente o logaritmicamente e viene utilizzata per analizzare la risposta in frequenza di circuiti, dispositivi o sistemi.
Come funziona
Un generatore di sweep cambia sistematicamente la frequenza del segnale in uscita. Questo può essere realizzato in modo manuale o automatizzato attraverso controlli elettronici. I parametri principali di uno sweep sono la frequenza iniziale, la frequenza finale, la velocità di sweep (quanto rapidamente la frequenza cambia) e il tipo di sweep (lineare o logaritmico).
Utilità e applicazioni
- Analisi di risonanza: utilizzato per trovare la frequenza di risonanza di componenti e circuiti, come filtri e antenne.
- Caratterizzazione dei filtri: permette di tracciare la risposta in frequenza di un filtro e determinare bande passanti e taglio.
- Test di amplificatori: verifica la risposta in frequenza e l’amplificazione a diverse frequenze.
- Diagnostica dei circuiti: aiuta a identificare problemi come oscillazioni non desiderate o attenuazioni in specifiche bande di frequenza.
- Sistemi di comunicazione: usato per testare la risposta di sistemi di comunicazione a diverse frequenze operative.
Vantaggi
- Versatilità: può essere utilizzato in una vasta gamma di applicazioni.
- Precisione: fornisce una caratterizzazione accurata della risposta in frequenza.
- Efficienza: automatizza il processo di test, risparmiando tempo e riducendo errori manuali.
In sintesi, un generatore di segnali sweepato è uno strumento essenziale per l’analisi e il test di dispositivi elettronici, offrendo una panoramica completa della loro risposta in frequenza e aiutando a ottimizzare le prestazioni del sistema.
Il Modulo DDS AD9833 utilizzato in questo progetto
Nella foto seguente è visibile il modulo DDS AD9833 utilizzato in questo progetto:

Il modulo DDS AD9833 è un generatore di segnali digitali prodotto da Analog Devices, progettato per creare forme d’onda sinusoidali, quadre e triangolari. Questo specifico modulo utilizza il chip AD9833, che consente di generare segnali con frequenze fino a circa 12.5 MHz.
Caratteristiche principali
- Clock di riferimento: il modulo integra un oscillatore da 25 MHz, visibile come un rettanolo argentato sulla scheda.
- Uscite: due connettori SMA (nell’immagine sono protetti dai loro cappucci rossi), uno per l’uscita del segnale (VOUT) e uno per l’ingresso del clock esterno (MCLK).
- Connessioni: include header pin per VCC, GND, DAT (MOSI), CLK (SCK), e FSY (CS), facilitando la connessione con microcontrollori come l’ESP32.
Utilizzo
- Generazione di segnali: ideale per testare e sviluppare circuiti elettronici, generando segnali a frequenza fissa o variabile.
- Applicazioni RF: usato in applicazioni di radiofrequenza per la modulazione e demodulazione dei segnali.
Il modulo DDS AD9833 è una soluzione versatile per chiunque desideri esplorare la generazione di segnali ad alta precisione utilizzando un microcontrollore come l’ESP32.
La Libreria AD9833 di Rob Tillaart utilizzata in questo progetto
La libreria AD9833 di Rob Tillaart, disponibile su GitHub a questo indirizzo https://github.com/RobTillaart/AD9833, è progettata per facilitare l’interfacciamento del modulo DDS AD9833 con microcontrollori come l’ESP32. Questa libreria offre una serie di funzionalità che semplificano la generazione e la configurazione di segnali.
Funzionalità principali
- Interfaccia SPI: utilizza l’interfaccia SPI a tre fili per comunicare con il modulo AD9833, rendendo facile l’integrazione con vari microcontrollori.
- Generazione di segnali: supporta la generazione di forme d’onda sinusoidali, quadre e triangolari.
- Configurazione della frequenza: permette di impostare facilmente la frequenza del segnale generato con una risoluzione di 28 bit, garantendo alta precisione.
- Configurazione della fase: supporta l’impostazione della fase del segnale per applicazioni avanzate.
API e metodi principali
- begin(): inizializza la comunicazione SPI e configura il modulo AD9833.
- setFrequency(frequency, channel): imposta la frequenza del segnale sul canale specificato.
- setWave(waveType): configura il tipo di forma d’onda da generare (sinusoidale, quadra, triangolare).
- getFrequency(): restituisce la frequenza corrente del segnale generato.
- getWave(): restituisce il tipo di forma d’onda corrente.
La libreria AD9833 di Rob Tillaart è uno strumento potente e flessibile per chiunque desideri utilizzare il modulo DDS AD9833. Facilita la configurazione e la generazione di segnali, rendendo il processo semplice e accessibile anche per chi ha poca esperienza con la generazione di segnali digitali.
Di che componenti abbiamo bisogno per il nostro generatore di segnali con ESP32 e modulo DDS AD9833?
La lista dei componenti non è particolarmente lunga:
- una breadboard per connettere la NodeMCU ESP32 agli altri componenti
- alcuni fili DuPont (maschio – maschio, maschio – femmina, femmina – femmina)
- un modulo DDS AD9833 come quello descritto nel paragrafo “Il Modulo DDS AD9833 utilizzato in questo progetto”
- (opzionale) un frequenzimetro digitale per misurare con precisione la frequenza del segnale generato. Questo strumento può aiutarti a verificare che il generatore stia funzionando correttamente.
- (opzionale) un oscilloscopio, fondamentale per visualizzare l’onda generata.
- e, ovviamente, una NodeMCU ESP32 !
Il modello di ESP32 scelto per questo progetto è quello dell’azienda AZ-Delivery.
Realizzazione del progetto
Lo schema elettrico
Prima di realizzare il circuito vero e proprio diamo un’occhiata al pinout della board:


Come puoi osservare dall’immagine seguente, lo schema elettrico (realizzato con Fritzing) è molto semplice:

Per rendere più chiari i collegamenti ecco la tabella di collegamento tra l’alimentazione e i GPIO dell’ESP32 e il modulo DDS AD9833:
Modulo DDS | ESP32 Pin |
---|---|
VCC | 3V3 |
GND | GND |
DAT (MOSI) | GPIO 23 |
CLK (SCK) | GPIO 18 |
FSY (CS) | GPIO 5 |
VOUT | Oscilloscopio |
Schema di connessione
- VCC a 3V3: alimenta il modulo DDS con 3.3V dall’ESP32.
- GND a GND: collega il pin di massa del modulo DDS alla massa dell’ESP32.
- DAT a GPIO 23: collega il pin DAT (MOSI) del modulo DDS al pin GPIO 23 dell’ESP32.
- CLK a GPIO 18: collega il pin CLK (SCK) del modulo DDS al pin GPIO 18 dell’ESP32.
- FSY a GPIO 5: collega il pin FSY (CS) del modulo DDS al pin GPIO 5 dell’ESP32.
- VOUT all’Oscilloscopio: collega l’uscita VOUT al tuo oscilloscopio per monitorare il segnale generato.
Questi collegamenti ti permetteranno di configurare e utilizzare il modulo DDS AD9833 con il tuo ESP32 per generare vari tipi di segnali.
Creiamo il progetto PlatformIO
Abbiamo già visto la procedura di creazione di un progetto PlatformIO nell’articolo Come creare un progetto per NodeMCU ESP8266 con PlatformIO.
Anche se si riferisce alla board ESP8266, la procedura è simile.
Semplicemente, nella scelta della piattaforma, dovrai scegliere la AZ-Delivery ESP-32 Dev Kit C V4.
Non installare nessuna delle librerie indicate nell’articolo.
Ora modifica il file platformio.ini per aggiungere queste due righe:
monitor_speed = 115200
upload_speed = 921600
in modo che il file abbia un aspetto del genere:
[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = arduino
monitor_speed = 115200
upload_speed = 921600
e aggiungi la libreria AD9833 di Rob Tillaart in modo che il file abbia un aspetto del genere:
[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps =
https://github.com/RobTillaart/AD9833
Puoi scaricare il progetto dal link seguente:
decomprimerlo, prendere il file main.cpp e sostituirlo al posto di quello che hai nel progetto precedentemente creato.
Vediamo ora come funziona lo sketch.
Lo sketch inizia con l’inclusione delle librerie necessarie e un controllo che il microcontrollore usato sia effettivamente un ESP32:
#include <Arduino.h>
#include "AD9833.h"
#ifndef ESP32
#error ESP32 only example, please select appropriate board
#endif
Vengono poi definite le variabili fixed_freq che viene utilizzata per impostare la frequenza del segnale generato quando non si è in modalità sweep, la variabile booleana up che, in modalità sweep, determina se la frequenza generata debba salire o scendere, le variabili freq_sweep_max e freq_sweep_min che determinano la frequenza di arrivo e la frequenza di partenza nel caso di modalità sweep, la variabile sweep_freq che contiene il valore di frequenza correntemente generato in caso di modalità sweep e la variabile booleana sweep che attiva/disattiva la modalità sweep:
int fixed_freq = 1000;
bool up = true;
int freq_sweep_max = 1000;
int freq_sweep_min = 100;
int sweep_freq = 100;
bool sweep = false;
Seguono la istanziazione del bus SPI per il controllo del modulo DDS e dell’oggetto AD di tipo AD9833 che gestisce il modulo DDS:
// HSPI uses default SCLK=14, MISO=12, MOSI=13, SELECT=15
// VSPI uses default SCLK=18, MISO=19, MOSI=23, SELECT=5
SPIClass * myspi = new SPIClass(VSPI);
AD9833 AD(5, myspi);
// AD9833 AD(15, 13, 14); // SW SPI
Incontriamo poi la funzione setup. In essa viene attivata la porta seriale:
Serial.begin(115200);
delay(2000);
while(!Serial);
poi vengono stampate sul Serial Monitor delle informazioni sulla versione della libreria:
Serial.println(__FILE__);
Serial.print("AD9833_LIB_VERSION: ");
Serial.println(AD9833_LIB_VERSION);
Serial.println();
vengono inizializzati il bus SPI e l’oggetto AD che gestisce il modulo DDS:
myspi->begin();
AD.begin();
vengono settati la frequenza dell’oscillatore al quarzo interno al modulo e la frequenza del segnale generato nel caso in cui la modalità sia a frequenza fissa (cioè non sweep):
AD.setCrystalFrequency(25000000);
AD.setFrequency(fixed_freq, 0);
viene poi settato il tipo di onda generata:
AD.setWave(AD9833_TRIANGLE); // AD9833_SINE AD9833_SQUARE1 AD9833_SQUARE2 AD9833_TRIANGLE
Nel caso di AD9833_SQUARE1 e AD9833_SQUARE2, una delle due onde quadre ha frequenza pari alla metà dell’altra.
Infine vengono stampati sul Serial Monitor informazioni sul tipo di onda generata e sulla sua frequenza.
Serial.println(AD.getWave());
Serial.print("Current frequency: ");
Serial.println(AD.getFrequency());
Nella funzione loop è implementta la parte che gestisce lo sweep.
if(sweep) {
if (up) sweep_freq++;
else sweep_freq--;
// reverse direction if needed
if (sweep_freq >= freq_sweep_max) up = false;
if (sweep_freq <= freq_sweep_min) up = true;
AD.setFrequency(sweep_freq);
Serial.print("Current frequency: ");
Serial.println(AD.getFrequency());
delay(10);
}
Se lo sweep è attivato il primo blocco if è attivo e il codice al suo interno calcola quale frequenza generare e se questa deve aumentare o diminuire (tramite la variabile up). La frequenza corrente viene settata tramite il comando AD.setFrequency(sweep_freq). Viene anche stampata, sul Serial Monitor, la frequenza corrente generata. L’ultimo comando, delay(10), determina la velocità con cui la frequenza viene incrementata/decrementata. Quindi per rallentare lo sweep è sufficiente aumentare il numero al suo interno (per esempio 20 o 50 al posto di 10).
In questa implementazione, la variazione della frequenza di sweep è lineare.
Considerazioni finali e limiti
Questi moduli hanno una buona qualità costruttiva e generalmente funzionano bene, ma non aspettarti di poter arrivare fino alla frequenza massima di 12,5 MHz dell’AD9833. L’AD9833 è un chip DDS (Direct Digital Synthesis) e quando la frequenza di uscita si avvicina alla frequenza di clock, che in questo caso è di 25 MHz, la capacità di riprodurre la forma d’onda richiesta inizia a diminuire.
La stabilità è buona fino a circa 1 MHz per le forme d’onda quadra e triangolare, poi la forma d’onda inizia a peggiorare man mano che la frequenza aumenta. Nel caso di onda sinusoidale, il segnale generato si presenta senza distorsioni apprezzabili fino a circa 4 MHz.
Nel caso di segnale sinusoidale e triangolare l’uscita ha un valore di tensione di circa 0,6 Vpp che oscilla tra 0 V e circa +0,6 V. A frequenze superiori a 1 MHz, l’ampiezza del segnale inizia a diminuire. A differenza delle altre due forme d’onda, l’uscita dell’onda quadra varierà fra 0 V e Vcc per la gran parte dei valori di frequenza generati.
Test con l’oscilloscopio
Di seguito i test fatti all’oscilloscopio sui tre tipi di onda:



Video del generatore in modalità sweep
Nel video seguente è possibile osservare il funzionamento dello sweep. La forma d’onda è una sinusoide la cui frequenza varia da un minimo di 100 Hz (perché abbiamo che freq_sweep_min = 100) ad un massimo di 1000 Hz (perché abbiamo che freq_sweep_max = 1000) per poi decrescere fino a 100 Hz e ricominciare a crescere fino a 1000 Hz in un loop infinito.
Newsletter
Se vuoi essere aggiornato sui nuovi articoli, iscriviti alla newsletter. Prima dell’iscrizione alla newsletter leggi la pagina Privacy Policy (UE)
Se ti vuoi disiscrivere dalla newsletter clicca sul link che troverai nella mail della newsletter.
🔗 Seguici anche sui nostri canali social per non perdere nessun aggiornamento!
📢 Unisciti al nostro canale Telegram per ricevere aggiornamenti in tempo reale.
🐦 Seguici su Twitter per rimanere sempre informato sulle nostre novità.
Grazie per far parte della nostra community TechRM! 🚀