Parma
Offline
Edison Member
Karma: 10
Posts: 2104
|
 |
« on: May 06, 2012, 06:22:50 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Rome
Offline
God Member
Karma: 1
Posts: 564
La mia prima bromografata!!
|
 |
« Reply #1 on: May 06, 2012, 07:26:05 pm » |
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..
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7340
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #2 on: May 06, 2012, 11:15:44 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Parma
Offline
Edison Member
Karma: 10
Posts: 2104
|
 |
« Reply #3 on: May 07, 2012, 01:18:33 am » |
Grazie astrobeed, Avevo pensato anche a questo ma non è che poi non riesco più a riprogrammare Arduino se inizio a scrivere sulla seriale?
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7340
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #4 on: May 07, 2012, 02:57:07 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 0
Posts: 355
|
 |
« Reply #5 on: May 07, 2012, 10:12:13 am » |
Puoi anche usare un shift register esterno. (quindi solo due pin a tua scelta dell' Arduino)
Io comunque preferirei PORTD.
|
|
|
|
|
Logged
|
|
|
|
|
Parma
Offline
Edison Member
Karma: 10
Posts: 2104
|
 |
« Reply #6 on: May 08, 2012, 03:12:24 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16431
Don't know what I do
|
 |
« Reply #7 on: May 08, 2012, 03:16:22 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Parma
Offline
Edison Member
Karma: 10
Posts: 2104
|
 |
« Reply #8 on: May 09, 2012, 09:56:48 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7340
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #9 on: May 09, 2012, 10:05:45 am » |
- 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.
|
|
|
|
|
Logged
|
|
|
|
|
Parma
Offline
Edison Member
Karma: 10
Posts: 2104
|
 |
« Reply #10 on: May 09, 2012, 10:25:52 am » |
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 
|
|
|
|
|
Logged
|
|
|
|
|
Parma
Offline
Edison Member
Karma: 10
Posts: 2104
|
 |
« Reply #11 on: May 25, 2012, 03:23:54 am » |
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
|
|
|
|
« Last Edit: May 25, 2012, 03:26:03 am by flz47655 »
|
Logged
|
|
|
|
|
|