206 lines
5.5 KiB
C
206 lines
5.5 KiB
C
/*********************************************************************
|
|
*
|
|
* ANSI C program:
|
|
* Monitor.c
|
|
*
|
|
* Description:
|
|
* This program counts digital events on a NI-6602
|
|
* Counter Input Channel. The Device, Counter Channel, Initial Count, Count
|
|
* Direction, and are all configurable.
|
|
*
|
|
* Edges are counted on the counter's default input terminal (refer
|
|
* to the I/O Connections Overview section below for more
|
|
* information), but could easily be modified to count edges on a
|
|
* PFI or RTSI line.
|
|
*
|
|
* Instructions for Running:
|
|
* 1. Select the Device and Channel which corresponds to the counter
|
|
* you want to count on.
|
|
* 2. Select the TCP/IP port number you want to listen on.
|
|
* 3. Enter the Initial Count, Count Direction, to specify how you want
|
|
* the counter to count.
|
|
*
|
|
* Steps:
|
|
* 1. Create a task.
|
|
* 2. Create a Counter Input channel to Count Events. The Edge
|
|
* parameter is used to determine if the counter will increment
|
|
* on rising or falling edges.
|
|
* 3. Call the Start function to arm the counter and begin
|
|
* counting. The counter will be preloaded with the Initial
|
|
* Count.
|
|
* 4. The counter will be continually polled.
|
|
* 5. Call the Clear Task function to clear the Task.
|
|
* 6. Display an error if any.
|
|
*
|
|
*********************************************************************/
|
|
|
|
#define CNTR_CHK(func) if (cntr_fatal(error=(func))) goto Error; else
|
|
|
|
#include "Monitor.h"
|
|
#include "utility.h"
|
|
#include "params.h"
|
|
#include "sock.h"
|
|
#include "cntr.h"
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <libiberty.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
|
|
#define MAX_COUNTERS 8
|
|
|
|
int usage(int argc, char* argv[], const char* reason)
|
|
{
|
|
int i;
|
|
fprintf(stderr, "%s", argv[0]);
|
|
for (i = 1; i < argc; ++i)
|
|
fprintf(stderr, " %s", argv[i]);
|
|
fprintf(stderr, "\n%s\n", reason);
|
|
fprintf(stderr, "usage: %s <DEVn/CTRn> <PORT>\n",
|
|
argv[0]);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
int error=0;
|
|
char errBuff[2048]={'\0'};
|
|
struct timeval now;
|
|
uint64 last_poll;
|
|
char* device = DEFAULT_COUNTER_DEVICE;
|
|
uint dev_no;
|
|
int port = DEFAULT_LISTEN_PORT;
|
|
int idx = 1;
|
|
COUNTER* counters[MAX_COUNTERS];
|
|
|
|
if (idx >= argc)
|
|
return usage(argc, argv, "no args");
|
|
if (argv[idx][0] == '-')
|
|
{
|
|
if (tolower(argv[idx][1]) == 'd')
|
|
{
|
|
if (isdigit(argv[idx][2]))
|
|
set_debug_level(argv[idx][2] - '0');
|
|
else
|
|
set_debug_level(0);
|
|
}
|
|
++idx;
|
|
}
|
|
|
|
if (idx >= argc)
|
|
return usage(argc, argv, "no device");
|
|
if (tolower(argv[idx][0]) == 'd' &&
|
|
tolower(argv[idx][1]) == 'e' &&
|
|
tolower(argv[idx][2]) == 'v' &&
|
|
isdigit(argv[idx][3]))
|
|
{
|
|
device = argv[idx];
|
|
++idx;
|
|
}
|
|
else if (tolower(argv[idx][0]) == 'p' &&
|
|
tolower(argv[idx][1]) == 'x' &&
|
|
tolower(argv[idx][2]) == 'i' &&
|
|
isdigit(argv[idx][3]))
|
|
{
|
|
device = argv[idx];
|
|
++idx;
|
|
}
|
|
else
|
|
return usage(argc, argv, "bad device");
|
|
|
|
if (idx >= argc)
|
|
return usage(argc, argv, "no port");
|
|
if (isdigit(argv[idx][0]))
|
|
{
|
|
port = 10 * (atoi(argv[idx]) / 10);
|
|
++idx;
|
|
}
|
|
else
|
|
return usage(argc, argv, "bad port");
|
|
|
|
dev_no = atoi(&device[3]);
|
|
sock_init();
|
|
gettimeofday(&now, NULL);
|
|
for (idx = 0; idx < MAX_COUNTERS; ++idx)
|
|
{
|
|
sprintf(device, "dev%d/ctr%d", dev_no, idx);
|
|
CNTR_CHK(cntr_init(&counters[idx], device));
|
|
sock_listen(port + idx, cntr_command, counters[idx]);
|
|
counters[idx]->current_time = now;
|
|
}
|
|
|
|
printf("Continuously polling. Press Ctrl+C to interrupt\n");
|
|
last_poll = 1000 * (uint64) now.tv_sec + now.tv_usec / 1000;
|
|
while (1)
|
|
{
|
|
uint64 timeofday;
|
|
int timeout = 0;
|
|
int next_timeout = 0;
|
|
do {
|
|
next_timeout = 1000;
|
|
sock_check(timeout);
|
|
gettimeofday(&now, NULL);
|
|
timeofday = 1000 * (uint64) now.tv_sec + now.tv_usec / 1000;
|
|
for (idx = 0; idx < MAX_COUNTERS; ++idx)
|
|
{
|
|
COUNTER* cp = counters[idx];
|
|
PARAMETERS* pp = &cp->params;
|
|
last_poll = 1000 * (uint64) cp->current_time.tv_sec
|
|
+ cp->current_time.tv_usec / 1000;
|
|
if (timeofday / pp->poll_period > last_poll / pp->poll_period)
|
|
timeout = 0;
|
|
else
|
|
{
|
|
timeout = pp->poll_period - timeofday % pp->poll_period;
|
|
if (timeout < 0)
|
|
{
|
|
if (timeout < 0)
|
|
dbg_printf(0, "Poll timeout < 0 at %d\n", timeout);
|
|
timeout = 0;
|
|
}
|
|
}
|
|
if (timeout < next_timeout)
|
|
next_timeout = timeout;
|
|
if (timeout == 0)
|
|
{
|
|
cp->current_time = now;
|
|
#if 1
|
|
dbg_printf(0, "%d:-%s %s %.3f %s %.3f %4d\n",
|
|
idx,
|
|
make_timestamp(&cp->current_time),
|
|
make_timestamp(&cp->sample_timer),
|
|
cntr_time_to_next_sample(cp),
|
|
make_timestamp(&cp->report_timer),
|
|
cntr_time_to_next_report(cp),
|
|
cp->sample_index);
|
|
#endif
|
|
CNTR_CHK(cntr_poll(cp));
|
|
}
|
|
}
|
|
if (next_timeout > 999)
|
|
next_timeout = 1;
|
|
timeout = next_timeout;
|
|
//dbg_printf(0, "Poll timeout = %d\n", timeout);
|
|
} while (timeout > 0);
|
|
}
|
|
|
|
Error:
|
|
puts("");
|
|
if (cntr_fatal(error))
|
|
{
|
|
cntr_errmsg(errBuff, sizeof(errBuff));
|
|
printf("DAQmx Error: %s\n", errBuff);
|
|
}
|
|
for (idx = 0; idx < MAX_COUNTERS; ++idx)
|
|
cntr_term(counters[idx]);
|
|
printf("End of program\n");
|
|
return 0;
|
|
}
|