.

     

MPI Application Template
template.c
 

countRate.c -- How to Maximize Count Rate
/* Copyright(c) 1991-2006 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.
 */

/*
 
This program will maximize (25MHz) count rate by disabling the encoder filter 
 or minimize(12.5MHz) count rate by enabling the encoder filter on an RMB-10V2. 
 
By default, the encoder filter is enabled. Setting the FilterDisable bit in the 
 feedbackQuadrature configuration register will allow a maximum of 25MHz.  

To modify count rate on  a different motor number, use '-motor #' option. It is
 defaulted on motor 0. 

To modify count rate on  all motors that are supported by the node, use 
 '-all (true or false)' option. It is defaulted at -all false.

To either maximize or minimize count rate, use '-countrate (min or max)'
 option.

To specify either primary or secondary encoder use the 
 '-encoder (primary or secondary)'
 option. It is defaulted on primary enconder on motor 0.

To specify which node to modify, use '-node #'. It is defaulted on '-node 0'.

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 SQNODE_NUMBER       (0)
#define MOTOR_NUMBER        (0)
#define PRIMARY_ENCODER     (0)
#define SECONDARY_ENCODER   (1)


/* Parse command line */
long parseCommandLine(int                argc,
                      char               *argv[],
                      MPIControlType     *controlType,
                      MPIControlAddress  *controlAddress,
                      long               *sqNodeNumber,
                      long               *motorNumber,
                      long               *allAxis,
                      long               *encoderOption,
                      long               *disableDigitalFilter)
{
    long    argIndex;
    char    *filterInput = NULL;
    char    *encOpt      = NULL;
    char    *all         = NULL;
    char    *lower       = NULL;

    /* Application-specific command line arguments */
    Arg argList[] =
    {
        {   "-node",        ArgTypeLONG,        sqNodeNumber,   },
        {   "-motor",       ArgTypeLONG,        motorNumber,    },
        {   "-all",         ArgTypeTEXT,        &all,           },
        {   "-countrate",   ArgTypeTEXT,        &filterInput,   },
        {   "-encoder",     ArgTypeTEXT,        &encOpt,        },
        {   NULL,           ArgTypeINVALID,     NULL,           }
    };

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

    /* Parse command line for application-specific arguments */
    while (argIndex < argc)
    {
        long    argIndexNew;

        argIndexNew = argSet(argList, argIndex, argc, argv);

        if (argIndexNew <= argIndex)
        {
            argIndex = argIndexNew;
            break;
        }
        else
        {
            argIndex = argIndexNew;
        }
    }

    /* Set enable/disable digital filter from user input */
    if(filterInput != NULL)
    {
        for(lower = filterInput; *lower != '\0'; lower++)
        {
            *lower = tolower(*lower);
        }

        if( strcmp(filterInput, "min") == 0 )
        {
            *disableDigitalFilter = FALSE;
        }
        else if( strcmp(filterInput, "max") == 0 )
        {
            *disableDigitalFilter = TRUE;
        }
        else
        {
            *disableDigitalFilter = -1;
        }
    }

    /* Set encoder option for primary or secondary */
    if(encOpt != NULL)
    {
        for(lower = encOpt; *lower != '\0'; lower++)
        {
            *lower = tolower(*lower);
        }

        if( strcmp(encOpt, "primary") == 0 )
        {
            *encoderOption = PRIMARY_ENCODER;
        }
        else if( strcmp(encOpt, "secondary") == 0 )
        {
            *encoderOption = SECONDARY_ENCODER;
        }
        else
        {
            *encoderOption = -1;
        }
    }

    /* Disable or enable on either all axis or a specified axis only */
    if(all != NULL)
    {
        for(lower = all; *lower != '\0'; lower++)
        {
            *lower = tolower(*lower);
        }

        if( strcmp(all, "true") == 0 )
        {
            *allAxis = TRUE;
        }
        else if( strcmp(all, "false") == 0 )
        {
            *allAxis = FALSE;
        }
        else
        {
            *allAxis = -1;
        }
    }
    /* Check for unknown/invalid command line arguments */
    if ((argIndex < argc) ||
        (*sqNodeNumber < 0) ||
        (*motorNumber < 0) ||
        (*encoderOption != PRIMARY_ENCODER &&
         *encoderOption != SECONDARY_ENCODER) ||
        (*allAxis != TRUE && *allAxis != FALSE) ||
        (*disableDigitalFilter != TRUE && *disableDigitalFilter != FALSE))
    {
        fprintf(stderr,"usage: %s %s\n"
                           "\t\t     [-node      #(0..%d)]\n"
                           /*RMB-10V2s support 4 motors*/
                           "\t\t     [-motor     #(0..3)]\n"
                           "\t\t     [-all       'true' or 'false']\n"
                           "\t\t     [-countrate 'max' or 'min']\n"
                           "\t\t     [-encoder   'primary' or 'secondary']\n",
                            argv[0],
                            ArgUSAGE,
                            MPISynqNetMaxNODE_COUNT);
        exit(MPIMessageARG_INVALID);
    }

    return 0;
}


/* Create and initialize MPI objects */
void programInit(MPIControl         *control,
                 MPIControlType      controlType,
                 MPIControlAddress  *controlAddress,
                 MPISqNode          *sqNode,
                 long                sqNodeNumber)
{
    long            returnValue;


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

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

    /* Create sqNode object */
    *sqNode =
        mpiSqNodeCreate(*control, sqNodeNumber);
    msgCHECK(mpiSqNodeValidate(*sqNode));
}


/* Perform certain cleanup actions and delete MPI objects */
void programCleanup(MPIControl  *control,
                    MPISqNode   *sqNode)
{
    long            returnValue;

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

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


/* Return the Feedback Quadrature Address that relates to the motorNumber */
unsigned long getFeedbackQuadratureAddress(long motorNumber,
                                           long encoderOption)
{
    unsigned long fqAddress = 0;

    /* Note that RMB 10v supports 4 axis only */
    if(motorNumber == 0)
    {
        /* if primary encoder */
        if(encoderOption == 0)
        {
            fqAddress = 0x00020000;
        }
        /* if secondary encoder */
        else
        {
            fqAddress = 0x00028000;
        }
    }
    else if (motorNumber == 1)
    {
        /* if primary encoder */
        if(encoderOption == 0)
        {
            fqAddress = 0x01020000;
        }
        /* if secondary encoder */
        else
        {
            fqAddress = 0x01028000;
        }
    }
    else if (motorNumber == 2)
    {
        /* if primary encoder */
        if(encoderOption == 0)
        {
            fqAddress = 0x02020000;
        }
        /* if secondary encoder */
        else
        {
            fqAddress = 0x02028000;
        }
    }
    else if (motorNumber == 3)
    {
        /* if primary encoder */
        if(encoderOption == 0)
        {
            fqAddress = 0x03020000;
        }
        /* if secondary encoder */
        else
        {
            fqAddress = 0x03028000;
        }
    }

    return fqAddress;
}


/* Get data that will be written to either enable or disable digital filter */
unsigned long getResponseData(long          disableDigitalFilter,
                              unsigned long responseData)
{
    /* Turn digital Filter Off to maximize count rate */
    if(disableDigitalFilter ==  TRUE)
    {
        responseData |= 0x2;
    }

    /* Turn digital Filter On to minimize count rate*/
    else
    {
        responseData &= ~(0x2);
    }

    return responseData;
}


/* Enable or disable digital filter on the specified motor on the RMB-10V2 */
void setDigitalFilter(MPISqNode sqNode,
                      long      motorNumber,
                      long      encoderOption,
                      long      disableDigitalFilter)
{
    MPISqNodeCommand        command;
    MPISqNodeResponse       response;

    long                    returnValue;

    /* Setting up read  command to be sent to the node */
    /* Get the relating feedback quadrature address of a motor */
    command.address         = getFeedbackQuadratureAddress(motorNumber,
                                                           encoderOption);
    command.header.channel  = MPISqNodeChannelNODE;
    command.header.memory   = MPISqNodeMemoryDATA;
    command.header.size     = MPISqNodeDataSize32BIT;
    command.header.type     = MPISqNodeCmdTypeREAD;

    /* Send read command and get a response  */
    returnValue =
        mpiSqNodeCommand(sqNode,
                         &command,
                         &response);
    msgCHECK(returnValue);

    /* Display data being read from the node */
    printf("Motor %d, Response from reading: 0x%x from 0x%x\n",
            motorNumber,
            response.data,
            command.address);

    /* Modify command setup for writing */
    command.data        = getResponseData(disableDigitalFilter,
                                          response.data);
    command.header.type = MPISqNodeCmdTypeWRITE;

    /* Send write command */
    returnValue =
        mpiSqNodeCommand(sqNode,
                         &command,
                         &response);
    msgCHECK(returnValue);

    /* Display data being written */
    printf("Motor %d, Writing              : 0x%x to   0x%x\n",
                motorNumber,
                command.data,
                command.address);

    /* Modify command setup for reading */
    command.header.type     = MPISqNodeCmdTypeREAD;

    /* Send read command and get response */
    returnValue =
        mpiSqNodeCommand(sqNode,
                         &command,
                         &response);
    msgCHECK(returnValue);

    /* Display data being read from the node */
    printf("Motor %d, Response from reading: 0x%x from 0x%x\n\n",
                motorNumber,
                response.data,
                command.address);

}


/* Verify that the Node is an RMB-10V2 */
long verifyNodeIsRMB (MPISqNode sqNode)
{
    MPISqNodeInfo   info;

    long returnValue;

    /* Print node information, expecting an RMB-10V */
    returnValue = mpiSqNodeInfo(sqNode, &info);
    msgCHECK(returnValue);

    /*printf("\n\nNode name: %s with %ld motors\n\n", 
            info.id.nodeName, info.motorCount); */

    /* Check if node name is in fact RMB-10V2 */
    if(strncmp(info.id.nodeName, "MEI RMB-10V2", 12) == 0)
    {
        returnValue = MPIMessageOK;
    }
    else
    {
        fprintf(stderr, "MEI RMB-10V2 is not located\n");
        returnValue = -1;
    }

    return returnValue;
}


int main(int     argc,
         char   *argv[])
{
    MPIControl         control;
    MPIControlType     controlType;
    MPIControlAddress  controlAddress;
    MPISqNode          sqNode;
    MPISqNodeInfo      info;

    long               sqNodeNumber         = SQNODE_NUMBER;
    long               motorNumber          = MOTOR_NUMBER;
    long               disableDigitalFilter = TRUE;
    long               encoderOption        = PRIMARY_ENCODER;
    long               allAxis              = FALSE;

    long               index;
    long               returnValue;

    /* Parse command line */
    parseCommandLine(argc,
                     argv,
                     &controlType,
                     &controlAddress,
                     &sqNodeNumber,
                     &motorNumber,
                     &allAxis,
                     &encoderOption,
                     &disableDigitalFilter);

    /* Create and initialize MPI objects */
    programInit(&control,
                controlType,
                &controlAddress,
                &sqNode,
                sqNodeNumber);

    /* Check if the node specified is an MEI RMB-10V2 */
    returnValue =
        verifyNodeIsRMB(sqNode);

    /* Disable or Enable Digital Filter on the specified motor or all */
    if(returnValue == MPIMessageOK)
    {
        /* Get node information */
        returnValue = mpiSqNodeInfo(sqNode, &info);
            msgCHECK(returnValue);

        /* If all motors */
        if(allAxis)
        {
            for(index = 0; index < info.motorCount; index++)
            {
                setDigitalFilter(sqNode,
                                 index,
                                 encoderOption,
                                 disableDigitalFilter);
            }
        }
        /* If a motor number is specified */
        else
        {
            /* Check if motor number is valid */
            if(motorNumber < info.motorCount)
            {
                setDigitalFilter(sqNode,
                                 motorNumber,
                                 encoderOption,
                                 disableDigitalFilter);
            }
            /* If motor number not valid, print error message */
            else
            {
                printf("\nCheck motor number requested. "
                       "Motor number %d is not supported.\n"
                       "%s supports motor number 0 to %d only. \n",
                       motorNumber, info.id.nodeName, info.motorCount-1);
            }
        }
    }

    /* Perform certain cleanup actions and delete MPI objects */
    programCleanup(&control,
                   &sqNode);

    return MPIMessageOK;
}


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