Files
sics/site_ansto/hardsup/Monitor/Pulser.c
Douglas Clowes d643fbef6a ignore periodicity if not given
r1122 | dcl | 2006-10-09 12:22:28 +1000 (Mon, 09 Oct 2006) | 2 lines
2012-11-15 12:47:28 +11:00

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;
}