SQEStop1.c -- SynqNet Emergency Stop configuration.
/* SQEStop1.c */
/* 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.
*/
/*
:SynqNet Emergency Stop configuration.
The SynqNet Node User Fault can be configured to trigger from any controller
memory address. When the masked value at the specified address matches the
pattern, the user fault is active. The User Fault triggers an action for
all the motors associated with the node.
Typically, the User Fault is configured to monitor the Node Disable input on
each node or a controller User Input, which are connected to the machine's
master Emergency Stop button.
The User Fault can also be configured to trigger a node IoAbort if the
userFault flag in MEISqNodeConfigIoAbort{} is enabled.
This sample demonstrates how to configure the User Fault to trigger from the
local controller X-ESTOP input. And it shows how to configure each motor to
generate an ABORT action when the user input is activated.
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.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main SQEStop1Main
argMainRENAME(main, SQEStop1)
#endif
/* Command line arguments and defaults */
long nodeCount = 1;
long motorCount = 4;
Arg argList[] = {
{ "-nodeCount", ArgTypeLONG, &nodeCount, },
{ "-motorCount", ArgTypeLONG, &motorCount, },
{ NULL, ArgTypeINVALID, NULL, }
};
int
main(int argc,
char *argv[])
{
MPIControl control;
MPIControlType controlType;
MPIControlAddress controlAddress;
MPIMotor motor;
MPIMotorConfig motorConfig;
MEIMotorConfig motorConfigXmp;
MEIXmpData *firmware;
MEISqNode sqNode;
MEISqNodeConfig nodeConfig;
long argIndex;
long returnValue;
long nodeIndex;
long motorIndex;
/* 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;
}
}
/* Check for unknown/invalid command line arguments */
if ((argIndex < argc) ||
(nodeCount >= MEIXmpMaxMotionBlocks) ||
(motorCount >= MEIXmpMAX_Motors)) {
meiPlatformConsole("usage: %s %s\n",
"\t\t[-nodeCount (0 .. %d)]\n"
"\t\t[-motorCount (0 .. %d)]\n",
argv[0],
ArgUSAGE,
MEIXmpMaxMotionBlocks,
MEIXmpMAX_Motors);
exit(MPIMessageARG_INVALID);
}
/* Create a control object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize the controller */
returnValue = mpiControlInit(control);
msgCHECK(returnValue);
/* Read the controller memory address */
returnValue =
mpiControlMemory(control,
&firmware,
NULL);
msgCHECK(returnValue);
/* Configure userFaults for each node to monitor a controller input bit. */
for (nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
/* Create a sqNode object */
sqNode =
meiSqNodeCreate(control,
nodeIndex);
msgCHECK(meiSqNodeValidate(sqNode));
returnValue =
meiSqNodeConfigGet(sqNode,
&nodeConfig);
msgCHECK(returnValue);
/* Trigger on Controller's User Input #0 */
returnValue =
meiPlatformMemoryToHost(meiControlPlatform(control),
firmware->SystemData.IO.Input[0].Ptr,
&nodeConfig.userFault.addr);
nodeConfig.userFault.mask = MEIControlInputXESTOP;
nodeConfig.userFault.pattern = MEIControlInputXESTOP;
returnValue =
meiSqNodeConfigSet(sqNode,
&nodeConfig);
msgCHECK(returnValue);
/* Delete object handles */
returnValue = meiSqNodeDelete(sqNode);
msgCHECK(returnValue);
}
/* Configure the motors associated with each sqNode to generate
an action when the userFault is activated.
*/
for (motorIndex = 0; motorIndex < motorCount; motorIndex++ ) {
/* Create a motor object */
motor =
mpiMotorCreate(control,
motorIndex);
msgCHECK(mpiMotorValidate(motor));
returnValue =
mpiMotorConfigGet(motor,
&motorConfig,
&motorConfigXmp);
msgCHECK(returnValue);
/* ABORT action when userFault is triggered */
motorConfigXmp.userFaultAction = MPIActionABORT;
motorConfig.abortDelay = 0.5; /* seconds */
returnValue =
mpiMotorConfigSet(motor,
&motorConfig,
&motorConfigXmp);
msgCHECK(returnValue);
/* Delete object handles */
returnValue = mpiMotorDelete(motor);
msgCHECK(returnValue);
}
/* Delete object handles */
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}
|