#include "flexmotn.h" #include <stdio.h> #define HOST 0xFF void ErrorHandler(i32 errorCode, u16 commandID, u16 resourceID); void main(void) { u8 boardID; // Board ID assigned to the FlexMotion controller in the // Board Configuration Utility u16 csr; // The communication status register i32 status = NIMC_noError; // Return Status of Functions u32 scanVar; // scanf wants a u16 to put numeric values in. // Variables for modal error handling u16 commandID; //The commandID of the function u16 resource; //The resource ID i32 errorCode; //The error generated //Initialization parameters u32 countsPerRev = 800; // Quadrature encoder counts per revolution u16 followingError = 32000; // Maximum following error to allow on closed loop axes f64 velocity = 25000; // Maximum RPM f64 accelDecel = 100000; // Acceleration and deceleration RPSPS u8 enableAxes = 0x02; // Bitmap of axes to enable u8 enableMap = 0x02; // Bitmap for inhibits to be enabled u8 polarityMap=0x02; // Bitmap for inhibits polarity u16 findIndexDir = 0; // Search for index line in forward direction i16 indexOffset = 0; // Encoder counts to move off of index after Find Index //PID Values PID PIDValues; // PID parameters for Servo axes // Set PID gain values to be loaded later PIDValues.kp = 10; PIDValues.ki = 10; PIDValues.ilim = 1000; PIDValues.kd = 180; PIDValues.td = 2; PIDValues.kv = 0; PIDValues.aff = 0; PIDValues.vff = 0; /****************** * START * ******************/ // Get user input for boardID printf ("\nEnter the board ID: "); scanf ("%d", &scanVar); boardID = (u8)scanVar; fflush(stdin); // flushes stdin. printf("\n"); /**************************** * STEP 1 * * Clear power up reset bit * ****************************/ printf("\nCalling Clear Power Up Status . . ."); status = flex_clear_pu_status (boardID); //Wait for the power up reset bit to go low. //Once the power up reset bit (power up reset bit) goes low //the FlexMotion board is ready. if(status == NIMC_noError) { do { //Read the communication Status register status = flex_read_csr_rtn(boardID, &csr); if(status != NIMC_noError) break; } while (csr & NIMC_POWER_UP_RESET); } /**************************** * STEP 2 * * Disable all axes * ****************************/ if (status == NIMC_noError) { printf("\nDisabling all axes . . ."); status = flex_enable_axes (boardID, NIMC_AXIS_CTRL, 0, 0); } /**************************** * STEP 3 * * Configure Encoder * ****************************/ printf("\nConfiguring feedback and output resources . . ."); if (status == NIMC_noError) { //Axis 1 mapping status = flex_config_axis (boardID, NIMC_AXIS1, NIMC_ENCODER1, 0, NIMC_DAC1, 0); } /**************************** * STEP 4 * * Enable Axis 1 * ****************************/ if (status == NIMC_noError) { printf("\nEnabling axes . . ."); status = flex_enable_axes (boardID, NIMC_AXIS_CTRL, NIMC_PID_RATE_250, enableAxes); } /**************************** * STEP 5 * * PID Parameter Setup * ****************************/ if (status == NIMC_noError) { printf("\nLoading PID parameters . . ."); status = flex_load_pid_parameters (boardID, NIMC_AXIS1, &PIDValues, HOST); } /**************************** * STEP 6 * * Setup Quadrature Encoder * ****************************/ if (status == NIMC_noError) { printf("\nLoading counts per revolution . . ."); status = flex_load_counts_steps_rev (boardID, NIMC_AXIS1, NIMC_COUNTS, countsPerRev); } /**************************** * STEP 7 * * Setup Inhibit Polarity * ****************************/ if(status == NIMC_noError) { printf("\nConfiguring inhibits . . ."); status = flex_configure_inhibits (boardID, polarityMap, enableMap); } /*************************** * STEP 8 * * Set Operation Mode * ***************************/ if (status == NIMC_noError) { printf("\nSetting operation mode . . ."); status = flex_set_op_mode (boardID, NIMC_AXIS1, NIMC_ABSOLUTE_POSITION); } /*************************** * STEP 9 * * Load Max Follow Error * ***************************/ if (status == NIMC_noError ) { printf("\nSetting following error . . ."); status = flex_load_follow_err (boardID, NIMC_AXIS1, followingError, HOST); } /*************************** * STEP 10 * * Load Default Velocity * ***************************/ if (status == NIMC_noError) { printf("\nLoading velocity . . ."); status = flex_load_velocity (boardID, NIMC_AXIS1, velocity, HOST); } /********************************* * STEP 11 * * Load Default * * Acceleration and Deceleration * *********************************/ if (status == NIMC_noError) { printf("\nLoading acceleration and deceleration . . ."); status = flex_load_acceleration (boardID, NIMC_AXIS1, NIMC_BOTH, accelDecel, HOST); } /****************************** * STEP 12 * * Find Encoder Index Position * ******************************/ // This is not used in our setup // If you wish to use this, you will have to tell // the board to wait until the move is done // if not and there is an error, this program will // not catch it since the error will occure after // this program is done. // //if (status == NIMC_noError) //{ // printf("\nFinding indexes . . ."); // status = flex_find_index (boardID, NIMC_AXIS1, findIndexDir, indexOffset); //} /*************************** * STEP 13 * * Reset Position to Zero * ***************************/ if (status == NIMC_noError) { printf("\nReseting positions to zero . . ."); status = flex_reset_pos (boardID, NIMC_AXIS1, 0, 0, HOST); } /************************************ * STEP 14 * * Energize (halt) configured axes * ************************************/ if (status == NIMC_noError) { printf("\nEnergizing (halting) configured axes . . ."); status = flex_stop_motion (boardID, NIMC_AXIS_CTRL, NIMC_HALT_STOP, enableAxes); } //Check for any modal errors if(status == NIMC_noError) { //Read the Communication Status Register to check the //Modal Error bit status = flex_read_csr_rtn(boardID, &csr); if (status == NIMC_noError) { while(csr & NIMC_MODAL_ERROR_MSG) { //If there are modal error - read them from the error stack //on the board status = flex_read_error_msg_rtn(boardID, &commandID, &resource, &errorCode); if (status != NIMC_noError) break; ErrorHandler((i32)errorCode, commandID, resource); status = flex_read_csr_rtn(boardID, &csr); if (status != NIMC_noError) break; } } } //If an non-modal error occurs report it if (status != NIMC_noError) { ErrorHandler ((i32)status, 0, 0); } printf("\n\nFinished.\n"); exit(0); } void ErrorHandler(i32 errorCode, u16 commandID, u16 resourceID) { i8 *errorDescription; //Pointer to i8's - to get error description u32 sizeOfArray; //Size of error description u16 descriptionType; //The type of description to be printed i32 status; //Error returned by function if(commandID == 0) { descriptionType = NIMC_ERROR_ONLY; } else { descriptionType = NIMC_COMBINED_DESCRIPTION; } //First get the size for the error description sizeOfArray = 0; errorDescription = NULL; //Setting this to NULL returns the size required status = flex_get_error_description(descriptionType, errorCode, commandID, resourceID, errorDescription, &sizeOfArray ); //Allocate memory on the heap for the description errorDescription = malloc(sizeOfArray + 1); sizeOfArray++; //So that the sizeOfArray is size of description + NULL character // Get Error Description status = flex_get_error_description(descriptionType, errorCode, commandID, resourceID, errorDescription, &sizeOfArray ); if (errorDescription != NULL) { printf("\n"); printf(errorDescription); //Print description to screen free(errorDescription); //Free allocated memory } else { printf("Memory Allocation Error"); } } /* End of Program */