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

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

Macros | Functions
ioPAC8500_tag_fast_ai.c File Reference

ioPAC8500 Fast AI TAG 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

ioPAC8500 Fast AI TAG Sample

Copyright
  Moxa Inc.

Date
  02-28-2014

Author
  TJ Tai

Version
  V1.0
  Fast AI TAG Sample

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

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

    Usage: ./ioPAC8500_tag_fast_ai [OPTIONS]

    Options:
        -i      Slot of DI module [1-9]. Default slot = 1
        -s      Slot of fast AI module [1-9]. Default slot = 3
        -c      Channel on Fast AI module [0-7]. Default channel = 0
        -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

Library:
TAG APIs
RTUxpress Project file:
ioPAC8500_tag_fast_ai.rtu
(Please right click on the link and ‘Save Target As…’ to save RTUxpress project file and open it with RTUxpress utility)

## 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 TAG Sample Application
*
* Date Author Comment
* 02-28-2014 TJ Tai Created.
******************************************************************************/
#include <libmoxa_rtu.h>
#define DEFAULT_OUT_NAME "fast_ai_data.csv"
int main(int argc, char **const argv)
{
int rc, i;
TAG_ERR_CODE retval = 0;
TAG_INFO tagInfo;
UINT32 diSlot = 1;
UINT32 aiSlot = 3, slotMin = 0, slotMax = 9;
UINT32 aiChannel = 0, channelMin = 0, channelMax = 7;
UINT32 foreInterval = 1, intervalMin = 0, intervalMax = 3;
UINT32 backInterval = 1;
char szOutFlieName[64];
FILE *pOutFile;
memset(szOutFlieName, 0, sizeof(szOutFlieName));
strncpy(szOutFlieName, DEFAULT_OUT_NAME, strlen(DEFAULT_OUT_NAME));
struct Timestamp diTriggerTime;
UINT32 u32Val = 0;
UINT32 triggerFlags = 0x1 << aiChannel;
int isDISet = 0, isTriggered = 0;
UINT8 *buf;
struct Timestamp aiTime;
UINT32 requiredBufSize;
UINT8 range = AI_RANGE_4_20mA;
int diChannelAmount = 16;
char ai[8][TAG_MAX_NAME_SIZE];
char di_tagName[diChannelAmount][TAG_MAX_NAME_SIZE];
while(-1 != (rc = getopt(argc, argv, "hi:s:c:f:b:o:")))
{
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 'f':
foreInterval = atoi(optarg);
if(foreInterval > intervalMax)
foreInterval = intervalMax;
break;
case 'b':
backInterval = atoi(optarg);
if(backInterval > intervalMax)
backInterval = intervalMax;
break;
case 'o':
memset(szOutFlieName, 0, sizeof(szOutFlieName));
strncpy(szOutFlieName, optarg, strlen(optarg));
break;
case '?':
case 'h':
default:
printf("Fast AI TAG sample program.\n\n");
printf("Usage: ./ioPAC8500_tag_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 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("\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", "fore", foreInterval);
printf("%-10s: %d\n", "back", backInterval);
printf("%-10s: %s\n", "output", szOutFlieName);
sprintf(ai[0], "S%d_AI%d_AIMaxValue", aiSlot, aiChannel);
sprintf(ai[1], "S%d_AI%d_AIMinValue", aiSlot, aiChannel);
sprintf(ai[2], "S%d_AI%d_BurnOutState", aiSlot, aiChannel);
sprintf(ai[3], "S%d_AI%d_EngineeringValue", aiSlot, aiChannel);
sprintf(ai[4], "S%d_AI%d_RawMaxValue", aiSlot, aiChannel);
sprintf(ai[5], "S%d_AI%d_RawMinValue", aiSlot, aiChannel);
sprintf(ai[6], "S%d_AI%d_RawValue", aiSlot, aiChannel);
sprintf(ai[7], "S%d_AI%d_ResetMaxMin", aiSlot, aiChannel);
retval = MX_RTU_Tag_Init();
if(retval != TAG_ERR_OK)
{
printf("MX_RTU_Tag_Init(), return code = %d.\n", retval);
return 0;
}
pOutFile = fopen(szOutFlieName, "w");
if(pOutFile == NULL)
{
fprintf(stderr, "Error open file: %s\n", szOutFlieName);
return -1;
}
// Config DI tag
for(i = 0; i < diChannelAmount; i++)
{
sprintf(di_tagName[i], "S%d_DI%d_DIValue", diSlot, i);
}
// Config Fast AI module
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);
// Start to polling DI0
do
{
rc = MX_RTU_Tag_Read(di_tagName[0], &u32Val, sizeof(u32Val), NULL, NULL);
if(rc != TAG_ERR_OK)
{
printf("MX_RTU_Tag_Read(%s) = %d\n", di_tagName[0], 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);
retval = MX_RTU_Tag_Uninit();
if(retval != TAG_ERR_OK)
{
printf("MX_RTU_Tag_Uninit(), return code = %d\n", retval);
}
return 0;
}