From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Forum Italiano sui Prodotti NI

annulla
Visualizzazione dei risultati per 
Cerca invece 
Intendevi dire: 

Single Sample Output Timing USB 6259

Salve a tutti.

Sto cercando di realizzare un PID controller utilizzando la schesa USB 6259 che abbiamo in laboratorio. La prima cosa di cui ho bisogno è generare una rampa ad una uscita analogica della scheda e, per ogni diverso valore di tensione, leggere la tensione presente ad uno degli ingressi analogici. Sto programmando la scheda in VisualBasic6. Dato che ho bisogno di effettuare una lettura per ogni step della rampa che genero non posso utilizzare la funzione DAQmxWriteAnalogF64 in modalità di generazione continua, con la quale non ho problemi a definire la frequenza della  rampa. Ho pensato quindi di generare un array  contenete i valori di tensione che voglio scivere (dataRampMod() nel codice che ho postato) e modificare l'uscita analogica della scheda utilizzando un ciclo for. In questo modo però la frequenza di scrittura risulta molto lenta. Impostando 1V di ampiezza della rampa e suddividendolo in 100 valori non riesco a generare una rampa con frequenza maggiore di qualche Hz. Vi riporto il codiche che ho scritto:

 

Private Sub cmdStartLock_Click()

Dim i As Long
Dim rate As Double
Dim WaveFrequency As Double
Dim sampsPerCycle As Double
Dim amplitude As Double
Dim offset As Double

On Error GoTo ErrorHandler
offset = 0

WaveFrequency = Val(txtFrequency.Text)
sampsPerCycle = Val(samplesPerBufferTextBox.Text)
rate = WaveFrequency * sampsPerCycle
amplitude = Val(txtAmplitude.Text)

GenerateRampModif amplitude, 0, sampsPerCycle

DAQmxErrChk DAQmxCreateTask("", taskHandlePiezoVoltage)
DAQmxErrChk DAQmxCreateAOVoltageChan(taskHandlePiezoVoltage, "Dev1/ao0", "", "-2.", "+2", DAQmx_Val_VoltageUnits1_Volts, "")


bStopFlag = False


Do While bStopFlag = False
DoEvents

For i = 0 To sampsPerCycle - 1

DAQmxErrChk DAQmxWriteAnalogF64(taskHandlePiezoVoltage, 1, True, 10#, DAQmx_Val_GroupByChannel, dataRampMod(i), sampsPerChanWritten, ByVal 0&)

Next i

Loop

DAQmxErrChk DAQmxStopTask(taskHandlePiezoVoltage)
DAQmxErrChk DAQmxClearTask(taskHandlePiezoVoltage)
MsgBox "Stop"
Exit Sub

ErrorHandler:
    DAQmxStopTask taskHandlePiezoVoltage
    DAQmxClearTask taskHandlePiezoVoltage
    MsgBox "StartLock subroutine error:" & Err.Number & " " & Err.Description, , "Error"

End Sub




Private Sub GenerateRampModif(ByVal amplitude As Double, ByVal offset As Double, ByVal numSampsPerChannel As Double)
    
    Dim step As Double
    Dim i As Long
    ReDim dataRampMod(0 To numSampsPerChannel - 1)
    
    step = amplitude / numSampsPerChannel
    
    For i = 0 To numSampsPerChannel - 1
    '  Puts the proper data in the array for sawtooth wave generation

            dataRampMod(i) = step * i
            
    Next i
End Sub

 

Ho provato ad utilizzare la fuznione DAQmxCfgSampClkTiming per configurare il timing della task ma non sono riuscito ad ottenere miglioramenti.

La mia domanda è: sto già spingendo la scheda al limite delle sue prestazioni e non può generare un segnale ("un punto alla volta") con una frequenza maggiore di quella che ho trovato? Oppure ci sono delle impostazioni che posso modificare per migliorare un po' la situazione. 

 

Qualcuno può aiutarmi?

Grazie!

0 Kudos
Messaggio 1 di 5
4.036Visualizzazioni

Ciao Nicola88,

 

perchè non impostare una generazione finita usando il DAQmxCfgSampClkTiming e mettendogli Finite Samples. Gli dovrai impostare anche il sample rate e il number of samples e hai molto più controllo sulla velocità perchè la temporizzazione viene settata con i parametri sopra e non da loop a livello software. Dopo basta che fai un po' di elaborazione e per ogni step della tua rampa dai un numero di campioni che preferisci, così nel tuo array avrai un tot di campioni per ogni step della rampa.

 

E' chiaro? 

0 Kudos
Messaggio 2 di 5
4.020Visualizzazioni

Ciao CorraDIT,

 

non ho capito molto bene.. Intendi che potrei generare una rampa composta da un numero finito di punti con il timing impostato con la funzione DAQmxCfgSampClkTiming, alla quale sincronizzare la funzione di di lettura dell'ingresso analogico?

 

Se è questo quello che intendi magari potrebbe anche funzionare però nella seconda parte della mia applicazione ho bisogno di regolare l'uscita analogica in base al risultato della lettura, quindi sarei comunque vincolato dai tempi del sistema operativo..

 

 

0 Kudos
Messaggio 3 di 5
4.013Visualizzazioni

Ciao Nicola88,

 

prova a temporizzare il ciclo mettendoci un Wait o Wait Until, anche molto basso: a volte può aiutare a velocizzare. Per il resto, ti consiglio di fare una generazione hardware, poi se devi fare delle elaborazioni e analisi ti consiglio di usare le code per passare i dati da un ciclo all'altro e permetterti di bufferizzare un po' di dati.

0 Kudos
Messaggio 4 di 5
4.002Visualizzazioni

Salve a tutti, grazie per le risposte!

Purtroppo mi sono reso conto che la scheda che sto usando non è adatta ai miei scopi, intrinsecamente troppo lenta. Vorrà dire che passerò a qualcosa di più veloce! 

A presto!

0 Kudos
Messaggio 5 di 5
3.955Visualizzazioni