207 lines
6.2 KiB
C
207 lines
6.2 KiB
C
/*********************************************************************
|
|
*
|
|
* ANSI C Example program:
|
|
* DigPulseTrain-Var.c
|
|
*
|
|
* Example Category:
|
|
* CO
|
|
*
|
|
* Description:
|
|
* This example demonstrates how to generate a continuous digital
|
|
* pulse train from a Counter Output Channel. The Frequency, Duty
|
|
* Cycle, and Idle State are all configurable.
|
|
*
|
|
* This example shows how to configure the pulse in terms of
|
|
* Frequency/Duty Cycle, but can easily be modified to generate a
|
|
* pulse in terms of Time or Ticks.
|
|
*
|
|
* Instructions for Running:
|
|
* 1. Select the Physical Channel which corresponds to the counter
|
|
* you want to output your signal to on the DAQ device.
|
|
* 2. Enter the Frequency and Duty Cycle to define the pulse
|
|
* parameters. You can also change the Idle State to determine
|
|
* the beginning and end states of the output. If the Idle State
|
|
* is High, the generation will use inverted logic.
|
|
* Additionally, you can set the Initial Delay (in seconds)
|
|
* which will delay the beginning of the pulse train from the
|
|
* start call; this is currently set to 0.0 in the code.
|
|
|
|
* Note: Use the Measure Period example to verify you are
|
|
* outputting the pulse train on the DAQ device.
|
|
*
|
|
* Steps:
|
|
* 1. Create a task.
|
|
* 2. Create a Counter Output channel to produce a Pulse in terms
|
|
* of Frequency. If the Idle State of the pulse is set to low,
|
|
* the state of the line will begin low and remain low after the
|
|
* generation is stopped.
|
|
* 3. Call the timing function to configure the duration of the
|
|
* pulse generation.
|
|
* 4. Call the Start function to arm the counter and begin the
|
|
* pulse
|
|
* train generation.
|
|
* 5. For continuous generation, the counter will continually
|
|
* generate the pulse train until stop button is pressed.
|
|
* 6. Call the Clear Task function to clear the Task.
|
|
* 7. Display an error if any.
|
|
*
|
|
* I/O Connections Overview:
|
|
* The counter will output the pulse train on the output terminal
|
|
* of the counter specified in the Physical Channel I/O control.
|
|
*
|
|
* This example uses the default output terminal for the counter of
|
|
* your device. To determine what the default counter pins for you
|
|
* device are or to set a different output terminal, refer to the
|
|
* Connecting Counter Signals topic in the NI-DAQmx Help (search
|
|
* for "Connecting Counter Signals").
|
|
*
|
|
*********************************************************************/
|
|
|
|
#define MIN_RATE (0.001)
|
|
#define MAX_RATE (20.0e6)
|
|
#define MIN_SLEEP 1
|
|
#define MAX_SLEEP 3600
|
|
#include <unistd.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <NIDAQmx.h>
|
|
|
|
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else
|
|
|
|
int32 CVICALLBACK DoneCallback(TaskHandle taskHandle, int32 status, void *callbackData);
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
int error=0;
|
|
TaskHandle taskHandle=0;
|
|
char errBuff[2048]={'\0'};
|
|
char* base_ptr = "";
|
|
char* range_ptr = "";
|
|
char* sleep_ptr = "";
|
|
double range = 1000.0;
|
|
double base_rate = 0.0;
|
|
int sleep_time = MAX_SLEEP;
|
|
int idx = 1;
|
|
char device[100] = "Dev1/Ctr1";
|
|
|
|
if (argc > idx
|
|
&& toupper(argv[idx][0]) == 'D'
|
|
&& toupper(argv[idx][1]) == 'E'
|
|
&& toupper(argv[idx][2]) == 'V')
|
|
{
|
|
strncpy(device, argv[idx], sizeof(device));
|
|
++idx;
|
|
}
|
|
if (argc > idx)
|
|
{
|
|
range_ptr = argv[idx];
|
|
range = (double) atof(range_ptr);
|
|
++idx;
|
|
}
|
|
if (range < MIN_RATE)
|
|
range = MIN_RATE;
|
|
if (range > MAX_RATE)
|
|
range = MAX_RATE;
|
|
if (argc > idx)
|
|
{
|
|
base_ptr = range_ptr;
|
|
base_rate = range;
|
|
range_ptr = argv[idx];
|
|
range = (double) atof(range_ptr);
|
|
if (base_rate + range > MAX_RATE)
|
|
range = MAX_RATE - base_rate;
|
|
++idx;
|
|
sleep_time = MIN_SLEEP;
|
|
}
|
|
printf("Input of '%s' gives base of %g\n", base_ptr, base_rate);
|
|
printf("Input of '%s' gives range of %g\n", range_ptr, range);
|
|
if (argc > idx)
|
|
{
|
|
sleep_ptr = argv[idx];
|
|
sleep_time = atoi(sleep_ptr);
|
|
if (sleep_time < MIN_SLEEP)
|
|
sleep_time = MIN_SLEEP;
|
|
if (sleep_time > MAX_SLEEP)
|
|
sleep_time = MAX_SLEEP;
|
|
++idx;
|
|
}
|
|
else if (range == 0)
|
|
sleep_time = MAX_SLEEP;
|
|
printf("Input of '%s' gives loop time of %d\n", sleep_ptr, sleep_time);
|
|
|
|
/*********************************************/
|
|
// DAQmx Configure Code
|
|
/*********************************************/
|
|
while (1)
|
|
{
|
|
double this_rate;
|
|
double rval;
|
|
rval = (double) random() / (double) RAND_MAX;
|
|
this_rate = range * rval;
|
|
this_rate += base_rate;
|
|
if (this_rate < MIN_RATE)
|
|
this_rate = MIN_RATE;
|
|
printf("Pulse train on %s at %f Hz.\n", device, this_rate);
|
|
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
|
|
DAQmxErrChk (DAQmxCreateCOPulseChanFreq(taskHandle,
|
|
device,
|
|
"",
|
|
DAQmx_Val_Hz,
|
|
DAQmx_Val_Low,
|
|
0.0,
|
|
this_rate,
|
|
0.50));
|
|
DAQmxErrChk (DAQmxCfgImplicitTiming(taskHandle,DAQmx_Val_ContSamps,1000));
|
|
|
|
DAQmxErrChk (DAQmxRegisterDoneEvent(taskHandle,0,DoneCallback,NULL));
|
|
|
|
/*********************************************/
|
|
// DAQmx Start Code
|
|
/*********************************************/
|
|
DAQmxErrChk (DAQmxStartTask(taskHandle));
|
|
|
|
do {
|
|
sleep(sleep_time);
|
|
} while (range == 0);
|
|
|
|
DAQmxStopTask(taskHandle);
|
|
DAQmxClearTask(taskHandle);
|
|
taskHandle = 0;
|
|
}
|
|
|
|
Error:
|
|
if( DAQmxFailed(error) )
|
|
DAQmxGetExtendedErrorInfo(errBuff,2048);
|
|
if( taskHandle!=0 ) {
|
|
/*********************************************/
|
|
// DAQmx Stop Code
|
|
/*********************************************/
|
|
DAQmxStopTask(taskHandle);
|
|
DAQmxClearTask(taskHandle);
|
|
}
|
|
if( DAQmxFailed(error) )
|
|
printf("DAQmx Error: %s\n",errBuff);
|
|
printf("End of program, press Enter key to quit\n");
|
|
getchar();
|
|
return 0;
|
|
}
|
|
|
|
int32 CVICALLBACK DoneCallback(TaskHandle taskHandle, int32 status, void *callbackData)
|
|
{
|
|
int32 error=0;
|
|
char errBuff[2048]={'\0'};
|
|
|
|
// Check to see if an error stopped the task.
|
|
DAQmxErrChk (status);
|
|
|
|
Error:
|
|
if( DAQmxFailed(error) ) {
|
|
DAQmxGetExtendedErrorInfo(errBuff,2048);
|
|
DAQmxClearTask(taskHandle);
|
|
printf("DAQmx Error: %s\n",errBuff);
|
|
}
|
|
return 0;
|
|
}
|