Go Down

Topic: DAC e Ripple (Read 2234 times) previous topic - next topic

flz47655

Ciao a tutti,
Ho realizzato qualche tempo fa un DAC (Digital-Analog-Converter) ad 8 bit basato sulla rete R-2R http://en.wikipedia.org/wiki/Resistor_ladder, con l'arrivo dell'oscilloscopio ho provato a verificare quali prestazioni poteva offrirmi.
All'uscita ho inserito un amplificatore operazionale LM358 in configurazione inseguitore di tensione http://it.wikipedia.org/wiki/Inseguitore_di_tensione e questo ha limitato diciamo l'escursione massima a 3.88 volt al posto dei 5 canonici, risolvibile alimentando con una tensione superiore l'integrato o utilizzando un op-amp equivalente rail-to-rail.

Ho notato generando una sinusoide (codice sperimentale in allegato) però che il segnale che ottengo è abbastanza "sporco", presenta dei picchi anche elevati che si attenuano al calare della frequenza, ecco la schermata dell'oscilloscopio (sinusoide a 73 Hz):



Cos'è secondo voi? una sorta di limite dovuto alle resistenze che ho scelto (9K e 18K) o all'op-amp o qualcos'altro?

La misura del ripple sull'alimentazione dell'op-amp:



Risulta relativamente elevata con un Vrms di 7 mV, è troppo?



Ecco infine la schedina:




Ciao e grazie a tutti

dab77


Ciao a tutti,
Ho realizzato qualche tempo fa un DAC (Digital-Analog-Converter) ad 8 bit basato sulla rete R-2R http://en.wikipedia.org/wiki/Resistor_ladder, con l'arrivo dell'oscilloscopio ho provato a verificare quali prestazioni poteva offrirmi.
All'uscita ho inserito un amplificatore operazionale LM358 in configurazione inseguitore di tensione http://it.wikipedia.org/wiki/Inseguitore_di_tensione e questo ha limitato diciamo l'escursione massima a 3.88 volt al posto dei 5 canonici, risolvibile alimentando con una tensione superiore l'integrato o utilizzando un op-amp equivalente rail-to-rail.

Ho notato generando una sinusoide (codice sperimentale in allegato) però che il segnale che ottengo è abbastanza "sporco", presenta dei picchi anche elevati che si attenuano al calare della frequenza, ecco la schermata dell'oscilloscopio (sinusoide a 73 Hz):



Cos'è secondo voi? una sorta di limite dovuto alle resistenze che ho scelto (9K e 18K) o all'op-amp o qualcos'altro?

La misura del ripple sull'alimentazione dell'op-amp:



Risulta relativamente elevata con un Vrms di 7 mV, è troppo?



Ecco infine la schedina:




Ciao e grazie a tutti

Purtroppo non so aiutarti, però...che saldature..

astrobeed


Ho notato generando una sinusoide (codice sperimentale in allegato) però che il segnale che ottengo è abbastanza "sporco", presenta dei picchi anche elevati che si attenuano al calare della frequenza, ecco la schermata dell'oscilloscopio (sinusoide a 73 Hz):


Il problema è dovuto alla lentezza della digitalWrite, circa 2 us per ogni operazione, tu cambi i singoli bit (pin) tramite otto digitalWrite e questo ti porta ad avere otto valori diversi nel tempo durante il cambio dello stato dei pin, va da se che a seconda del valore binario ottieni diversi valori analogici e questo crea i picchi che osservi.
Anche se i picchi sono di breve durata, pochi us, il DSO te li visualizza sotto forma di glitch amplificandone la durata apparente a seconda della time base in modo da evidenziare il fatto.
Devi modificare tutti bit nello stesso istante, ovvero non devi usare la digitalWrite ma scrivere direttamente su i registri dei port interessati, l'ideale è utilizzare gli otto bit di un solo port, su Arduino è possibile solo con PORTD, pin da 0 a 7, non dovresti avere problemi ad utilizzare la seriale per programmare Arduino perché i PIN sono settati come OUT e non c'è nessun carico su Tx e Rx.

flz47655

Grazie astrobeed,
Avevo pensato anche a questo ma non è che poi non riesco più a riprogrammare Arduino se inizio a scrivere sulla seriale?

astrobeed


ma non è che poi non riesco più a riprogrammare Arduino se inizio a scrivere sulla seriale?


No perché i due pin Tx e Rx (0 e 1) li usi come out, il problema si presenta se li usi come input dove hai un segnale esterno che prevale su quello del convertitore USB-UART (è collegato ai pin tramite due resistenze da 1k) o colleghi un dispositivo seriale esterno.
Tieni presente che quando resetti Arduino, manualmente o autoreset che sia, entra il funzione il bootloader che scavalca qualunque setup che fai dal tuo software, pertanto fino a che non scade il timeout prestabilito, pochi decimi di secondo, il tuo sketch non viene avviato e il bootloader può utilizzare la seriale a suo uso esclusivo.





acik

Puoi anche usare un shift register esterno. (quindi solo due pin a tua scelta dell' Arduino)

Io comunque preferirei PORTD.

flz47655

Scusa, non ho capito come potrei usare uno shift register per cambiare in un colpo solo tutti i pin, se devo passare da una configurazione 01010101 ad una del tipo 11111111 con lo shift register ci riuscirei in un colpo solo? Come soluzione mi viene in mente solamente disabilitare l'output, impostare il valore tramite tante cicli dove butto dentro allo shift register degli 1 e poi riabilitare l'output ma il tutto diventa estremamente lento.. PORTD sembra molto più efficente.

Ciao

leo72

Gli shift register hanno un registro interno che viene caricato bit per bit. Una volta che hai impostato il valore, dai l'impulso sul latch ed il registro spedisce contemporaneamente il valore del registro interno sui piedini esterni.

Sicuramente manipolare la porta del micro ti fa perdere meno tempo.

flz47655

Sono tornato a casa e ho provato le migliorie:
- Usando PORTD (ed eliminando il rescaling tramite moltiplicazione) sono riuscito ad ottenere una frequenza massima di 2604 Hz ed un output molto pulito, senza nessun glitch. Per un DAC a 8 bit mi sembra abbastanza buono, tramite la FFT la frequenza generata ha +2 Db e le altre sono molto attenuate (non mi ricordo quanto ma abbastanza)

- Ho scoperto che con
  cli();  // disable global interrupts, millis timer, and serial communication will be affected by disabling interrupts 
la frequenza generata è più stabile, altrimenti varia un pochino (di qualche Hz).

Mi ritengo molto soddisfatto per il momento.
Ringrazio tutti per i suggerimenti che mi avete dato.

astrobeed


- Usando PORTD (ed eliminando il rescaling tramite moltiplicazione) sono riuscito ad ottenere una frequenza massima di 2604 Hz ed un output molto pulito, senza nessun glitch. Per un DAC a 8 bit mi sembra abbastanza buono,


Tenuto conto che ad ogni sinusoide completa devi effettuare 256 cambi di stato del DAC in realtà esegui ben 2604*256 = 666624 cicli ad ogni secondo, un buon risultato per una piccola mcu che va a solo 16 MHz  :)
Sicuramente ottimizzando al massimo puoi salire sensibilmente di frequenza, però tocca lavorarci molto sopra e usare vari "trucchi" di programmazione per risparmiare cicli macchina.

flz47655

Non mi interessa andare oltre queste frequenze con Arduino per il momento, più avanti farò un piccolo generatore di segnali in HW con una CPLD e sarà sicuramente molto più veloce :)

Più che altro ci tenevo a dire che per risolvere il problema della saturazione dell'op-amp ho fatto così: in pratica tenendo sempre a GND il pin 7 del DAC ed eseguendo uno shift sul dato da scrivere (es. PORTD = data >> 1) trasformo per l'evenienza il DAC in un 7 bit che non fa saturare l'op-amp :)

flz47655

#11
May 25, 2012, 10:23 am Last Edit: May 25, 2012, 10:26 am by flz47655 Reason: 1
Senza stare li a perdere tempo per ottimizzare al massimo il codice di Arduino, ho implementato in Hardware invece che in software su CPLD (http://www.electroit.tk/index.php?topic=175.0) un DDS che manda i bit al DAC, ogni ciclo di sinusoide è composto da 16 step, a 50 MHz ho quindi generato una sinusoide a 3MHz circa:

Onda e FFT


Dettaglio sull'onda:


L'onda appare con un'ampiezza di 800mV nonostante VCC sia 3.3V.. ma va bene lo stesso

Ciao

Go Up