.

     

MPI Application Template
template.c
 

record5.c -- Record data with a continuous recorder.
/* record5.c */

/* Copyright(c) 1991-2007 by Motion Engineering, Inc.  All rights reserved.
 *
 * This software  contains proprietary and  confidential information  of
 * Motion Engineering Inc., and its suppliers.  Except as may be set forth
 * in the license agreement under which  this software is supplied, use,
 * disclosure, or  reproduction is prohibited without the prior express
 * written consent of Motion Engineering, Inc.
 */

/*

:Record data with a continuous recorder
  
  This program demonstrates how to use a continuous recorder to
  record data gathered from an analog input source and perform
  data analysis on each MPIEventTypeRECORDER_HIGH event.

  The result can also be written to a text file using the processRecord function.

  Upon each MPIEventTypeRECORDER_HIGH event, the function analyzeData will
  loop through the data records and increment variable dataAnalysisResult 
  when the input triggers a user defined limit.

Warning!  This is a sample program to assist in the integration of an
 MEI motion controller with your application.  It may not contain all
 of the logic and safety features that your application requires.
 
The msgCHECK(...) macros used in the following sample code are intended
 to convey our strong belief that ALL error return codes should be checked.
 Actual application code should use specific error handling techniques (other
 than msgCHECKs) best suited to your internal error recovery methods.
 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "stdmpi.h"
#include "stdmei.h"

#include "apputil.h"

#define RECORDER_NUMBER (0)
#define SQNODE_NUMBER   (0)

#define INPUT_CHANNEL   (0)
#define INPUT_MASK      (0x0000FFFF)

#define PERIOD          (0)      /* Record every sample */
#define RECORD_COUNT    (2000)   /* Size of recorder records */
#define POINT_COUNT     (1)      /* Number of data points */

/* User defined trigger */
#define SCHMITTLOW      (2000)
#define SCHMITTHIGH     (4000)

/* Number of records recorded before MPIEventTypeRECORDER_HIGH is triggerred. */
#define HIGH_COUNT      (2000)   

long  dataAnalysisResult = 0;

/* Perform basic command line parsing. (-control -server -port -trace) */
void basicParsing(int                    argc,
                  char                  *argv[],
                  MPIControlType        *controlType,
                  MPIControlAddress     *controlAddress)
{
    long argIndex;

    /* Parse command line for Control type and address */
    argIndex = argControl(argc, argv, controlType, controlAddress);

    /* Check for unknown/invalid command line arguments */
    if (argIndex < argc) {
        fprintf(stderr,"usage: %s %s\n", argv[0], ArgUSAGE);
        exit(MPIMessageARG_INVALID);
    }
}

/* Create and initialize MPI objects */
void programInit(MPIControl         *control,
                 MPIControlType      controlType,
                 MPIControlAddress  *controlAddress,
                 MPIRecorder        *recorder,
                 MPIRecorderRecord **records,
                 long                recordCount,
                 MEISqNode          *sqNode,
                 long                sqNodeNumber,
                 MPIEventMgr        *eventMgr,
                 MPINotify          *notify,
                 Service       *service)
{
    MPIEventMask      eventMask;
    MPIRecorderStatus recorderStatus;

    long          returnValue;

    /* Create motion controller object */
    *control =
        mpiControlCreate(controlType,
                         controlAddress);
    msgCHECK(mpiControlValidate(*control));

    /* Initialize motion controller */
    returnValue =
        mpiControlInit(*control);
    msgCHECK(returnValue);

    /* Create recorder object */
    *recorder =
        mpiRecorderCreate(*control, -1);
    msgCHECK(mpiRecorderValidate(*recorder));

    /* Create sqNode object */
    *sqNode =
        meiSqNodeCreate(*control, sqNodeNumber);
    msgCHECK(meiSqNodeValidate(*sqNode));

    /* Request notification of ALL events from recorder */
    mpiEventMaskCLEAR(eventMask);
    mpiEventMaskRECORDER(eventMask);
    returnValue =
      mpiRecorderEventNotifySet(*recorder,
                                eventMask,
                                NULL);
   msgCHECK(returnValue);

    /* Create event notification object for recorder*/
    *notify =
        mpiNotifyCreate(eventMask,
                        *recorder);
    msgCHECK(mpiNotifyValidate(*notify));

    /* Create event manager object */
    *eventMgr =
        mpiEventMgrCreate(*control);
    msgCHECK(mpiEventMgrValidate(*eventMgr));

    /* Append notify to event manager */
    returnValue =
        mpiEventMgrNotifyAppend(*eventMgr, *notify);
    msgCHECK(returnValue);

   /* Create service thread */
   *service =
      serviceCreate(*eventMgr,
                    -1,    /* default (max) priority */
                    -1);   /* -1 => enable interrupts */
   meiAssert(*service != NULL);

   returnValue =
      mpiRecorderStatus(*recorder,
                        &recorderStatus,
                        NULL);
   msgCHECK(returnValue);

    /* Allocate memory for record buffer */
    *records =
        (MPIRecorderRecord *)meiPlatformAlloc(sizeof(MPIRecorderRecord) *
                                              recordCount);
    meiAssert(*records != NULL);
}

/* Perform certain cleanup actions and delete MPI objects */
void programCleanup(MPIControl          *control,
                    MPIRecorder         *recorder,
                    MPIRecorderRecord   *records,
                    long                recordCount,
                    MEISqNode           *sqNode,
                    MPIEventMgr         *eventMgr,
                    MPINotify           *notify,
                    Service             *service)
{
    long            returnValue;

     /* Free recorder buffer */
    returnValue =
        meiPlatformFree(records,
                        (sizeof(MPIRecorderRecord) * recordCount));
    meiAssert(returnValue == MPIMessageOK);

    /* Delete service */
    returnValue =
        serviceDelete(*service);
    msgCHECK(returnValue);

    *service = MPIHandleVOID;

    /* Delete event manager object */
    returnValue =
        mpiEventMgrDelete(*eventMgr);
    msgCHECK(returnValue);
    *eventMgr = MPIHandleVOID;

    /* Delete event notification object */
    returnValue =
        mpiNotifyDelete(*notify);
    msgCHECK(returnValue);
    *notify = MPIHandleVOID;

    /* Delete sqNode object */
    returnValue =
        meiSqNodeDelete(*sqNode);
    msgCHECK(returnValue);
    *sqNode = MPIHandleVOID;

    /* Delete recorder object */
    returnValue =
        mpiRecorderDelete(*recorder);
    msgCHECK(returnValue);
    *recorder = MPIHandleVOID;

    /* Delete motion controller object */
    returnValue =
        mpiControlDelete(*control);
    msgCHECK(returnValue);
    *control = MPIHandleVOID;
}

/* Print the records */
void analyzeData(MPIRecorderRecord *records,
                 long recordCount,
                 long inputMask)
{
    MPIRecorderRecord   *recordPtr;
         long           recordIndex;
         MPI_BOOL       trigger = FALSE;

    /* Output record buffer to screen */
   for(recordIndex = 0; recordIndex < recordCount; recordIndex++){
        /* Cast records to MPIRecorderRecord pointer */
        recordPtr = (MPIRecorderRecord *)&records[recordIndex];
      /* Disable trigger when input is HIGH */
      if ((recordPtr->point[0] & inputMask) > SCHMITTHIGH && trigger == TRUE)
      {
         trigger = FALSE;
         dataAnalysisResult = dataAnalysisResult + 1;
         printf("pills: %d\r", dataAnalysisResult);
      }
      /* Reset trigger when input is LOW */
      if ((recordPtr->point[0] & inputMask) < SCHMITTLOW && trigger == FALSE)
         trigger = TRUE;
   }/* end for */
}

void writeDataToFile(MPIRecorderRecord  *Record,
                long recordCount,
                long writeToFile)
{
   /* Make sure there are records to analyze */
   if (recordCount > 0)
   {
      FILE                 *outfile;
      MPIRecorderRecord    *record;

      /* Open file if writing to file */
      if(writeToFile)outfile = fopen("records.txt", "a+");

      if (writeToFile?(outfile == NULL):0) /* only check if writing to file */
      { /* Error opening file */
         fprintf(stderr,
               "Could not open output file %s.\n",
               "records.txt");
      }
      else
      {
         long  recordIndex;

       fprintf(writeToFile?outfile:stderr,"Recording started\n");
         /* Loop through all the records */
         for (recordIndex = 0; recordIndex < recordCount; recordIndex++)
         {
         record = (MPIRecorderRecord *)&Record[recordIndex];

         fprintf(writeToFile?outfile:stderr,"%ld",record->point[0]);
         fprintf(writeToFile?outfile:stderr,"\n");
       }/* End for */

      /* Close file at end of loop */
       if(writeToFile)fclose(outfile);
      }
   }
}

/* Configure recorder */
configRecorder(MPIRecorder recorder,
            MEISqNode  sqNode,
            long       highCount,
            long       period,
            long       pointCount,
            long       inputMask)
{
   MPIRecorderConfig   recorderConfig;      /* data recorder configuration handle */
   long               *analogPtr;           /* analog input pointer */
   long                returnValue;         /* return value from library */

   /* Get analog input pointer */
   returnValue =
      meiSqNodeAnalogInPtr(sqNode,
                           INPUT_CHANNEL,
                           &inputMask,
                           &analogPtr);
   msgCHECK(returnValue);

   /* Set recorder record type */
   returnValue =
      mpiRecorderRecordConfig(recorder,
                              MPIRecorderRecordTypePOINT,
                              pointCount,
                              &analogPtr);
   msgCHECK(returnValue);

   /* Get recorder configuration handle */
   returnValue =
      mpiRecorderConfigGet(recorder,
                           &recorderConfig,
                           NULL);
   msgCHECK(returnValue);

   /* Config recorder parameters */
   recorderConfig.period = period;
   recorderConfig.highCount = highCount;
   recorderConfig.bufferWrap = TRUE;

   /* Set recorder configuration using handle */
   returnValue =
      mpiRecorderConfigSet(recorder,
                           &recorderConfig,
                           NULL);
   msgCHECK(returnValue);
}

/* Start recorder with Recorder events enabled */
startRecorder(MPIRecorder          recorder,
              MPIRecorderRecord   *records,
              MPINotify            notify,
             long                  recordCount,
             long                  highCount,
             long                  inputMask)
{
   long       countGet;
   long       returnValue;                /* return value from library */

    /* Start recording */
    returnValue =
        mpiRecorderStart(recorder,
                         -1); /* -1 = continuous */
   msgCHECK(returnValue);

    /* Loop repeatedly */
    while (meiPlatformKey(MPIWaitPOLL) <= 0) {

        MPIEventStatus  eventStatus;

        /* Wait for recorder events */
        returnValue =
         mpiNotifyEventWait(notify,
                            &eventStatus,
                            MPIWaitFOREVER);
        msgCHECK(returnValue);

      returnValue =
         mpiRecorderRecordGet(recorder,
                              recordCount,
                              (MPIRecorderRecord *)records,
                              &countGet);
      msgCHECK(returnValue);

        switch (eventStatus.type) {
         case MPIEventTypeRECORDER_HIGH:{
            /* Save data to text file */
            writeDataToFile(records,  recordCount, 1);
            /* Perform data analysis */
            analyzeData(records, highCount, inputMask);
            break;
         }/* End case */

            case MPIEventTypeRECORDER_FULL:{
            printf("FULL %d\n", countGet);
            break;
         }/* End case */
            case MPIEventTypeRECORDER_DONE:{
            printf("DONE %d\n", countGet);
            break;
         }/* End case */
            default: {
            printf("Unknown Current Event Status: %u \r \n", eventStatus.type);
                break;
            }/* End default */
      }/* End switch */
   }/* End while */

   printf("\n");
}

/* Stop recorder */
void stopRecorder(MPIRecorder recorder)
{
   long returnValue;
   /* Stop recorder if not already stopped */
   returnValue = mpiRecorderStop(recorder);
   if(returnValue == MPIRecorderMessageSTOPPED)
   {
      returnValue = MPIMessageOK;
   }
   msgCHECK(returnValue);
}

/* Main function */
int main(int     argc,
         char   *argv[])
{
    MPIControl          control;           /* motion controller handle  */
    MPIControlType      controlType;
    MPIControlAddress   controlAddress;
    MPIRecorder         recorder;          /* data recorder handle      */
    MPIRecorderRecord  *records;
    MPINotify           notify;            /* event notification handle */
    MPIEventMgr         eventMgr;          /* event manager handle      */
    Service             service;           /* service thread */
    MEISqNode           sqNode;

    long                recordCount = RECORD_COUNT;
    long                returnValue;                /* return value from library */

    /* Perform basic command line parsing. (-control -server -port -trace) */
    basicParsing(argc,
                 argv,
                 &controlType,
                 &controlAddress);

    /* Create and initialize MPI objects */
    programInit(&control,
                controlType,
                &controlAddress,
                &recorder,
                &records,
                recordCount,
                &sqNode,
                SQNODE_NUMBER,
                &eventMgr,
                &notify,
                &service);

   /* Configure recorder */
   configRecorder(recorder,
                  sqNode,
                  HIGH_COUNT,
                  PERIOD,
                  POINT_COUNT,
                  INPUT_MASK);

   /* Start recorder with events enabled */
   startRecorder(recorder,
                 records,
                 notify,
                 RECORD_COUNT,
                 HIGH_COUNT,
                 INPUT_MASK);

   /* Stop recorder */
   stopRecorder(recorder);

    /* Perform certain cleanup actions and delete MPI objects */
    programCleanup(&control,
                   &recorder,
                   records,
                   recordCount,
                   &sqNode,
                   &eventMgr,
                   &notify,
                   &service);

    return MPIMessageOK;
}

      
       Legal Notice  |  Tech Email  |  Feedback
      
Copyright ©
2001-2009 Motion Engineering