Contoured Move C/C++ Code
The following example code is not necessarily complete, and may not compile if copied exactly. Refer to the examples folder on the NI-Motion CD for files that are complete and compile as is.
// Main function void main(void) { u8 boardID; // Board identification number u8 vectorSpace; // Vector space number u16 csr = 0; // Communication status register u16 axisStatus; // Axis status u16 status; // Temporary copy of status u16 moveComplete; // Move complete status i32 i; i32 points[1994] = NIMC_SPIRAL_ARRAY; // Array of 2D points to move u32 numPoints = 1994; // Total number of points to contour through i32 bufferSize = 1000; // The size of the buffer to allocate on the motion controller f64 actualInterval; // The interval the controller can really contour at i32* downloadData = NULL; // The temporary array that is created to download the points to the controller u32 currentDataPoint = 0; // Indicates the next point in the points array that is to be downloaded i32 backlog; // Indicates the available space to download more points u16 bufferState; // Indicates the state of the onboard buffer u32 pointsDone; // Indicates the number of points that have been consumed u32 dataCopied = 0; // Keeps tack of the points copied // Variables for modal error handling u16 commandID; // The commandID of the function u16 resourceID; // The resource ID i32 errorCode; // Error code /////////////////////////////// // Set the board ID boardID = 1; // Set the axis number vectorSpace = NIMC_VECTOR_SPACE1; //////////////////////////////// // Configure a 2D Vector Space comprising of axes 1 and 2 err = flex_config_vect_spc(boardID, vectorSpace, 1, 2, 0); CheckError; // Set the operation mode to absolute position err = flex_set_op_mode(boardID, vectorSpace, NIMC_ABSOLUTE_CONTOURING); CheckError; // Configure buffer on motion controller memory (RAM) // Note requested time interval is hardcoded to 10 milliseconds err = flex_configure_buffer(boardID, 1 /*buffer number*/, vectorSpace, NIMC_POSITION_DATA, bufferSize, numPoints, NIMC_TRUE, 10, &actualInterval); CheckError; // Send the first 1000 points of the data downloadData = malloc(sizeof(i32)*bufferSize); for(i=0;i<bufferSize;i++){ downloadData[i] = points[i]; currentDataPoint++; } err = flex_write_buffer(boardID, 1/*buffer number*/, bufferSize, 0, downloadData, 0xFF); free(downloadData); downloadData = NULL; CheckError; // Start Motion err = flex_start(boardID, vectorSpace, 0); CheckError; for(;;){ axisStatus = 0; // Check for available space and download remaining points every 50 milliseconds Sleep(50); // Check to see if we have more points to download if(currentDataPoint < numPoints){ err = flex_check_buffer_rtn(boardID, 1/*buffer number*/, &backlog, &bufferState, &pointsDone); CheckError; if(backlog >= 300){ downloadData = malloc(sizeof(i32)*backlog); dataCopied = 0; for(i=0;i<backlog;i++){ if(currentDataPoint > numPoints) break; downloadData[i] = points[currentDataPoint]; currentDataPoint++; dataCopied++; } err = flex_write_buffer (boardID, 1 /*buffer number*/, dataCopied, 0, downloadData, 0xFF); free(downloadData); downloadData = NULL; CheckError; } } // Check the move complete status err = flex_check_move_complete_status(boardID, vectorSpace, 0, &moveComplete); CheckError; if(moveComplete) break; // Check for axis off status/following error or any modal errors // Read the communication status register and check the modal errors err = flex_read_csr_rtn(boardID, &csr); CheckError; // Check the modal errors if (csr & NIMC_MODAL_ERROR_MSG){ err = csr & NIMC_MODAL_ERROR_MSG; CheckError; } // Check the motor off status on all the axes or axis err = flex_read_axis_status_rtn(boardID, 1, &status); CheckError; axisStatus |= status; err = flex_read_axis_status_rtn(boardID, 2, &status); CheckError; axisStatus |= status; if( (axisStatus & NIMC_FOLLOWING_ERROR_BIT) || (axisStatus & NIMC_AXIS_OFF_BIT) ){ break; // Break out of the for loop as an axis was killed } } // Set the mode back to absolute mode to get the controller out of contouring // mode err = flex_set_op_mode(boardID, vectorSpace, NIMC_ABSOLUTE_POSITION); CheckError; // Free the buffer allocated on the controller memory err = flex_clear_buffer(boardID, 1/*buffer number*/); CheckError; return; // Exit the Application ///////////////////////////////////////////////////////////////////////// // Error Handling // nimcHandleError; //NIMCCATCHTHIS: // Check to see if there were any Modal Errors if (csr & NIMC_MODAL_ERROR_MSG){ do{ // Get the command ID, resource and the error code of the modal // error from the error stack on the board flex_read_error_msg_rtn(boardID,&commandID,&resourceID,&errorCode); nimcDisplayError(errorCode,commandID,resourceID); // Read the Communication Status Register flex_read_csr_rtn(boardID,&csr); }while(csr & NIMC_MODAL_ERROR_MSG); } else // Display regular error nimcDisplayError(err,0,0); return; // Exit the Application }