Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed


// This example uses the Kinesis C++ API to move and control Thorlabs integrated stepper motor, LTS, K10CR1, and MLJ stages.
/* Default parameters
HS LTS300C 300mm Stage

General

Name = HS LTS300C 300mm Stage
Stage ID = Unknown
Axis ID = SingleAxis

Home Settings

HomeDir = MOT_Reverse
HomeLimitSwitch = MOT_ReverseLimitSwitch
HomeVel = 2
HomeZeroOffset = 0,5

Jog Settings

JogMode = MOT_ExtSingleStep
JogStopMode = MOT_Profiled
JogStepSize = 5,0
JogMinVel = 0,0
JogAccn = 10,0
JogMaxVel = 10,0

Control Settings

DefMinVel = 0,0
DefAccn = 20,0
DefMaxVel = 20,0

Limit Settings

CWHardLimit = MOT_LimitSwitchMakeOnContact
CCWHardLimit = MOT_LimitSwitchMakeOnContact
CWSoftLimit = 3,0
CCWSoftLimit = 1,0
SoftLimitMode = MOT_LimitSwitchIgnored
LimitsSoftwareApproachPolicy = DisallowIllegalMoves

Physical Settings

Pitch = 1,0
StepsPerRev = 200
GearboxRatio = 1
TST101 Stage ID = 0
UseDeviceUnits = False
Units = MOT_Linear
DirSense = MOT_Backwards
MinPos = 0,00
MaxPos = 300,00
MaxAccn = 50,0
MaxVel = 50,0
MaxContinuousVel = 40,0
Factor = 1,0
UnitsTxt = mm
DisplayDP = -1

Misc. Settings

BacklashDist = 0,05
MoveFactor = 30
RestFactor = 5

Stepper Motor Settings

Pitch = 1,0
StepsPerRev = 200
GearboxRatio = 1
TST101 Stage ID = 0
UseDeviceUnits = False
Units = MOT_Linear
DirSense = MOT_Backwards
MinPos = 0,00
MaxPos = 300,00
MaxAccn = 50,0
MaxVel = 50,0
MaxContinuousVel = 40,0
Factor = 1,0
UnitsTxt = mm
DisplayDP = -1

Velocity Profile Settings

BowIndex = 0

Button Settings

ButtonMode = MOT_JogMode
ButtonPos1 = 10,0
ButtonPos2 = 20,0

Potentiometer Settings

FPControls = True
PotZeroWnd = 1
PotVel1 = 5,0
PotWnd1 = 50
PotVel2 = 10,0
PotWnd2 = 80
PotVel3 = 15,0
PotWnd3 = 100
PotVel4 = 20,0


*/


//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 <userint.h>
#include <utility.h>
#include "ThorlabsLTS_ui.h"


#include "ThorlabsMotionControlIntegratedStepperMotors.h"


void LTS_waitMove(int i, int timeout);
void LTS_waitHome(int i, int timeout);
char serialNumbers[][9] = {"45388004", "45387934","45388034"};  

// Set number of microsteps, found in APT communications protocol. Should be changed to 136533 if using K10CR1
int StepsPerMm = 409600;
double SingleMove=1; // in mm

int LTSTimerOut=0;
int p1_h;


int CVICALLBACK LTS_Timeout (int panel, int control, int event,
                             void *callbackData, int eventData1, int eventData2) {
  switch (event) {
    case EVENT_TIMER_TICK:
      LTSTimerOut = 1;
      printf("LTS timeout\n");
      break;
  }
  return 0;
}

/*
void LTS_Timerast (int signumber) {
  LTSTimerOut = 1;
  printf("TIMEOUT !!!\n");
  SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_ENABLED, 0);
}
*/


void LTS_Tmlnk (int tout) {
  LTSTimerOut = 0;
  SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_INTERVAL, (float)tout/1000.);
  SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_ENABLED, 1);
}

void LTS_Tmulk ( void ) {
  SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_ENABLED, 0);
  LTSTimerOut = 0;
}

void LTS_Home(int i,int wait){

//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( "Start Homing...\n");
                if (wait) LTS_waitHome(i, wait);
                // printf( "Homed...\n");
}

int LTS_Init(int i){

  int errorReturn = ISC_Open(serialNumbers[i]);
  /*
  double stepsPerRev = 200;
  double gearBoxRatio = 1;
  double pitch = 1;
  int err = ISC_SetMotorParamsExt(serialNumbers[i], stepsPerRev, gearBoxRatio, pitch);
  err = ISC_GetMotorParamsExt(serialNumbers[i], &stepsPerRev, &gearBoxRatio, &pitch);
  // No effect
  */

  Sleep(1000);
  if (errorReturn == 0){
          printf( "Device %d (serial %s) Connected... \n",i, serialNumbers[i]);
          //Settings are loaded based on Stage Name. The integrated stepper class holds LTS and K10CR1 Information.
          ISC_SetLEDswitches(serialNumbers[i], 0); // disable LED
          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_StopProfiled(int i){
  ISC_StopProfiled(serialNumbers[i]);
}  

void LTS_MoveAbsolute(int i, double position, int wait){
        ISC_SetMoveAbsolutePosition(serialNumbers[i], (position*StepsPerMm));
    ISC_MoveAbsolute(serialNumbers[i]);
        if (wait) LTS_waitMove(i, wait);
       
}

void LTS_MoveRelative(int i, double distance, int wait){
        ISC_SetMoveRelativeDistance(serialNumbers[i], (distance*StepsPerMm));
    ISC_MoveRelativeDistance(serialNumbers[i]);
        if (wait) LTS_waitMove(i, wait);
}


double LTS_GetPosition(int i){
  int device_unit = ISC_GetPosition(serialNumbers[i]); ;
  double real_unit = 1.0*device_unit / StepsPerMm;
  //const int unitType = 0 ;// 0 .. distance , 1 .. velocity, 2 .. acceleration
  // does not work int err = ISC_GetRealValueFromDeviceUnit(serialNumbers[i], device_unit,&real_unit, unitType);
  // printf("err = 0x%x pos %d %f\n", err ,device_unit, real_unit);
  return real_unit;
}

unsigned int LTS_GetStatus(int i){
  return ISC_GetStatusBits(serialNumbers[i]);
}  


int LTS_Enable(int i){
  return ISC_EnableChannel(serialNumbers[i]);
}


int LTS_Disable(int i){
  return ISC_DisableChannel(serialNumbers[i]);
}


int LTS_GetNumberPositions(int i){
  return ISC_GetNumberPositions(serialNumbers[i]);
}

int LTS_Open(){

  TLI_BuildDeviceList();
  TLI_DeviceInfo info;
  int err=0;
  for (int i=0;i<3;i++){
        TLI_GetDeviceInfo(serialNumbers[i], &info);
        Sleep(100);
        err = LTS_Init(i);
        printf("%s err=%x\n", info.description, err);
        if (err) return err;
  }
  return 0;
}


void LTS_RegisterMessageCallback(int i, void (* functionPointer)()){
  ISC_RegisterMessageCallback(serialNumbers[i], functionPointer );
}

void LTS_GetRealValueFromDeviceUnit(int i, int device_unit, double *real_unit, int unitType){
  ISC_GetRealValueFromDeviceUnit(serialNumbers[i], device_unit, real_unit, unitType);
}

void LTS_GetDeviceUnitFromRealValue(int i, double real_unit, int *device_unit, int unitType){
  ISC_GetDeviceUnitFromRealValue(serialNumbers[i], real_unit, device_unit, unitType);
}
//Waits should only be used for Home commands. The home command has a different status return.
void LTS_waitHome(int i, int tout)// Waits until a single axis is homed.
{
        WORD messageType=0;
        WORD messageId=0;
        DWORD messageData=0;
        int condition=0;
        LTS_Tmlnk (tout);
        do {
                while (!ISC_MessageQueueSize(serialNumbers[i])){
                  Sleep(250);
                  if (LTSTimerOut) break;
                }
                if (LTSTimerOut){
                        printf( "Timeout in axis [%d] pos: %f messageType %d, messageId %d\n",i,LTS_GetPosition(i), messageType, messageId);
                        break;
                }
                ISC_GetNextMessage(serialNumbers[i], &messageType, &messageId, &messageData);
                condition = (messageType == 2) && (messageId == 0);
               
        } while (!condition || !LTSTimerOut);
           
        LTS_Tmulk();
}

void LTS_waitMove(int i, int tout)// Waits until axis is stopped.
{
        WORD  messageType=0;
        WORD  messageId=0;
        DWORD messageData=0;
        int condition=0;  
        LTS_Tmlnk (tout);
        do {
                while (!ISC_MessageQueueSize(serialNumbers[i])){
                  Sleep(250);
                  if (LTSTimerOut) break;
                }
                if (LTSTimerOut){
                        printf( "Timeout in axis [%d] pos: %f messageType %d, messageId %d\n",i,LTS_GetPosition(i), messageType, messageId);
                        break;
                }
                ISC_GetNextMessage(serialNumbers[i], &messageType, &messageId, &messageData);
                condition = (messageType == 2) && (messageId == 1);
               
        } while (!condition);      
       
         
        LTS_Tmulk();
}
//*******************************************************************

#ifdef LTS_MAIN


int rID, tfID;

#define MAX_THREADS 10
static CmtThreadPoolHandle poolHandle = 0;
int lid[][14]= {
          {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_L1_2,P1_L2_2,P1_L3_2,P1_L4_2,P1_L5_2,P1_L6_2,P1_L7_2,P1_L8_2,P1_L9_2,P1_L10_2,P1_L11_2,P1_L12_2,P1_L13_2,P1_L14_2},
          {P1_L1_3,P1_L2_3,P1_L3_3,P1_L4_3,P1_L5_3,P1_L6_3,P1_L7_3,P1_L8_3,P1_L9_3,P1_L10_3,P1_L11_3,P1_L12_3,P1_L13_3,P1_L14_3}};
int dstat[3]={P1_N2,P1_N2_2,P1_N2_3};
int dpos[3]={P1_XP,P1_YP,P1_ZP};
int ctrl_c=0;

void LTS_SetStatus(int nid){

        int status=LTS_GetStatus(nid);
        SetCtrlVal (p1_h, dstat[nid], status);
        SetCtrlVal (p1_h, lid[nid][12], (status & 0x20000000)>0);
        SetCtrlVal (p1_h, lid[nid][13], (status & 0x80000000)>0);
                 
        for (int i=0; i<12; i++) {
          SetCtrlVal (p1_h, lid[nid][i], status & 1);
          status>>=1;
        }
                 
}



void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle,
                               CmtThreadFunctionID functionID, unsigned int event,
                               int value, void *callbackData  ) {
  SetCtrlVal (p1_h, P1_SCANLED, 0);
  ctrl_c=0;
  return ;

}

int CVICALLBACK daq(void *functionData) {
        ctrl_c =0;
        SetCtrlVal (p1_h, P1_SCANLED, 1);
        int nx,ny,nz;
        GetCtrlVal(p1_h,P1_NX, &nx);
        GetCtrlVal(p1_h,P1_NY, &ny);
        GetCtrlVal(p1_h,P1_NZ, &nz);
       
        double dx,dy,dz;
        GetCtrlVal(p1_h,P1_DX, &dx);
        GetCtrlVal(p1_h,P1_DY, &dy);
        GetCtrlVal(p1_h,P1_DZ, &dz);
       
        double x0,y0,z0;
        GetCtrlVal(p1_h,P1_X0, &x0);
        GetCtrlVal(p1_h,P1_Y0, &y0);
        GetCtrlVal(p1_h,P1_Z0, &z0);
       
        int cbx,cby,cbz;
        int timeout=10000; // timeout in ms
        GetCtrlVal(p1_h,P1_CBX, &cbx);
        GetCtrlVal(p1_h,P1_CBY, &cby);
        GetCtrlVal(p1_h,P1_CBZ, &cbz);
       
    if (!cbx) nx=1;
        if (!cby) ny=1;
        if (!cbz) nz=1;
        int  nstep=0;
        double totalSteps=nx*ny*nz;
        for (int iz=0;iz<nz;iz++){
          double zposition= z0+ iz*dz;
         
          SetCtrlVal(p1_h,P1_IZ, iz);
          SetCtrlVal(p1_h,P1_DAQLED, 1);
          LTS_MoveAbsolute(2,zposition,timeout);
          SetCtrlVal(p1_h,P1_DAQLED, 0);
          for (int iy=0;iy<ny;iy++){
                double yposition= y0+ iy*dy;
               
                SetCtrlVal(p1_h,P1_IY, iy);
                SetCtrlVal(p1_h,P1_DAQLED, 1);
                LTS_MoveAbsolute(1,yposition,timeout);
                SetCtrlVal(p1_h,P1_DAQLED, 0);
            for (int ix=0;ix<nx;ix++){
                   double xposition= x0+ ix*dx;
                   
                   SetCtrlVal(p1_h,P1_IX, ix);
                   SetCtrlVal(p1_h,P1_DAQLED, 1);
                   LTS_MoveAbsolute(0,xposition,timeout);
                   SetCtrlVal(p1_h,P1_DAQLED, 0);
                   
                   for (int k=0;k<3;k++){  
             double n2 = LTS_GetPosition(k);
             SetCtrlVal (p1_h, dpos[k], n2);
                     LTS_SetStatus(k);
                   }
                   
                   //printf("[%d]\n",nstep++);
                   nstep++;
                   double ratio = nstep/totalSteps;
                   SetCtrlVal(p1_h,P1_PROGRESS, 100.*ratio);
                   Delay(0.1);
                   
                   if (ctrl_c) break;
            }
                if (ctrl_c) break;
          }
          if (ctrl_c) break;
        }
       
        return 0;
}


void MessageCB(){
        //printf("Message %d\n",d[0]);
        return;
}

int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpszCmdLine, int nCmdShow) {


  int evcontrl,evpanel,ierr;
  double n2;
  int comled;
  int enabled=0;
 

  SetSleepPolicy(VAL_SLEEP_MORE);
  CmtNewThreadPool (MAX_THREADS,  &poolHandle);
  SetStdioPort (CVI_STDIO_WINDOW);
  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_B3);

  GetCtrlVal (p1_h, P1_COMLED, &comled);
  if (!comled) {
      //GetCtrlVal (p1_h, P1_PORT, &port);
      //if (MIKRO_Open (port)) continue;
      LTS_Open();
       
      SetCtrlVal (p1_h, P1_COMLED, 1);
          for (int i=0;i<3;i++) LTS_RegisterMessageCallback(i, &MessageCB );
  }

  int scanled=0;
  while (1) {
    ierr = GetUserEvent (1, &evpanel, &evcontrl);
        //printf("GetUserEvent %d %d\n", evpanel, evcontrl);
 
       
        if (evcontrl == P1_STOPSCAN) ctrl_c=1;
        GetCtrlVal (p1_h, P1_SCANLED, &scanled);
        if (scanled) continue;
        if (evcontrl == P1_B1) break;
    switch (evcontrl) {
      case P1_BL:
        LTS_MoveRelative(0,-SingleMove, 0);
        break;
      case P1_BR:
        LTS_MoveRelative(0,+SingleMove, 0);
        break;
      case P1_BU:
        LTS_MoveRelative(1,+SingleMove, 0);
        break;
      case P1_BD:
        LTS_MoveRelative(1,-SingleMove, 0);
        break;
      case P1_BF:
        LTS_MoveRelative(2,+SingleMove, 0);
        break;
      case P1_BB:
        LTS_MoveRelative(2,-SingleMove, 0);
        break;
      case P1_HO:
        LTS_Home(0,0);
        break;
          case P1_HO_2:
        LTS_Home(1,0);
        break;
          case P1_HO_3:
        LTS_Home(2,0);
        break;
      case P1_GX:
        GetCtrlVal (p1_h, P1_XG, &n2);
                LTS_MoveAbsolute(0,n2,0);
        break;
      case P1_GY:
        GetCtrlVal (p1_h, P1_YG, &n2);
        LTS_MoveAbsolute(1,n2,0);
        break;
      case P1_GZ:
        GetCtrlVal (p1_h, P1_ZG, &n2);
        LTS_MoveAbsolute(2,n2,0);
        break;
      case P1_G:
        GetCtrlVal (p1_h, P1_XG, &n2);
        LTS_MoveAbsolute(0,n2,0);
        GetCtrlVal (p1_h, P1_YG, &n2);
        LTS_MoveAbsolute(1,n2,0);
        GetCtrlVal (p1_h, P1_ZG, &n2);
        LTS_MoveAbsolute(2,n2,0);
                break;
      case P1_B3: // reset
      case P1_B3_2: // reset
          case P1_B3_3: // reset
                printf("RST Not yet implemented\n");
        break;
          case P1_STOP:
        LTS_StopProfiled(0);
        break;
          case P1_STOP_2:
        LTS_StopProfiled(1);
        break;
          case P1_STOP_3:
        LTS_StopProfiled(2);
        break; 
      case P1_EN:
        LTS_Enable(0);
        break;
          case P1_EN_2:
        LTS_Enable(1);
        break;
          case P1_EN_3:
        LTS_Enable(2);
        break;
          case P1_DIS:
        LTS_Disable(0);
        break;
          case P1_DIS_2:
        LTS_Disable(1);
        break;
          case P1_DIS_3:
        LTS_Disable(2);
        break;
          case P1_TIMER:
                for (int k=0;k<3;k++){  
          double position = LTS_GetPosition(k);
          SetCtrlVal (p1_h, dpos[k], position);
                  LTS_SetStatus(k);
                }
        break;
          case P1_SCAN:
                 
                enabled=1;
                const int LTS_Enabled = 0x80000000;
                for (int i=0;i<3;i++) if (!(LTS_GetStatus(i)& LTS_Enabled)) enabled =0;
                if (enabled){  
                  SetCtrlVal(p1_h,P1_DAQLED, 0);
                  CmtScheduleThreadPoolFunctionAdv (poolHandle, daq, &rID,
                                        DEFAULT_THREAD_PRIORITY,
                                        EndOfThread,
                                        EVENT_TP_THREAD_FUNCTION_END,
                                        NULL, RUN_IN_SCHEDULED_THREAD,
                                        &tfID);
                } else {
                  MessagePopup ("Error", "Enable LTS Stages First");
                }        
                break;
      default:
        break;
    }
    Delay(0.001);
   
  }

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

  return 0;
}




int CVICALLBACK TimerCB (int panel, int control, int event,
                                                 void *callbackData, int eventData1, int eventData2)
{
        int isrunning;
        switch (event)
        {
                case EVENT_TIMER_TICK:
                        GetCtrlVal (p1_h, P1_SCANLED, &isrunning);
                        if (!isrunning) QueueUserEvent (1, p1_h, P1_TIMER);
                        break;
        }
        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(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