Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

// C++ Example for Thorlabs LTS stages;
// 2023-09-06;
// 2023-09-06;
// C++20;
// Kinesis 1.14.37;
// ==================
// This example uses the Kinesis C++ API to move and control Thorlabs integrated stepper motor, LTS, K10CR1, and MLJ stages.


//CVI Add dll path to: Options>Environment>Include Path> C:\Program Files\Thorlabs\Kinesis
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
#include <utility.h>


#include "ThorlabsMotionControlIntegratedStepperMotors.h"


void waitMove(char serialNo[]);
void waitHome(char serialNo[]);
char serialNumbers[][9] = {"45388004", "45387934","45388034"};  
       
// Set number of microsteps, found in APT communications protocol. Should be changed to 136533 if using K10CR1
int conversionRate = 409600;

void LTS_Home(int i){

//Set up homing parameters.
                MOT_HomingParameters homingParams;
                ISC_GetHomingParamsBlock(serialNumbers[i], &homingParams);
                homingParams.direction = MOT_Reverse;
                ISC_SetHomingParamsBlock(serialNumbers[i], &homingParams);

                //Clear existing messages in the hardware buffer.
                ISC_ClearMessageQueue(serialNumbers[i]);

                //Home the stage and wait for the return message before continuing.
                ISC_Home(serialNumbers[i]);
                printf( "Homing...\n");
                waitHome(serialNumbers[i]);
                printf( "Homed...\n");
}

int LTS_Init(int i){

  int errorReturn = ISC_Open(serialNumbers[i]);
  Sleep(1000);
  if (errorReturn == 0){
          printf( "Device %d (%s) Connected...\n",i, serialNumbers[i] );
          //Settings are loaded based on Stage Name. The integrated stepper class holds LTS and K10CR1 Information.
          ISC_StartPolling(serialNumbers[i], 50);
          Sleep(1000);
  } else {
          printf( "Error connecting device %d (%s)\n",i, serialNumbers[i] );  
  }
  return errorReturn;
}

void LTS_Close(int i){
//Close the stage
        ISC_StopPolling(serialNumbers[i]);
        ISC_Close(serialNumbers[i]);
        printf( "Device Disconnected...\n");
}

void LTS_MoveAbsolute(int i, int position){
        ISC_SetMoveAbsolutePosition(serialNumbers[i], conversionRate * position);
    ISC_MoveAbsolute(serialNumbers[i]);
       
}

void LTS_MoveRelative(int i, int distance){
        ISC_SetMoveRelativeDistance(serialNumbers[i], distance);
    ISC_MoveRelativeDistance(serialNumbers[i]);
}


int LTS_GetPosition(int i){
  return ISC_GetPosition(serialNumbers[i]);
}


//Waits should only be used for Home commands. The home command has a different status return.
void waitHome(char serialNo[])// Waits until a single axis is homed.
{
        WORD messageType;
        WORD messageId;
        DWORD messageData;
        ISC_WaitForMessage(serialNo, &messageType, &messageId, &messageData);
        while (messageType != 2 || messageId != 0)
        {
                ISC_WaitForMessage(serialNo, &messageType, &messageId, &messageData);
                printf( "pos: %d\n" ,     ISC_GetPosition(serialNo) );

        }
}

void waitMove(char serialNo[])// Waits until axis is stopped.
{
        WORD messageType;
        WORD messageId;
        DWORD messageData;
        ISC_WaitForMessage(serialNo, &messageType, &messageId, &messageData);
        while (messageType != 2 || messageId != 1)
        {
                ISC_WaitForMessage(serialNo, &messageType, &messageId, &messageData);
                printf( "pos: %d\n",      ISC_GetPosition(serialNo) );      
        }
}



#ifdef THORLABS_MAIN

int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpszCmdLine, int nCmdShow) {
  int i,j;
  int nlines,atline;
  int evcontrl,evpanel,p1_h,ierr,type;
  int rstat,n1,n2, n3, nid;
  int comled;
  int lid[16]= {P1_L1,P1_L2,P1_L3,P1_L4,P1_L5,P1_L6,P1_L7,P1_L8,
                P1_L9,P1_L10,P1_L11,P1_L12,P1_L13,P1_L14,P1_L15,P1_L16
               };
  short int ns2, port;
  char tline[80];

  if (InitCVIRTE (hInstance, 0, 0) == 0) return -1; /* out of memory */

//  p1_h = LoadPanel (0,"ThorlabsLTS_ui.uir", P1);
  p1_h = BuildP1 (0);
  ierr = DisplayPanel (p1_h);
  ierr = SetActiveCtrl (p1_h,P1_B1);
  ierr = SetActiveCtrl (p1_h,P1_B2);
  ierr = SetActiveCtrl (p1_h,P1_B3);

  while (1) {
    ierr = GetUserEvent (1, &evpanel, &evcontrl);
    if (evcontrl == P1_B1) break;
    GetCtrlVal (p1_h, P1_COMLED, &comled);
    if (!comled) {
      GetCtrlVal (p1_h, P1_PORT, &port);
      if (MIKRO_Open (port)) continue;
      MIKRO_Init(1,0);
      MIKRO_Init(2,0);
      MIKRO_Init(3,0);
      SetCtrlVal (p1_h, P1_COMLED, 1);
    }
    switch (evcontrl) {
      case P1_BL:
        MoveRelative(0,1000);
        break;
      case P1_BR:
        MoveRelative(1,1000);
        break;
      case P1_BU:
        MoveRelative(2,1000);
        break;
      case P1_BD:
        MoveRelative(0,-1000);
        break;
      case P1_BF:
        MoveRelative(1,-1000);
        break;
      case P1_BB:
        MoveRelative(2,-1000);
        break;
      case P1_HO:
        ierr = GetCtrlVal (p1_h, P1_N3, &nid);
        LTS_Home(nid);
        break;
      case P1_GX:
        GetCtrlVal (p1_h, P1_XG, &n2);
                LTS_MoveAbsolute(0,n2);
        break;
      case P1_GY:
        GetCtrlVal (p1_h, P1_YG, &n2);
        LTS_MoveAbsolute(1,n2);
        break;
      case P1_GZ:
        GetCtrlVal (p1_h, P1_ZG, &n3);
        LTS_MoveAbsolute(2,n2);
        break;
      case P1_G:
        GetCtrlVal (p1_h, P1_XG, &n2);
        LTS_MoveAbsolute(0,n2);
        GetCtrlVal (p1_h, P1_YG, &n2);
        LTS_MoveAbsolute(1,n2);
        GetCtrlVal (p1_h, P1_ZG, &n3);
        LTS_MoveAbsolute(2,n3);
      case P1_B2:
      case P1_S1:
                  /*
        ierr = GetCtrlVal (p1_h, P1_S1, MIKRO_Send);
        nout = strlen (MIKRO_Send);
        MIKRO_Send[nout++]=13;
        rstat = FlushInQ (MIKRO_Port);
        rstat = ComWrt (MIKRO_Port, MIKRO_Send, nout);
        if ((nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa))!=0)
          nin = ComRdTerm (MIKRO_Port, MIKRO_Receive, 30, 0xa);
        if (nin!=0) nin--;
        MIKRO_Receive[nin]=0;
        switch (nin) {
          case 0:
            ierr = SetCtrlVal (p1_h, P1_N2, 0);
            break;
          case 9:
            nout = sscanf (MIKRO_Receive, "%x %hx", &n1,&ns2);
            ierr = SetCtrlVal (p1_h, P1_N2, ns2);
            break;
          case 13:
            nout = sscanf (MIKRO_Receive, "%x %x", &n1,&n2);
            ierr = SetCtrlVal (p1_h, P1_N2, n2);
            break;
          default:
            break;
        }
        ierr = SetCtrlVal (p1_h, P1_N1, nin);
        ierr = SetCtrlVal (p1_h, P1_S2, MIKRO_Receive);
                  */

        break;
      case P1_B3: // reset
                /*
                  ierr = GetCtrlVal (p1_h, P1_N3, &nid);
        ierr = GetCtrlVal (p1_h, P1_STAGETYPE, &type);
        MIKRO_Reset(nid);
        rstat = GetNumTextBoxLines (p1_h, P1_T1, &atline);
        rstat = InsertTextBoxLine (p1_h, P1_T1, atline, MIKRO_Receive);
        MIKRO_Init(nid, type);
                */

        break;
      case P1_B4: // status
                  /*
        ierr = GetCtrlVal (p1_h, P1_N3, &nid);
        n2=MIKRO_GetStat(nid);
        ierr = SetCtrlVal (p1_h, P1_N2, n2);
        ierr = SetCtrlVal (p1_h, P1_N1, nin);
        ierr = SetCtrlVal (p1_h, P1_S2, MIKRO_Receive);
        for (i=0; i<16; i++) {
          ierr = SetCtrlVal (p1_h, lid[i], n2 & 1);
          n2>>=1;
        }
                  */

        break;
      case P1_EN:
                  /*
        ierr = GetCtrlVal (p1_h, P1_N3, &nid);
        MIKRO_Cmd(nid,"en");
                  */

        break;
      default:
        break;
    }
    Delay(0.1);
    n2 = LTS_GetPosition(0);
       
    SetCtrlVal (p1_h, P1_XP, n2);
    n2 = LTS_GetPosition(1);
    SetCtrlVal (p1_h, P1_YP, n2);
    n2 = LTS_GetPosition(2);
    SetCtrlVal (p1_h, P1_ZP, n2);
  }

  GetCtrlVal (p1_h, P1_COMLED, &comled);
  if (comled) for (int i=0;i<3;i++) LTS_Close (i);

  return 0;
}


#else
// *************************************

int main(int argc, char ** argv)
{
        //Sets up simulations. Comment in if running on physical hardware.
        //TLI_InitializeSimulations();

        //Input serial number. Change for your specific device.
        //serials = ["45388004", "45387934","45388034"]


        //Build Device List and open device.
        TLI_BuildDeviceList();
        TLI_DeviceInfo info;
        int err=0;
        for (int i=0;i<3;i++){
          TLI_GetDeviceInfo(serialNumbers[i], &info);
          printf("%s\n", info.description);
          Sleep(1000);
          err |= LTS_Init(i);
        }  
       
       
        for (int i=0;i<3;i++){

                //Move the stage and wait for the return message before continuing.
                for (int k=0;k<10;k++){
                  LTS_MoveAbsolute(i,k);
                  printf( "Moving ...\n");
                  waitMove(serialNumbers[i]);
                  printf( "Move Complete...\n");
                }
               
         
        }
               
        for (int i=0;i<3;i++){
           LTS_Close(i);
        }
       
        //Closes simulations. Comment if running on physical hardware.
        //TLI_UninitializeSimulations();
        Delay(10);
        return 0;
}
#endif