Synchronizing Host Applications with Onboard Programs 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 axis; // Axis number u16 csr = 0; // Communication status register i32 targetPosition; // Move length i32 multiplier; // multiplier u16 axisStatus; // Axis status u16 moveCompleteStatus; // Move complete status // 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 axis = 1; // Set the move length targetPosition = 5000; // Set the multiplier multiplier = -1; //////////////////////////////// //-------------------------------------------------------- // Onboard program. This onboard moves an axis back and // forth between targetPosition and -targetPosition. Before // reversing directions it indicates to the host computer that // it is about to do so. //-------------------------------------------------------- // Initialize onboard variable 2 to the multiplier used to change the // target position err = flex_load_var(boardID, multiplier, 2); CheckError; // Initialize onboard variable 1 to the target position err = flex_load_var(boardID, targetPosition, 1); CheckError; // Begin onboard program storage - program number 1 err = flex_begin_store(boardID, 1); // Set the operation mode to absolute position err = flex_set_op_mode(boardID, axis, NIMC_ABSOLUTE_POSITION); CheckError; // Set the velocity err = flex_load_velocity(boardID, axis, 10000, 0xFF); CheckError; // Insert Label number 1 err = flex_insert_program_label(boardID, 1); CheckError; // Load Target Position from onboard variable 1 err = flex_load_target_pos(boardID, axis, 0, 1); CheckError; // Start the move err = flex_start(boardID, axis, 0); CheckError; // Wait for move to complete err = flex_wait_on_condition(boardID, 0, NIMC_WAIT, NIMC_CONDITION_MOVE_COMPLETE, (u8)(1<<axis)/*Indicates axis to wait on*/, 0, NIMC_MATCH_ALL, 3000 /*time out*/, 0); CheckError; // Multiply Variables 1 i.e. the target position with 2 i.e. the multiplier // Save the result in variable 1 - this calculates the negative of last target position err = flex_mult_vars(boardID, 1, 2, 1); CheckError; // Set the 13th bit in the move complete status register so that the host // knows that the axis is about to reverse direction err = flex_set_status_momo(boardID, 0x20, 0); CheckError; // Jump unconditionally to load new target position err = flex_jump_label_on_condition (boardID, 0, NIMC_CONDITION_TRUE, 0, 0, NIMC_MATCH_ALL, 1/*label number*/); CheckError; // End Program Storage err = flex_end_store(boardID, 1); CheckError; //-------------------------------------------------------- // Host program. This programs monitors the 13th bit in the // move complete status register and records the position // the axis is going to move to //-------------------------------------------------------- do { // Check the move complete status/following error/axis off status err = flex_read_axis_status_rtn(boardID, axis, &axisStatus); CheckError; // 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; } // Read the move complete status register and once the 13th bit is set // reset the bit and reads the target position err = flex_read_mcs_rtn(boardID, &moveCompleteStatus); CheckError; if(moveCompleteStatus & (1<<13)){ i32 currentTargetPosition; // Reset the 13th bit in the move complete status register err = flex_set_status_momo(boardID, 0, 0x20); CheckError; err = flex_read_var_rtn(boardID, 1, ¤tTargetPosition); CheckError; } Sleep (50); // Check every 50 ms }while (!(axisStatus & NIMC_FOLLOWING_ERROR_BIT) && !(axisStatus & NIMC_AXIS_OFF_BIT)); // Exit on move complete/following error/axis off 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 }