Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

RTSI Trigger (DAQmx & C++)

Dear Reader

I tried to Synchronize the Starting of the output of two NI cards using the RTSI bus.
I wrote the following code - but the slave-device doesn't start.
Could anyone please tell me what's maybe missing?

Pascal

//PCIe 6259 (Dev1): AO master, export StartTrigger to RTSI0
    error = DAQmxCreateTask("",&ao6259TaskHandle);
    error = DAQmxCreateAOVoltageChan(ao6259TaskHandle, "Dev1/ao0", "", -5.0, 5.0, DAQmx_Val_Volts, "");
    error = DAQmxCfgSampClkTiming(ao6259TaskHandle, "OnboardClock", 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 10000);
    error = DAQmxExportSignal(ao6259TaskHandle, DAQmx_Val_StartTrigger, "RTSI0");
    error = DAQmxWriteRaw(ao6259TaskHandle, 10000, false, 10.0, dataBuffer, NULL, NULL);

//PCI 6733 (Dev2): Slave device (only triggered)
    error = DAQmxCreateTask("", &ao6733TaskHandle);
    error = DAQmxCreateAOVoltageChan(ao6733TaskHandle, "Dev2/ao0", "", -5.0, 5.0, DAQmx_Val_Volts, "");
    error = DAQmxCfgSampClkTiming(ao6733TaskHandle, "OnboardClock", 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 10000);
    error = DAQmxCfgDigEdgeStartTrig(ao6733TaskHandle, "RTSI0", DAQmx_Val_Rising);
    error = DAQmxWriteRaw(ao6733TaskHandle, 10000, false, 10.0, dataBuffer, NULL, NULL);


    error = DAQmxStartTask(ao6259TaskHandle);


0 Kudos
Message 1 of 11
(7,495 Views)

Hello phoei,

basically there a two ways to achieve this:

1. Both tasks use the same timing:

In this case the analog output task generates the masterclock and the second task uses this as reference. The tasks should be started in the following order: First start the task that depends on a clock and then the one that generates the clock. in doing so, the two tasks on separate devices are automatically synchronized and triggered, as the slave task can be run, but it won't acquired data, before the mastertasks starts, because it depends on this clock as a reference.

This is what I can see from your excerpt of code. You started the ao task, but you didn't start the second tasks, that want's to use this clock. Remember to do this in the following order: Slave task (steady) master task (go).

error = DAQmxStartTask(ao6733TaskHandle);
error = DAQmxStartTask(ao6259TaskHandle);

2. Specification of an additional Trigger Signal

RTSI cannot only be used to share clocks, but also trigger signals. In this case also a RTSI cable is used to interconnect the boards, and one can directly refer to signals of the other devices.

Let me know if you have any queueries.

Regards,

C.L. - National Instruments Germany

0 Kudos
Message 2 of 11
(7,484 Views)
Hello

Thanks for your reply.
Solution 1: Since I don't want to restrict myself to have the same sampling rates on both devices, I don't want to share the sampling clock.
Is it also possible to synchronize the 20 MHz Masterclock and to have different sampling rates on the devices individually?

Could you perhaps give me a hint what's missing in my code (I just want to synchronize the Start of sampling)?
I don't get any error - but unfortunately also no output on the slave-device.

Thank you...
Pascal
0 Kudos
Message 3 of 11
(7,481 Views)
Hello Pascal,
 
if you want to use different sampling clocks on the boards with a common trigger pulse, the programming is not to difficult. But itf you want to have the same 20 MHz from one (Master-) device with the slave device, this clock needs to be exported as well.
 
This is shown in detail with the following example, which can be used for synchronizing any type of devices that can be connected through RTSI. Simply go to the examplefinder in CVI and search for the following example: Hardware input and Output >> DAQmx >> Synchronization >> Multi-device >> ContinuousAI.prj
 
This example allows to share a common 20 MHz reference clock and assigns different sampling reates for both tasks.
 
Please ensure, that the RTSI cable is not just connecting the devices, but also configured in MAX !
 
Additionally you can make the devices wait for a common trigger signal.
 
Hope this helps,
Regards,
C.L.
 
 
0 Kudos
Message 4 of 11
(7,480 Views)
The DAQmx C-Documentation is everything else than optimal (many undocumented functions in the samples).
It would really be helpfull if you could give me a hint what's missing in my code.
We bought 8 cards and really paid a lot...

Thanks
Pascal
0 Kudos
Message 5 of 11
(7,461 Views)

Hello Pascal,

if non of the following ideas work, I would suggest to post your sample here, so we can take a look at it.

Just some questions:

1. Did you use the following order?

error = DAQmxStartTask(ao6733TaskHandle);
error = DAQmxStartTask(ao6259TaskHandle);

2. Instead of the DAQmx_Val_StartTrigger try the DAQmx_Val_SampleClock as the start trigger.

3. I assume the RTSI cable is not just plugged in, right. If you use the measurement and automation explorer to configure the cable, you can directly access any sourc of adjacent devices without the neccesity to use the export signal function.

If non of these work. Please post your sample so I can take alook at it.

Regards, C.L.

0 Kudos
Message 6 of 11
(7,458 Views)
Hi

Here I post you the code I tried to use.
The master-device outputs the data as desired.
The slave-device does nothing...


#include "stdafx.h"
#include "windows.h"
#include "NIDAQmx.h"
#include <math.h>


int main(int argc, char* argv[])
{
    // PCIe 6259 master, PCI 6733 as slave
    int32       error                = 0;
    TaskHandle    ao6259TaskHandle    = 0;
    TaskHandle  triggerHandle        = 0;
    TaskHandle  aiTaskHandle        = 0;
    TaskHandle    ao6733TaskHandle    = 0;

    char        errBuff[2048]={'\0'};
    const int32    nPoints = 10000;
    short        dataBuffer[nPoints];
    float64     dummyBuffer[10];
    uInt32      digiData[10]={0xFFFFFFFF,2,4,8,16,32,64,128,256,0xFFFFFFFF};
   


    //init analog dataBuffer
    for (int i=0; i<nPoints; i++) {
        dataBuffer[i] = floor(15000.0*sin(((double)i)/707.0)+15001.0);
    }
   
   
//PCIe 6259 (Dev1): AO master, export StartTrigger to RTSI0
    error = DAQmxCreateTask("",&ao6733TaskHandle);
    error = DAQmxCreateTask("",&ao6259TaskHandle);
    error = DAQmxCreateAOVoltageChan(ao6259TaskHandle, "Dev1/ao0", "", -5.0, 5.0, DAQmx_Val_Volts, "");
    error = DAQmxCfgSampClkTiming(ao6259TaskHandle, "OnboardClock", 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 10000);
    error = DAQmxExportSignal(ao6259TaskHandle, DAQmx_Val_SampleClock, "RTSI0");
    error = DAQmxWriteRaw(ao6259TaskHandle, 10000, false, 10.0, dataBuffer, NULL, NULL);

//PCI 6733 (Dev2): Slave device (only triggered)

    error = DAQmxCreateAOVoltageChan(ao6733TaskHandle, "Dev2/ao0", "", -5.0, 5.0, DAQmx_Val_Volts, "");
    error = DAQmxCfgSampClkTiming(ao6733TaskHandle, "OnboardClock", 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 10000);
    error = DAQmxCfgDigEdgeStartTrig(ao6733TaskHandle, "RTSI0", DAQmx_Val_Rising);
    error = DAQmxWriteRaw(ao6733TaskHandle, 10000, false, 10.0, dataBuffer, NULL, NULL);

    DAQmxGetExtendedErrorInfo(errBuff,2048);


    error = DAQmxStartTask(ao6259TaskHandle);
   
  
    getchar();
   
    DAQmxClearTask(ao6259TaskHandle);
    DAQmxClearTask(ao6733TaskHandle);
   
    return 0;
}


Greets
Pascal
0 Kudos
Message 7 of 11
(7,455 Views)

Hello Pascal,

I took a look at your code and it ran perfectly on my machine. As I already told you: You need to start the slave task in advance!

I just added the red line of code.

#include <ansi_c.h>
//#include "stdafx.h"
//#include "windows.h"
#include <NIDAQmx.h>
#include <math.h>

#define false 0
#define true 1


int main(int argc, char* argv[])
{
    // PCI 6251 master, PCI 6733 as slave
    int32 error = 0;
    TaskHandle  ao6251TaskHandle = 0;
    TaskHandle  triggerHandle = 0;
    TaskHandle  aiTaskHandle = 0;
    TaskHandle  ao6733TaskHandle = 0;

    char errBuff[2048]={'\0'};
    const int32 nPoints = 10000;
    short dataBuffer[10000];
    float64 dummyBuffer[10];
    uInt32 digiData[10]={0xFFFFFFFF,2,4,8,16,32,64,128,256,0xFFFFFFFF};
 

    // Init analog dataBuffer 
    int i=0;
    for (i=0; i<nPoints; i++) {
        dataBuffer[i] = floor(15000.0*sin(((double)i)/707.0)+15001.0);
    }
   
   
    //PCI 6251 (Dev4): AO master, export StartTrigger to RTSI0
    error = DAQmxCreateTask("",&ao6733TaskHandle);
    error = DAQmxCreateTask("",&ao6251TaskHandle);
    error = DAQmxCreateAOVoltageChan(ao6251TaskHandle, "Dev4/ao0", "", -5.0, 5.0, DAQmx_Val_Volts, "");
    error = DAQmxCfgSampClkTiming(ao6251TaskHandle, "OnboardClock", 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 10000);
    error = DAQmxExportSignal (ao6251TaskHandle, DAQmx_Val_StartTrigger, "RTSI0");
    error = DAQmxWriteRaw(ao6251TaskHandle, 10000, false, 10.0, dataBuffer, NULL, NULL);

 //PCI 6733 (Dev1): Slave device (only triggered)

 error = DAQmxCreateAOVoltageChan(ao6733TaskHandle, "Dev1/ao0", "", -5.0, 5.0, DAQmx_Val_Volts, "");
 error = DAQmxCfgSampClkTiming (ao6733TaskHandle, "OnboardClock", 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 10000);

 error = DAQmxCfgDigEdgeStartTrig (ao6733TaskHandle, "RTSI0", DAQmx_Val_Rising);
 error = DAQmxWriteRaw (ao6733TaskHandle, 10000, false, 10.0, dataBuffer, NULL, NULL);

 DAQmxGetExtendedErrorInfo(errBuff,2048);

 error = DAQmxStartTask(ao6733TaskHandle);
 error = DAQmxStartTask(ao6251TaskHandle);

  getchar();
   
    DAQmxClearTask(ao6733TaskHandle);
    DAQmxClearTask(ao6251TaskHandle);
  
    return 0;
}

Hope this helps, regards, C.L.

0 Kudos
Message 8 of 11
(7,422 Views)
Sure - but this has nothing to do with being triggered by the master card.
Because if I comment out the start of the mastercard, the slave device starts sampling as well!

Do you know how to really let one card trigger the other one...?

Pascal
0 Kudos
Message 9 of 11
(7,406 Views)
...I just found out the RTSI-Cable is not ok anymore...

Not it works!

Thanks a lot!
Pascal
0 Kudos
Message 10 of 11
(7,396 Views)