| ioPAC RTU Controllers C/C++ Sample Code Programming Guide

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

Macros | Functions
fast_ai.c File Reference

Fast AI Sample More...

`#include <libmoxa_rtu.h>`

## Macros
#define | DEFAULT_OUT_NAME "fast_ai_data.csv"

## Functions
int | main (int argc, char **const argv)

## Detailed Description

Fast AI Sample

Copyright
  Moxa Inc.

Date
  04-16-2013

Author
  Wanhan Hsieh

Version
  V1.0
  Fast AI Sample

    Introduction:
    This is fast AI sample code. The controller will trigger the fast AI module to record data when the DI is triggered,
    and then store the obtained batch data into a file.
    Example:
    1. Using default: ./fast_ai
    2. Setting fast AI channel and sampling rate: ./fast_ai -c3 -r5000
    Default:
    Slot of DI module = 1
    Slot of fast AI module = 2
    Channel on fast AI module = 0
    Samplig rate = 500
    Fore interval = 1
    Back interval = 1
    Output file name = fast_ai_data.csv
    Burnout value = 0
    Help:

    root@Moxa:/tmp#./fast_ai -h
    Fast AI sample program.

    Usage: ./fast_ai [OPTIONS]

    Options:
        -i      Slot of DI module [1-9]. Default slot = 1
        -s      Slot of fast AI module [1-9]. Default slot = 2
        -c      Channel on Fast AI module [0-7]. Default channel = 0
        -r      Samplig rate [10-5000]. Default rate = 500
        -f      Fore interval [0-3]. Default interval = 1
        -b      Back interval [0-3]. Default interval = 1
        -o      Output file name. Default name = fast_ai_data.csv
        -l      Burnout value[0.000000-4.000000]. Default value = 0.000000

Library:
FAST_AI APIs

## Macro Definition Documentation

#define DEFAULT_OUT_NAME "fast_ai_data.csv"

## Function Documentation

int main | ( | int | argc,
|  | char **const | argv
| ) |  |

/*******************************************************************************
* Copyright Moxa Inc.
*
* Fast AI Sample Application
*
* Date Author Comment
* 04-16-2013 Wanhan Hsieh Created.
******************************************************************************/
#include <libmoxa_rtu.h>
#define DEFAULT_OUT_NAME "fast_ai_data.csv"
int main(int argc, char **const argv)
{
int rc, i;
UINT32 diSlot = 1;
UINT32 aiSlot = 2, slotMin = 0, slotMax = 0;
UINT32 aiChannel = 0, channelMin = 0, channelMax = 7;
UINT8 range = AI_RANGE_4_20mA;
UINT32 rate = 200, rateMin = 10, rateMax = 5000;
UINT32 foreInterval = 1, intervalMin = 0, intervalMax = 3;
UINT32 backInterval = 1;
float burnout = 0.0, burnoutMin = 0.0, burnoutMax = 4.0;
char szOutFlieName[64];
FILE *pOutFile;
UINT8 diMode;
struct Timestamp diTriggerTime;
UINT32 u32Val = 0;
UINT32 triggerFlags = 0x1 << aiChannel;
int isDISet = 0, isTriggered = 0;
UINT8 *buf;
struct Timestamp aiTime;
UINT32 requiredBufSize;
MX_RTU_Total_Slots_Get(&slotMax);
memset(szOutFlieName, 0, sizeof(szOutFlieName));
strncpy(szOutFlieName, DEFAULT_OUT_NAME, strlen(DEFAULT_OUT_NAME));
while(-1 != (rc = getopt(argc, argv, "hi:s:c:r:f:b:o:l:")))
{
switch(rc)
{
case 'i':
diSlot = atoi(optarg);
if(diSlot < slotMin || diSlot > slotMax)
{
printf("Error parameter: slot: %d\n", diSlot);
return -1;
}
break;
case 's':
aiSlot = atoi(optarg);
if(aiSlot < slotMin || aiSlot > slotMax)
{
printf("Error parameter: slot: %d\n", aiSlot);
return -1;
}
break;
case 'c':
aiChannel = atoi(optarg);
if(aiChannel < channelMin || aiChannel > channelMax)
{
printf("Error parameter: channel: %d\n", aiChannel);
return -1;
}
triggerFlags = 0x1 << aiChannel;
break;
case 'r':
rate = atoi(optarg);
if(rate < rateMin)
rate = rateMin;
if(rate > rateMax)
rate = rateMax;
break;
case 'f':
foreInterval = atoi(optarg);
if(foreInterval > intervalMax)
foreInterval = intervalMax;
break;
case 'b':
backInterval = atoi(optarg);
if(backInterval > intervalMax)
backInterval = intervalMax;
break;
case 'l':
burnout = atoi(optarg);
if(burnout < burnoutMin)
burnout = burnoutMin;
if(burnout > burnoutMax)
burnout = burnoutMax;
break;
case 'o':
memset(szOutFlieName, 0, sizeof(szOutFlieName));
strncpy(szOutFlieName, optarg, strlen(optarg));
break;
case '?':
case 'h':
default:
printf("Fast AI sample program.\n\n");
printf("Usage: ./fast_ai [OPTIONS]\n\n");
printf("Options:\n");
printf("\t%-8s Slot of DI module [%d-%d]. Default slot = %d\n",
"-i", slotMin, slotMax, diSlot);
printf("\t%-8s Slot of fast AI module [%d-%d]. Default slot = %d\n",
"-s", slotMin, slotMax, aiSlot);
printf("\t%-8s Channel on Fast AI module [%d-%d]. Default channel = %d\n",
"-c", channelMin, channelMax, aiChannel);
printf("\t%-8s Samplig rate [%d-%d]. Default rate = %d\n",
"-r", rateMin, rateMax, rate);
printf("\t%-8s Fore interval [%d-%d]. Default interval = %d\n",
"-f", intervalMin, intervalMax, foreInterval);
printf("\t%-8s (One unit = 1sec)\n", "");
printf("\t%-8s Back interval [%d-%d]. Default interval = %d\n",
"-b", intervalMin, intervalMax, backInterval);
printf("\t%-8s (One unit = 1sec)\n", "");
printf("\t%-8s Output file name. Default name = %s\n",
"-o", szOutFlieName);
printf("\t%-8s Burnout value[%f-%f]. Default value = %f\n",
"-l", burnoutMin, burnoutMax, burnout);
printf("\n");
return 0;
}
}
printf("%-10s: %d\n", "DI slot", diSlot);
printf("%-10s: %d\n", "AI slot", aiSlot);
printf("%-10s: %d\n", "AI channel", aiChannel);
printf("%-10s: %d\n", "rate", rate);
printf("%-10s: %d\n", "fore", foreInterval);
printf("%-10s: %d\n", "back", backInterval);
printf("%-10s: %s\n", "output", szOutFlieName);
printf("%-10s: %.3f\n", "burnout", burnout);
rc = MX_RTU_Module_Fast_AI_Range_Get(aiSlot, 0, 1, &range);
if(rc != MODULE_RW_ERR_OK)
printf("MX_RTU_Module_Fast_AI_Range_Set(%d, %d, %d), return code = %d.\n",
aiSlot, 0, 1, rc);
printf("%-10s: %d\n", "range", range);
pOutFile = fopen(szOutFlieName, "w");
if(pOutFile == NULL)
{
fprintf(stderr, "Error open file: %s\n", szOutFlieName);
return -1;
}
// Config DI module
diMode = DI_MODE_DI;
rc = MX_RTU_Module_DI_Mode_Set(diSlot, 0, 1, &diMode);
if(rc != MODULE_RW_ERR_OK)
printf("MX_RTU_Module_DI_Mode_Set(%d, %d, %d), return code = %d.\n",
diSlot, 0, 1, rc);
// Config Fast AI module
rc = MX_RTU_Module_Fast_AI_Sampling_Rate_Set(aiSlot, rate);
if(rc != MODULE_RW_ERR_OK)
printf("MX_RTU_Module_Fast_AI_Sampling_Rate_Set(%d, %d), return code = %d.\n",
aiSlot, rate, rc);
rc = MX_RTU_Module_Fast_AI_Sampling_Rate_Get(aiSlot, &rate);
if(rc != MODULE_RW_ERR_OK)
printf("MX_RTU_Module_Fast_AI_Sampling_Rate_Get(%d), return code = %d.\n", aiSlot, rc);
else
printf("Sampling Rate = %d\n", rate);
rc = MX_RTU_Module_Fast_AI_Buf_Overflow_Reset(aiSlot, triggerFlags);
if(rc != MODULE_RW_ERR_OK)
printf("MX_RTU_Module_Fast_AI_Buf_Overflow_Reset(%d, %d), return code = %d.\n",
aiSlot, triggerFlags, rc);
rc = MX_RTU_Module_Fast_AI_Burnout_Value_Set(aiSlot, aiChannel, 1, &burnout);
if(rc != MODULE_RW_ERR_OK)
printf("MX_RTU_Module_Fast_AI_Burnout_Value_Set(%d, %d, %d), return code = %d.\n",
aiSlot, aiChannel, 1, rc);
// Start to polling DI
do
{
rc = MX_RTU_Module_DI_Value_Get(diSlot, &u32Val, &diTriggerTime);
if(rc != MODULE_RW_ERR_OK)
{
printf("MX_RTU_Module_DI_Value_Get(%d), return code = %d.\n", diSlot, rc);
break;
}
else if(u32Val & 0x1 != 0)
{
isDISet = 1;
}
}
while(!isDISet);
// Trigger Fast AI
if(isDISet)
{
printf("Trigger Fast AI !\n");
do
{
rc = MX_RTU_Module_Fast_AI_Trigger_Set(aiSlot, triggerFlags,
foreInterval, backInterval, &requiredBufSize);
if(rc != MODULE_RW_ERR_OK &&
rc != MODULE_RW_ERR_IO_FAST_AI_NOT_READY)
printf("MX_RTU_Module_Fast_AI_Trigger_Set(%d, 0x%02X, %d, %d), return code = %d.\n",
aiSlot, triggerFlags, foreInterval, backInterval, rc);
else
isTriggered = 1;
}
while(rc == MODULE_RW_ERR_IO_FAST_AI_NOT_READY);
}
// Get Fast AI data
if(isTriggered)
{
buf = (UINT8*) malloc(requiredBufSize);
if(buf == NULL)
{
fprintf(stderr, "Error allocate memory\n");
return -1;
}
do
{
rc = MX_RTU_Module_Fast_AI_Batch_Data_Get(aiSlot, aiChannel,
foreInterval, backInterval, buf, &aiTime);
if(rc == MODULE_RW_ERR_OK)
{
UINT16 raw;
float eng;
fprintf(pOutFile, "DI Trigger time: %02d:%02d:%02d.%02d\n",
diTriggerTime.hour, diTriggerTime.min, diTriggerTime.sec,
diTriggerTime.msec);
fprintf(pOutFile, "AI data start time: %02d:%02d:%02d.%02d\n",
aiTime.hour, aiTime.min, aiTime.sec, aiTime.msec);
for(i = 0; i < requiredBufSize; i += 2)
{
memcpy(&raw, &buf[i], 2);
MX_RTU_AIO_Raw_to_Eng(range, 16, raw, &eng);
fprintf(pOutFile, "%f\n", eng);
}
printf("Save AI data into %s.\n", szOutFlieName);
break;
}
else if(rc != MODULE_RW_ERR_IO_FAST_AI_BUF_EMPTY)
{
printf("MX_RTU_Module_Fast_AI_Batch_Data_Get(%d, %d, %d, %d), return code = %d.\n",
aiSlot, aiChannel, foreInterval, backInterval, rc);
}
}
while(rc == MODULE_RW_ERR_IO_FAST_AI_BUF_EMPTY);
}
free(buf);
fclose(pOutFile);
return 0;
}