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.
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.
in data 11-16-2015 09:09 AM
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!
in data 11-17-2015 03:46 AM
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?
in data 11-17-2015 07:34 AM
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..
in data 11-18-2015 02:11 AM
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.
in data 11-24-2015 08:23 AM
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!