.

     

MPI Application Template
template.c
 

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);
}


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