SQStatus3.c -- Display/Save/Verify SynqNet Topology and DMD/SigmaIII
Specific Information
/* SQStatus3.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.
*/
/*
:Display/Save/Verify SynqNet Topology and Drive Specific Information
This sample application is the same as SQStatus2.c with the addition
drive specific configuration display and verification.
This program only displays and verifies 3rd party drives that support the
meiSqNodeDriveInfo(...) routines. Depending on your SynqNet installation
and configuration, additional steps may be required to verify other
individual drive specific values and structures. Please consult your
drive/motor manufacturer documentation for details.
If the -save <filename> option is selected, the topology info is saved to a text file.
The saved text file can be used to verify the SynqNet topology at system startup
using the -verify <filename> option. This option saves the current topology info to
a temporary file, then compares the temporary file to the saved file. A failure or
success is reported after the verify check.
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 <string.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
#include "..\sqNodeLib\include\sqNodeLib.h"
#if defined(ARG_MAIN_RENAME)
#define main SQStatus3Main
argMainRENAME(main, SQStatus3)
#endif
/* Command line arguments and defaults */
long synqNetNumber = 0;
char *saveFilename = NULL;
char *verifyFilename = NULL;
Arg argList[] = {
{ "-synqNet", ArgTypeLONG, &synqNetNumber, },
{ "-save", ArgTypeTEXT, &saveFilename, },
{ "-verify", ArgTypeTEXT, &verifyFilename, },
{ NULL, ArgTypeINVALID, NULL, }
};
long
networkInfoOutput(MEISynqNet synqNet,
char *fileName);
long
networkInfoVerify(MEISynqNet synqNet,
char *filename);
int
main(int argc,
char *argv[])
{
MPIControl control;
MPIControlType controlType;
MPIControlAddress controlAddress;
MEISynqNet synqNet;
long returnValue;
long argIndex;
/* 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) ||
(synqNetNumber < 0) ||
(synqNetNumber >= MEIXmpMaxSynqNets) ||
((saveFilename != NULL) && (verifyFilename != NULL))) {
meiPlatformConsole("usage: %s %s\n",
"\t\t[-synqNet (0 .. %d)]\n"
"\t\t[-save filename | -verify filename]\n",
argv[0],
ArgUSAGE,
MEIXmpMaxSynqNets - 1);
exit(MPIMessageARG_INVALID);
}
/* Create control object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize the controller */
returnValue = mpiControlInit(control);
msgCHECK(returnValue);
/* Create SynqNet Object */
synqNet =
meiSynqNetCreate(control,
synqNetNumber);
msgCHECK(meiSynqNetValidate(synqNet));
/* Display current topology */
networkInfoOutput(synqNet, NULL);
if (saveFilename != NULL) {
char in;
/* verify with user */
printf("\n\nIs this network topology correct? (y/n)");
in = getchar();
/* save topology to file */
if ((in == 'y') ||
(in == 'Y')) {
networkInfoOutput(synqNet, saveFilename);
printf("\nNetwork topology saved to file: %s\n\n", saveFilename);
}
}
if (verifyFilename != NULL) {
returnValue =
networkInfoVerify(synqNet, verifyFilename);
if (returnValue == -1) {
printf("Verify failed\n\n");
}
else {
printf("Verify Successful!!\n\n");
}
}
/* Delete object handles */
returnValue = meiSynqNetDelete(synqNet);
msgCHECK(returnValue);
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}
long
networkInfoOutput(MEISynqNet synqNet,
char *fileName)
{
MEISynqNetInfo synqNetInfo;
MEISqNode sqNode;
MEISqNodeInfo nodeInfo;
long nodeFirst;
long nodeLast;
long bytes;
long index;
long returnValue;
FILE *stream = stdout;
/* open file for output */
if (fileName != NULL) {
stream = fopen( fileName, "w" );
}
/* Read SynqNet Info */
returnValue =
meiSynqNetInfo(synqNet, &synqNetInfo);
msgCHECK(returnValue);
if (synqNetInfo.nodeCount) {
/* Display SynqNet Info */
bytes =
fprintf(stream,
"SynqNet Information\n"
" Node Count : %ld\n\n",
synqNetInfo.nodeCount);
nodeFirst = synqNetInfo.nodeOffset;
nodeLast = synqNetInfo.nodeOffset + synqNetInfo.nodeCount;
for (index = nodeFirst; index < nodeLast; index++) {
sqNode =
meiSqNodeCreate(meiSynqNetControl(synqNet),
index);
msgCHECK(meiSqNodeValidate(sqNode));
returnValue =
meiSqNodeInfo(sqNode, &nodeInfo);
msgCHECK(returnValue);
bytes +=
fprintf(stream,
"\n Node [%ld] Information\n"
" Type : %s\n"
" Motor Count : %d\n"
" Motor Offset : 0x%x\n",
index,
nodeInfo.id.nodeName,
nodeInfo.motorCount,
nodeInfo.motorOffset);
bytes +=
fprintf(stream,
" Serial Number: %s\n"
" Model Number : %s\n"
" VendorDevice : 0x%x\n"
" Version : 0x%x\n\n",
nodeInfo.id.serialNumber,
nodeInfo.id.modelNumber,
nodeInfo.fpga.vendorDevice,
nodeInfo.fpga.version);
switch(nodeInfo.id.nodeType) {
case (SQNodeLibNodeTypeYASKAWA_SGDZ_MD) : {
SGDZMDInfo driveInfo;
long drive;
memset((void*)&driveInfo,0x0,sizeof(driveInfo));
for (drive=0; drive < nodeInfo.motorCount; drive++) {
/* Read Drive specific Info */
returnValue =
meiSqNodeDriveInfo(sqNode,
index,
(void*)&driveInfo,
NULL);
msgCHECK(returnValue);
bytes +=
fprintf(stream,
" Drive/Amp Information\n"
" FW Version : %d\n"
" Encoder Type : %s\n"
" Motor Type : %s\n"
" Rated Current : %2.2f A\n"
" Rated Power : %d Watts\n"
" Rated Speed : %d rpm\n"
" Rated Torque : %2.2f Nm\n\n",
driveInfo.version,
driveInfo.encoder.type,
driveInfo.motor.type,
driveInfo.motor.rating.current * 0.1,
driveInfo.motor.rating.power,
driveInfo.motor.rating.speed * 100,
driveInfo.motor.rating.torque * 0.01);
}
break;
}
case (SQNodeLibNodeTypeYASKAWA_SGDS) : {
SGDSInfo driveInfo;
memset((void*)&driveInfo,0x0,sizeof(driveInfo));
/* Read Drive specific Info */
returnValue =
meiSqNodeDriveInfo(sqNode,
index,
(void*)&driveInfo,
NULL);
msgCHECK(returnValue);
bytes +=
fprintf(stream,
" Drive/Amp Information\n"
" FW Version : %d\n"
" Motor Capacity : %d\n"
" Motor Torque : %d\n"
" Motor TorqueMax: %d\n",
driveInfo.FWVersion,
driveInfo.MotorCapacity,
driveInfo.MotorTorque,
driveInfo.MotorTorqueMax);
break;
}
case (SQNodeLibNodeTypeGLENTEK_OMEGA) : {
GLENTEKOmegaInfo driveInfo;
memset((void*)&driveInfo,0x0,sizeof(driveInfo));
/* Read Drive specific Info */
returnValue =
meiSqNodeDriveInfo(sqNode,
index,
(void*)&driveInfo,
NULL);
msgCHECK(returnValue);
bytes +=
fprintf(stream,
" Drive/Amp Information\n"
" Base Model : %d\n"
" Powerboard Tab : %d\n"
" PreAmp Tab : %d\n"
" Continuous Current Rating: %6.3lf\n"
" Peak Current Rating : %6.3lf\n"
" Bus Under-Voltage : %6.3lf\n"
" Bus Over-Voltage : %6.3lf\n"
" I/O Invert Mask : 0x%8.8x\n"
" Cal. Offset Phase R : %d\n"
" Cal. Offset Phase S : %d\n"
" Cal. Offset Phase T : %d\n"
" FW Command Set : %d\n"
" FW Version : %s\n",
driveInfo.mode.baseModel,
driveInfo.mode.powerBoardTab,
driveInfo.mode.preAmpTab,
driveInfo.mode.currentRatingCont,
driveInfo.mode.currentRatingPeak,
driveInfo.mode.busUnderVoltage,
driveInfo.mode.busOverVoltage,
driveInfo.mode.ioInvertMask,
driveInfo.calibration.adcOffsetPhaseR,
driveInfo.calibration.adcOffsetPhaseS,
driveInfo.calibration.adcOffsetPhaseT,
driveInfo.firmware.commandSet,
driveInfo.firmware.version);
break;
}
case (SQNodeLibNodeTypeKOLLMORGEN_CD) :
case (SQNodeLibNodeTypeKOLLMORGEN_DASA) : {
DASADriveInfo driveInfo;
long drive;
memset((void*)&driveInfo,0x0,sizeof(driveInfo));
for (drive=0; drive < nodeInfo.motorCount; drive++) {
/* Read Drive specific Info */
returnValue =
meiSqNodeDriveInfo(sqNode,
index,
(void*)&driveInfo,
NULL);
msgCHECK(returnValue);
bytes +=
fprintf(stream,
" Drive/Amp Information\n"
" Continuous Current Rating: %d\n"
" Peak Current Rating : %d\n"
" Max Current for drive : %d\n"
" PWM Frequency : %d\n"
" Drive FW Version : 0x%8.8x\n",
driveInfo.dicont,
driveInfo.dipeak,
driveInfo.imax,
driveInfo.pwmfrq,
driveInfo.ver);
}
break;
}
default: {
break;
}
}
}
}
else {
printf("No SynqNet Blocks found.\n");
}
/* close output file */
if (fileName != NULL) {
fclose( stream );
}
return (bytes);
}
long
networkInfoVerify(MEISynqNet synqNet,
char *fileName)
{
long returnValue = MPIMessageOK;
long bytes, i;
char chr1, chr2;
FILE *stream1, *stream2;
/* save current topology to temp file */
bytes =
networkInfoOutput(synqNet, "tmpfile.txt");
/* open files */
stream1 = fopen( "tmpfile.txt", "r" );
stream2 = fopen( fileName, "r" );
/* compare files */
for(i=0;i<bytes;i++) {
chr1=fgetc(stream1);
chr2=fgetc(stream2);
if (chr1 != chr2) {
returnValue = -1;
break;
}
}
return (returnValue);
}
|