|
/* trustanalogrecord.c */
/* trustanalogfeedback.c */
/* Copyright(c) 1991-2004 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.
*/
/*
: Sets up analog feedback for a control loop using a Trust TA805-D
This program sets up an axis to get it's actual position from an analog channel on a Trust TA805-D. The methods shown here are applicable to other analog feedbacks from a high level. Some modification of the analog input pointers will likely need to be done to adapt this code to other sources of analog input.
It is important to understand that because of the way that analog inputs are sent back to the controller, only the odd number
(input 1 and 3 on a TA805-D) ADCs can be used as control loop feedback.
This is because the ADC inputs are 16 bits and two ADC inputs are packed into one word that the feedback loop reads. An example:
Input for ADC 0 and 1 looks like this: 0xaaaabbbb, where aaaa is ADC 1 and bbbb is ADC 0.
This means that you can use ADC 1 (aaaa) because the contribution of ADC 0 (bbbb) is less than one LSB bit on ADC 1 (insignificant noise).
In addition, this program will show you how to scale the analog feedback so that you do not get an ananlog input that is shifted up by 16 bits (multiplied by 65384). This rescaling actually will remove the even ADC completely.
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 "stdmpi.h" #include "stdmei.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME) #define main trustanalogfeedbackMain argMainRENAME(main, template) #endif
/* 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)
{ long returnValue;
/* Create motion controller object */ *control = mpiControlCreate(controlType, controlAddress); msgCHECK(mpiControlValidate(*control));
/* Initialize motion controller */ returnValue = mpiControlInit(*control); msgCHECK(returnValue);
}
/* Perform certain cleanup actions and delete MPI objects */ void programCleanup(MPIControl *control) { long returnValue;
/* Delete motion controller object */ returnValue = mpiControlDelete(*control); msgCHECK(returnValue);
*control = MPIHandleVOID;
}
/* This program sets the axis encoder input to the address that points to the adc input. It increments the pointer to the ADC for the ADC number. Only Odd numbered ADCs can be used. arguments: axisNum - number of the axis whose actual position is to be configured. blockNumber - number of the TA805D node. adcIndex - ADC index on the TA805D.
Actual position is scaled by 1 / 2^16 to compensate for using the upper 16 bits of the ADC word. */
void AnalogFeedbackConfig(MPIControl control, int axisNum, int blockNumber, int adcIndex) { MEIXmpData *firmware; MEIXmpBufferData* buffer; long *inPtr, *inPtrHost; long analogPtr; long returnValue; long coeff = MEIXmpFRACTIONAL_UNITY >> 16; /* scale for MSB ADC */
returnValue = mpiControlMemory(control, &firmware, &buffer); msgCHECK(returnValue);
returnValue = mpiControlMemoryGet(control, &inPtr, &buffer->Block[blockNumber].AnalogIO.InPtr, sizeof(buffer->Block[blockNumber].AnalogIO.InPtr)); msgCHECK(returnValue);
/* increment once per two adcs (must use odd ADC) */ analogPtr = (long)inPtr + adcIndex / 2;
returnValue = mpiControlMemorySet(control, &firmware->Axis[axisNum].APos[0].Ptr, (void**)&analogPtr, sizeof(firmware->Axis[axisNum].APos[0].Ptr)); msgCHECK(returnValue);
returnValue = mpiControlMemorySet(control, &firmware->Axis[axisNum].APos[0].Coeff, &coeff, sizeof(firmware->Axis[axisNum].APos[0].Coeff)); msgCHECK(returnValue);
}
int main(int argc, char *argv[]) { MPIControl control; MPIControlType controlType; MPIControlAddress controlAddress;
/* Perform basic command line parsing. (-control -server -port -trace) */ basicParsing(argc, argv, &controlType, &controlAddress);
/* Create and initialize MPI objects */ programInit(&control, controlType, &controlAddress);
/* Set up axis 0 to have analog feedback from adc input 5 on block 0 */ AnalogFeedbackConfig(control, 0, 0, 5);
/* Perform certain cleanup actions and delete MPI objects */ programCleanup(&control);
return MPIMessageOK; }
|