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
}