Synchronizing Host Applications with Onboard Programs C/C++ Code

NI-Motion

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, &currentTargetPosition);
         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
}