Sommario:

Generatore di forme d'onda Arduino: 5 passaggi (con immagini)
Generatore di forme d'onda Arduino: 5 passaggi (con immagini)

Video: Generatore di forme d'onda Arduino: 5 passaggi (con immagini)

Video: Generatore di forme d'onda Arduino: 5 passaggi (con immagini)
Video: Generatore di segnali con AD9850 da 0 a 40 MHz con Arduino - Video 543 2024, Dicembre
Anonim
Generatore di forme d'onda Arduino
Generatore di forme d'onda Arduino

Aggiornamento di febbraio 2021: dai un'occhiata alla nuova versione con 300 volte la frequenza di campionamento, basata sul Raspberry Pi Pico

In laboratorio, spesso è necessario un segnale ripetitivo di una certa frequenza, forma e ampiezza. Potrebbe essere per testare un amplificatore, controllare un circuito, un componente o un attuatore. In commercio sono disponibili potenti generatori di forme d'onda, ma è relativamente facile crearne uno utile con un Arduino Uno o un Arduino Nano, vedi ad esempio:

www.instructables.com/id/Arduino-Waveform-…

www.instructables.com/id/10-Resister-Ardui…

Ecco la descrizione di un altro con le seguenti caratteristiche:

* Forme d'onda accurate: uscita a 8 bit utilizzando R2R DAC, forma a 256 campioni

* Veloce: frequenza di campionamento di 381 kHz

* Preciso: gamma di frequenza a passi di 1 mHz. Preciso come il cristallo di Arduino.

* Facilità d'uso: forma d'onda e frequenza impostabili con encoder rotativo singolo

* Ampia gamma di ampiezze: da millivolt a 20V

* 20 forme d'onda predefinite. Facile aggiungere altro.

* Facile da realizzare: componenti standard Arduino Uno o Nano plus

Passaggio 1: considerazioni tecniche

Fare un segnale analogico

Un difetto di Arduino Uno e Nano è che non ha un convertitore digitale-analogico (DAC), quindi non è possibile fargli emettere una tensione analogica direttamente sui pin. Una soluzione è la scala R2R: 8 pin digitali sono collegati a una rete di resistori in modo da raggiungere 256 livelli di uscita. Attraverso l'accesso diretto alla porta, Arduino può impostare 8 pin contemporaneamente con un singolo comando. Per la rete di resistori sono necessari 9 resistori con valore R e 8 con valore 2R. Ho usato 10kOhm come valore per R, che mantiene la corrente dai pin a 0,5 mA o meno. Immagino che anche R = 1kOhm potrebbe funzionare, dal momento che Arduino può facilmente fornire 5 mA per pin, 40 mA per porta. È importante che il rapporto tra i resistori R e 2R sia realmente 2. Ciò si ottiene più facilmente mettendo in serie 2 resistori di valore R, per un totale di 25 resistori.

Accumulatore di fase

La generazione di una forma d'onda si riduce quindi all'invio ripetitivo di una sequenza di numeri a 8 bit ai pin Arduino. La forma d'onda viene memorizzata in una matrice di 256 byte e questa matrice viene campionata e inviata ai pin. La frequenza del segnale di uscita è determinata dalla velocità con cui si avanza attraverso l'array. Un modo robusto, preciso ed elegante per farlo è con un accumulatore di fase: un numero a 32 bit viene incrementato a intervalli regolari e usiamo gli 8 bit più significativi come indice dell'array.

Campionamento veloce

Gli interrupt consentono di campionare in tempi ben definiti, ma l'overhead degli interrupt limita la frequenza di campionamento a ~100kHz. Un loop infinito per aggiornare la fase, campionare la forma d'onda e impostare i pin richiede 42 cicli di clock, ottenendo così una frequenza di campionamento di 16MHz/42=381kHz. La rotazione o la pressione dell'encoder rotativo provoca un cambio di pin e un interrupt che esce dal loop per modificare l'impostazione (forma d'onda o frequenza). In questa fase i 256 numeri nell'array vengono ricalcolati in modo che non sia necessario eseguire calcoli effettivi della forma d'onda nell'anello principale. La frequenza massima assoluta che può essere generata è 190kHz (metà della frequenza di campionamento) ma poi ci sono solo due campioni per periodo, quindi poco controllo della forma. L'interfaccia quindi non permette di impostare la frequenza sopra i 100kHz. A 50kHz, ci sono 7-8 campioni per periodo ea 1,5 kHz e sotto tutti i 256 numeri memorizzati nell'array vengono campionati ogni periodo. Per le forme d'onda in cui il segnale cambia in modo uniforme, ad esempio l'onda sinusoidale, saltare i campioni non è un problema. Ma per le forme d'onda con picchi stretti, ad esempio un'onda quadra con un ciclo di lavoro ridotto, c'è il pericolo che per frequenze superiori a 1,5 kHz la mancanza di un singolo campione possa comportare un comportamento della forma d'onda non come previsto

Precisione della frequenza

Il numero di cui la fase viene incrementata ad ogni campione è proporzionale alla frequenza. La frequenza può quindi essere impostata con una precisione di 381kHz/2^32=0.089mHz. In pratica tale precisione non è quasi mai necessaria, quindi l'interfaccia si limita a impostare la frequenza in passi di 1 mHz. La precisione assoluta della frequenza è determinata dalla precisione della frequenza di clock di Arduino. Questo dipende dal tipo di Arduino, ma la maggior parte specifica una frequenza di 16.000 MHz, quindi una precisione di ~ 10 ^ -4. Il codice consente di modificare il rapporto tra la frequenza e l'incremento di fase per correggere piccole deviazioni dell'ipotesi di 16MHz.

Buffering e amplificazione

La rete di resistori ha un'elevata impedenza di uscita, quindi la sua tensione di uscita diminuisce rapidamente se è collegato un carico. Questo può essere risolto bufferizzando o amplificando l'uscita. Qui, il buffering e l'amplificazione vengono eseguiti con un opamp. Ho usato l'LM358 perché ne avevo alcuni. È un opamp lento (velocità di variazione 0,5 V per microsecondo) quindi ad alta frequenza e ampiezza elevata il segnale viene distorto. Una cosa buona è che può gestire tensioni molto vicine a 0V. La tensione di uscita è tuttavia limitata a ~2V al di sotto del binario, quindi l'utilizzo di +5V di potenza limita la tensione di uscita a 3V. I moduli step-up sono compatti ed economici. Alimentando +20V all'opamp, può generare segnali con tensione fino a 18V. (NB, lo schema dice LTC3105 perché era l'unico step-up che ho trovato in Fritzing. In realtà ho usato un modulo MT3608, guarda le immagini nei passaggi successivi). Scelgo di applicare un'attenuazione variabile all'uscita del DAC R2R quindi uso uno degli operazionali per bufferizzare il segnale senza amplificazione e l'altro per amplificare di 5.7, in modo che il segnale possa raggiungere un'uscita massima di circa 20V. La corrente di uscita è piuttosto limitata, ~10mA, quindi potrebbe essere necessario un amplificatore più potente se il segnale deve pilotare un grande altoparlante o un elettromagnete.

Passaggio 2: componenti richiesti

Per il generatore di forme d'onda principale

Arduino Uno o Nano

Display LCD 16x2 + trimmer 20kOhm e resistenza serie 100Ohm per retroilluminazione

Encoder rotativo a 5 pin (con pulsante integrato)

25 resistori da 10kOhm

Per il buffer/amplificatore

LM358 o altro doppio opamp

modulo step-up basato su MT3608

Resistenza variabile da 50kOhm

Resistenza da 10kOhm

Resistenza 47kOhm

condensatore da 1muF

Passaggio 3: costruzione

Costruzione
Costruzione
Costruzione
Costruzione

Ho saldato il tutto su una scheda prototipo 7x9cm, come mostrato nella foto. Dato che si è un po' disordinato con tutti i fili ho provato a colorare di rosso i conduttori che portano il positivo e di nero quelli che portano la massa.

L'encoder che ho usato ha 5 pin, 3 da un lato, 2 dall'altro. Il lato con 3 pin è l'encoder vero e proprio, il lato con 2 pin è il pulsante integrato. Sul lato 3 pin, il pin centrale va collegato a massa, gli altri due pin a D10 e D11. Sul lato a 2 pin, un pin deve essere collegato a massa e l'altro a D12.

È la cosa più brutta che abbia mai fatto, ma funziona. Sarebbe bello mettere in un recinto, ma per ora il lavoro extra e il costo non lo giustificano davvero. Il Nano e il display sono collegati con pin-header. Non lo rifarei se ne costruissi uno nuovo. Non ho messo connettori sulla scheda per captare i segnali. Invece, li raccolgo con cavi di coccodrillo da pezzi sporgenti di filo di rame, etichettati come segue:

R - segnale grezzo dal DAC R2R

B - segnale bufferizzato

A - segnale amplificato

T - segnale timer dal pin 9

G - terra

+ - tensione 'alta' positiva dal modulo elevatore

Passaggio 4: il codice

Il codice, uno sketch Arduino, è allegato e dovrebbe essere caricato su Arduino.

Sono state predefinite 20 forme d'onda. Dovrebbe essere semplice aggiungere qualsiasi altra onda. Nota che le onde casuali riempiono l'array di 256 valori con valori casuali, ma lo stesso modello viene ripetuto ogni periodo. I veri segnali casuali suonano come rumore, ma questa forma d'onda suona molto più come un fischio.

Il codice imposta un segnale a 1kHz sul pin D9 con TIMER1. Questo è utile per controllare la temporizzazione del segnale analogico. È così che ho capito che il numero di cicli di clock è 42: se presumo 41 o 43 e genero un segnale a 1kHz, ha chiaramente una frequenza diversa dal segnale sul pin D9. Con il valore 42 si abbinano perfettamente.

Normalmente, Arduino interrompe ogni millisecondo per tenere traccia del tempo con la funzione millis(). Ciò disturberebbe l'accurata generazione del segnale, quindi l'interruzione particolare è disabilitata.

Il compilatore dice: "Sketch utilizza 7254 byte (23%) di spazio di archiviazione del programma. Il massimo è 30720 byte. Le variabili globali utilizzano 483 byte (23%) di memoria dinamica, lasciando 1565 byte per le variabili locali. Il massimo è 2048 byte." Quindi c'è ampio spazio per il codice più sofisticato. Attenzione che potrebbe essere necessario scegliere "ATmega328P (old bootloader)" per caricare correttamente sul Nano.

Passaggio 5: utilizzo

Il generatore di segnale può essere alimentato semplicemente tramite il cavo mini-USB dell'Arduino Nano. È meglio farlo con un power bank, in modo che non ci sia un loop di massa accidentale con l'apparato a cui può essere collegato.

Quando è acceso genererà un'onda sinusoidale di 100Hz. Ruotando la manopola è possibile scegliere uno degli altri 20 tipi di onde. Ruotando mentre è premuto, il cursore può essere impostato su una qualsiasi delle cifre della frequenza, che può quindi essere modificata al valore desiderato.

L'ampiezza può essere regolata con il potenziometro e può essere utilizzato il segnale bufferizzato o amplificato.

È davvero utile utilizzare un oscilloscopio per controllare l'ampiezza del segnale, in particolare quando il segnale fornisce corrente a un altro dispositivo. Se viene assorbita troppa corrente, il segnale verrà tagliato e il segnale sarà fortemente distorto

Per frequenze molto basse, l'uscita può essere visualizzata con un LED in serie con una resistenza da 10kOhm. Le frequenze audio possono essere ascoltate con un altoparlante. Assicurati di impostare il segnale molto piccolo ~ 0,5 V, altrimenti la corrente diventa troppo alta e il segnale inizia a tagliare.

Consigliato: