예제 #1
0
    //************************************
    // Method:    setupCLK
    // FullName:  fetch::device::NationalInstrumentsDAQ::setupCLK
    // Access:    public
    // Returns:   void
    // Qualifier:
    //
    // set up counter for sample clock
    // - A finite pulse sequence is generated by a pair of on-board counters.
    //   In testing, it appears that after the device is reset, initializing
    //   the counter task doesn't work quite right.  First, I have to start the
    //   task with the paired counter once.  Then, I can set things up normally.
    //   After initializing with the paired counter once, things work fine until
    //   the device (or computer) is reset.  My guess is this is a fault of the
    //   board or driver software.
    // - below, we just cycle the counters when config gets called.  This ensures
    //   everything configures correctly the first time, even after a device
    //   reset or cold start.
    //************************************
    void NationalInstrumentsDAQ::setupCLK(float64 nrecords, float64 record_frequency_Hz)
    {
      TaskHandle clk = 0;

      int32      N = _config->ao_samples_per_waveform();
      float64   hz = computeSampleFrequency(nrecords, record_frequency_Hz);
      const char *dev          =_config->name().c_str(),
                 *ctr          =_config->ctr().c_str(),
                 *armstart_in  =_config->armstart().c_str(),
                 *gate_out     =_config->frame_trigger_out().c_str(),
                 *trig         =_config->trigger().c_str();
      float64     lvl          =_config->level_volts();
      char term_ctr[1024]={0},
           term_gate[1024]={0},
           term_arm_out[1024]={0};
      make_terminal_name(term_ctr    ,sizeof(term_ctr)    ,dev,ctr);
      make_terminal_name(term_gate   ,sizeof(term_gate)   ,dev,ctr);
      strcat(term_gate,"Gate");
      make_terminal_name(term_arm_out,sizeof(term_arm_out),dev,gate_out);

      DAQERR( DAQmxClearTask(_clk.daqtask) ); // Once a DAQ task is started, it needs to be cleared before restarting
      DAQERR( DAQmxCreateTask("fetch_CLK",&_clk.daqtask));
      clk = _clk.daqtask;
      DAQERR(DAQmxCreateCOPulseChanFreq     (clk,term_ctr,NULL,DAQmx_Val_Hz,DAQmx_Val_Low,0.0,hz,0.5));
      DAQERR(DAQmxCfgImplicitTiming         (clk,DAQmx_Val_FiniteSamps,N));
      DAQERR(DAQmxCfgDigEdgeStartTrig       (clk,"AnalogComparisonEvent",DAQmx_Val_Rising));
      DAQERR(DAQmxSetArmStartTrigType       (clk,DAQmx_Val_DigEdge));             // Arm trigger has to be through clk
      DAQERR(DAQmxSetDigEdgeArmStartTrigSrc (clk,armstart_in));
      DAQERR(DAQmxSetDigEdgeArmStartTrigEdge(clk,DAQmx_Val_Rising));
      DAQERR(DAQmxSetStartTrigRetriggerable (clk,1));
      DAQERR(DAQmxConnectTerms(term_gate,term_arm_out,DAQmx_Val_DoNotInvertPolarity));
    }
예제 #2
0
void ScanThreadLinear::InitializeSyncAndScan(void)
{
//CLEAR TASKS
	DAQmxClearTask(taskClock);
	DAQmxClearTask(taskTrig);
	DAQmxClearTask(taskTrA);
	DAQmxClearTask(taskAnalog);
	
	Samps = globalOptions->IMAGEHEIGHT+NumPtsDw;
	LineRate = Samps*FrameRate;
	
	//CREATE TASKS
	DAQmxCreateTask("",&taskAnalog);
	DAQmxCreateTask("",&taskTrig);
	DAQmxCreateTask("",&taskTrA);
	DAQmxCreateTask("",&taskClock);

	
	/*************************
		   CLOCK SOURCE 
	*************************/
	//CREATE INTERNAL CLOCK SOURCE
	DAQmxCreateCOPulseChanFreq(taskClock, "Dev1/ctr0", "", DAQmx_Val_Hz, 
		DAQmx_Val_Low, __DDELAY, FrameRate, .2);

	
	/*************************
		DIGITAL PULSE TRAIN
	*************************/
	//CREATE DIGITAL LINE
	DAQmxCreateDOChan(taskTrig,"Dev1/port0/line0","",DAQmx_Val_ChanPerLine);

	//SET TIMING AND STATE CLOCK SOURCE
	//Clock source is based off the analog sample clock
	DAQmxCfgSampClkTiming(taskTrig,"ao/SampleClock",FrameRate*Samps,
		DAQmx_Val_Rising,DAQmx_Val_ContSamps,Samps);
	
	/*************************
		ANALOG SAW TOOTH
	*************************/
	//CREATE ANALOG CHANNEL
	DAQmxCreateAOVoltageChan(taskAnalog,"Dev1/ao0",
			   "",-10,10.0,DAQmx_Val_Volts,NULL);
	DAQmxCreateAOVoltageChan(taskAnalog,"Dev1/ao1",
		   "",-10,10.0,DAQmx_Val_Volts,NULL);

	//SET TIMING
	DAQmxCfgSampClkTiming(taskAnalog,"",FrameRate*Samps,
		DAQmx_Val_Rising,DAQmx_Val_ContSamps,Samps);

	//GET TERMINAL NAME OF THE TRIGGER SOURCE
	GetTerminalNameWithDevPrefix(taskTrig, "Ctr0InternalOutput",trigName);
	
	//TRIGGER THE ANALOG DATA BASED OFF INTERNAL TRIGGER (CLOCK SOURCE)
	DAQmxCfgDigEdgeStartTrig(taskAnalog,trigName,DAQmx_Val_Rising);

	if (globalOptions->bVolumeScan == false)
	{
		GenSawTooth(Samps,XScanVolts_mV,XScanOffset_mV,ScanBuff);

		for (int i = 0; i< Samps; i++)
			VolBuff[i] = ScanBuff[i];

		for (int i = Samps; i < 2*Samps; i++)
			VolBuff[i] = YScanOffset_mV/1000;

		DAQmxWriteAnalogF64(taskAnalog, Samps, false ,10 ,DAQmx_Val_GroupByChannel, VolBuff,NULL,NULL);

		//GENERATE PULSE TRAIN TO TRIGGER CAMERA
		GenPulseTrain(Samps,digiBuff);
		DAQmxWriteDigitalLines(taskTrig,Samps,false,10.0,DAQmx_Val_GroupByChannel,digiBuff,NULL,NULL);
	}
	else
	{
		
		int frameCount;

		GenSawTooth(Samps,XScanVolts_mV,XScanOffset_mV,ScanBuff);
		for (frameCount = 0; frameCount < globalOptions->NumFramesPerVol; frameCount++)
		{
			
			for (int i = 0; i< Samps; i++)
				VolumeBuff[i+frameCount*Samps] = ScanBuff[i];
		}

		GenStairCase(Samps,globalOptions->NumFramesPerVol,YScanVolts_mV, YScanOffset_mV, tempBuff);

		for (int i = 0; i < Samps*globalOptions->NumFramesPerVol; i++)
			VolumeBuff[i + Samps*globalOptions->NumFramesPerVol] = tempBuff[i];

		DAQmxWriteAnalogF64(taskAnalog, Samps*globalOptions->NumFramesPerVol, false ,10 ,DAQmx_Val_GroupByChannel, VolumeBuff,NULL,NULL);

		//GENERATE PULSE TRAIN TO TRIGGER CAMERA
		for (int frameCount = 0; frameCount < globalOptions->NumFramesPerVol; frameCount++)
		{
			GenPulseTrain(Samps,digiBuff);
			for (int i = 0; i< Samps; i++)
				digiVolBuff[i+frameCount*Samps] = digiBuff[i];
		}

		DAQmxWriteDigitalLines(taskTrig,Samps*globalOptions->NumFramesPerVol,false,10.0,DAQmx_Val_GroupByChannel,digiVolBuff,NULL,NULL);
	}


	//GENERATE PULSE TRAIN TO TRIGGER CAMERA
	DAQmxCreateCOPulseChanFreq(taskTrA,"Dev1/ctr1","",DAQmx_Val_Hz,DAQmx_Val_Low,0.0,LineRate,0.2);
	DAQmxCfgImplicitTiming(taskTrA,DAQmx_Val_FiniteSamps,globalOptions->IMAGEHEIGHT);
	DAQmxCfgDigEdgeStartTrig(taskTrA,"/Dev1/PFI4",DAQmx_Val_Rising);
	DAQmxSetStartTrigRetriggerable(taskTrA, 1);
	DAQmxConnectTerms ("/Dev1/Ctr1InternalOutput", "/Dev1/RTSI0",  DAQmx_Val_DoNotInvertPolarity);
	
	//START TASKS
	//IMPORTANT - Need to arm analog task first to make sure that the digital and analog waveforms are in sync
	DAQmxStartTask(taskAnalog);
	DAQmxStartTask(taskTrA);
	DAQmxStartTask(taskTrig);
	DAQmxStartTask(taskClock);
}