Ho un problema riguardo la comunicazione SPI tra Arduino DUE e un DAC esterno ad elevata risoluzione (componente AD5570 http://www.analog.com/media/en/technical-documentation/data-sheets/AD5570.pdf
Quello che mi piacerebbe fare sarebbe acquisire tramite il monitor seriale la tensione desiderata in uscita al DAC (ex. 100mV o 1V) e trasferirla al DAC tramite SPI dopo averla convertita in codifica binaria.
Oltre a questo mi piacerebbe ottenere in uscita al DAC una rampa in tensione lenta.
Sto lavorando al codice ma ho problemi nella parte di selezione della tensione, conversione e conseguente comunicazione al DAC. Purtroppo non ho ancora disponibile il componente per poterlo testare, ma volevo portarmi avanti con il codice per capire al meglio come affrontare il problema.
Ho trovato alcuni esempi sul web ma non ho capito del tutto come siano stati realizzati.
Per quanto riguarda i collegamenti, considerando il pinout del componente, pensavo di collegare:
... ma prima di comprare una board ... li leggete i reference per capire le caratteristiche di cosa state comprando ?
Sulla DUE il bus SPI NON si trova sui pin come su Arduino UNO, ma SOLO sul connettore SPI a sei poli !
Ti rammento inoltre che la scheda funziona esclusivamente a 3.3V e molti dei suoi pin sono in grado di dare un decimo della corrente (max 3 mA) dei pin degli altri Arduino (max 40 mA). I rimanenti comunque non danno più di 15 mA.
Forse mi sono spiegato male, ma i collegamenti li ho realizzati sul connettore SPI a sei poli eccetto il pin di sincronismo che è collegato al pin PWM 10 della board.
... perdona, ma ... non era assolutamente chiaro :
Quando chiedi spiegazioni/aiuto dai sempre il massimo delle informazioni (link ai prodotti, nome dei connettori usati, ecc.) perché noi ... non possiamo sapere cosa l'utente fa
I numeri sulla sinistra si riferiscono ai pin del DAC mentre sulla destra ho riportato i corrispondenti pin della board.
Cercherò di fornire le informazioni il più precisamente possibile, come penso di aver fatto per il mio problema.
... Quello che mi piacerebbe fare sarebbe acquisire tramite il monitor seriale la tensione desiderata in uscita al DAC (ex. 100mV o 1V) e trasferirla al DAC tramite SPI dopo averla convertita in codifica binaria.
Oltre a questo mi piacerebbe ottenere in uscita al DAC una rampa in tensione lenta.
Forse sono stato poco chiaro anche in questo!
Il DAC mi serve per generare segnali da inviare ad un dispositivo. Ciò che vorrei ottenere sarebbe:
1-tensione continua in uscita al DAC (ex. 100mV, 1V) che possa essere scelta dall'utente, quindi l'utente sceglierà la tensione tramite il monitor seriale e questo valore deve essere trasferito al DAC come cofica binaria per generare il segnale desiderato;
2-rampa di tensione in uscita al DAC con pendenza regolabile dall'utente per realizzare una misura diversa dalla precedente. Quindi anche in questo caso il DAC genererà una rampa di tensione con "pendenza" specificata dall'utente o fissa.
Ho letto alcuni esempi online ma non credo di averli capiti...se dovesse esserci qualcos'altro di poco chiaro cercherò di chiarire al meglio il tutto. Spero anche di non aver sbagliato sezione.
Il pin 10 in realtà è legato a comodità nella realizzazione del layout.
Per quanto riguarda il codice, non capisco come poter realizzare questo passaggio dalla selezione della tensione all'effettiva generazione da parte del DAC. Relativamente al primo punto del post precedente la bozza del codice implementato per ora è:
int DACR;
float DACR_MILLI;
long Din; //segnale in ingresso al DAC
String Din_Bin; //codifica binaria in ingresso al DAC
const int V_ref = 5; //tensione di riferimento del DAC
const int tot_level = 65536; //2^16 livelli in cui può essere suddivisa l'uscita
float millivolt = 0.001; //conversione in millivolt
if (Serial.available()!=0){
DACR = Serial.parseInt() ;
DACR_MILLI = DACR*millivolt;
Serial.print("Voltage selected [mV]: ");
Serial.println(DACR,DEC);
Din = (DACR_MILLI/(4*V_ref) + 0.5)*tot_level;
Din_Bin = Din_Bin + String(Din,BIN);
Serial.println(Din_Bin);
delay(1000);
digitalWrite(pinSYNC_DAC,LOW); //comunicazione SPI tra Arduino e DAC
SPI.transfer(pinSYNC_DAC, highByte(Din_Byte), SPI_CONTINUE);
SPI.transfer(pinSYNC_DAC, lowByte(Din_Byte), SPI_LAST);
digitalWrite(pinSYNC_DAC,HIGH);
}
}
non so se questa sia la strada più semplice...la parte di codice che segue l'if pensavo di includerla in una funzione apposita che mi permetta di impostare il DAC prima della misura.
Relativamente al secondo punto non ho idea di come procedere per avere la rampa, ma forse è meglio concentrarsi su un problema alla volta.
... scusa, vedo che dichiari int, float, long, String ... a che servono tutti questi tipi dati ? ? ?
Quell'affare in ingresso vuole semplicemente 2 bytes ovvero un "unsigned int" che rappresenta il valore da generare dato appunto dalla formula che trovi nel datasheet a pag. 17 ovvero :
Infatti pensavo ci fosse qualcosa che non andava, tenendo conto anche del fatto che highByte() e lowByte() non funzionano con un argomento di tipo String.
Il float è legato al fatto che io inserisco un numero da seriale, ma se questo valore lo volessi in millivolt e non in volt, dovrei moltiplicare il tutto per 0.001.
il concetto quindi è convertire il dato immesso da seriale in un unsigned int?
... da seriale accetta pure il valore in millivolt (... o in volt, come preferisci), poi, sapendo Vrefin (lo fissi tu) e Vout (valore letto dalla seriale) ti calcoli ... l'incognita (... ovvero il valore intero non segnato) da trasmettere al DAC
Perfetto, quindi se ho capito bene il codice diventa più o meno così:
int DACR;
unsigned int Din; //codifica binaria in ingresso al DAC
const int V_ref = 5; //tensione di riferimento del DAC
const int tot_level = 65536; //2^16 livelli in cui può essere suddivisa l'uscita
if (Serial.available()!=0){
DACR = Serial.parseInt() ;
Serial.print("Voltage selected [mV]: ");
Serial.println(DACR,DEC);
Din = (DACR/(4*V_ref) + 0.5)*tot_level;
Serial.println(Din);
delay(1000);
digitalWrite(pinSYNC_DAC,LOW); //comunicazione SPI tra Arduino e DAC
SPI.transfer(pinSYNC_DAC, highByte(Din), SPI_CONTINUE);
SPI.transfer(pinSYNC_DAC, lowByte(Din), SPI_LAST);
digitalWrite(pinSYNC_DAC,HIGH);
}
in questo modo il DAC mi dovrebbe fornire in uscità ciò che ho selezionato tramite la seriale?
... hai verificato se il valore che stampa la Serial.println() corrisponde al valore che ti aspetti ? Se SI ... c'è da mettere solo a punto/verificare la comunicazione SPI ...
Con il codice che del messaggio precedente (al quale aggiungere il Serial.begin() nel Setup()) non ottengo buoni risultati.
Infatti inserendo il valore "100" per esempio, mi aspetterei 1100100, che comunque è insufficiente da inviare al DAC. Invece il monito seriale stampa questo:
Voltage selected [mV]: 100
360448
Voltage selected [mV]: 200
688128