Subversion Repositories f9daq

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1.  
  2. // This example uses the Kinesis C++ API to move and control Thorlabs integrated stepper motor, LTS, K10CR1, and MLJ stages.
  3. /* Default parameters
  4. HS LTS300C 300mm Stage
  5.  
  6. General
  7.  
  8. Name = HS LTS300C 300mm Stage
  9. Stage ID = Unknown
  10. Axis ID = SingleAxis
  11.  
  12. Home Settings
  13.  
  14. HomeDir = MOT_Reverse
  15. HomeLimitSwitch = MOT_ReverseLimitSwitch
  16. HomeVel = 2
  17. HomeZeroOffset = 0,5
  18.  
  19. Jog Settings
  20.  
  21. JogMode = MOT_ExtSingleStep
  22. JogStopMode = MOT_Profiled
  23. JogStepSize = 5,0
  24. JogMinVel = 0,0
  25. JogAccn = 10,0
  26. JogMaxVel = 10,0
  27.  
  28. Control Settings
  29.  
  30. DefMinVel = 0,0
  31. DefAccn = 20,0
  32. DefMaxVel = 20,0
  33.  
  34. Limit Settings
  35.  
  36. CWHardLimit = MOT_LimitSwitchMakeOnContact
  37. CCWHardLimit = MOT_LimitSwitchMakeOnContact
  38. CWSoftLimit = 3,0
  39. CCWSoftLimit = 1,0
  40. SoftLimitMode = MOT_LimitSwitchIgnored
  41. LimitsSoftwareApproachPolicy = DisallowIllegalMoves
  42.  
  43. Physical Settings
  44.  
  45. Pitch = 1,0
  46. StepsPerRev = 200
  47. GearboxRatio = 1
  48. TST101 Stage ID = 0
  49. UseDeviceUnits = False
  50. Units = MOT_Linear
  51. DirSense = MOT_Backwards
  52. MinPos = 0,00
  53. MaxPos = 300,00
  54. MaxAccn = 50,0
  55. MaxVel = 50,0
  56. MaxContinuousVel = 40,0
  57. Factor = 1,0
  58. UnitsTxt = mm
  59. DisplayDP = -1
  60.  
  61. Misc. Settings
  62.  
  63. BacklashDist = 0,05
  64. MoveFactor = 30
  65. RestFactor = 5
  66.  
  67. Stepper Motor Settings
  68.  
  69. Pitch = 1,0
  70. StepsPerRev = 200
  71. GearboxRatio = 1
  72. TST101 Stage ID = 0
  73. UseDeviceUnits = False
  74. Units = MOT_Linear
  75. DirSense = MOT_Backwards
  76. MinPos = 0,00
  77. MaxPos = 300,00
  78. MaxAccn = 50,0
  79. MaxVel = 50,0
  80. MaxContinuousVel = 40,0
  81. Factor = 1,0
  82. UnitsTxt = mm
  83. DisplayDP = -1
  84.  
  85. Velocity Profile Settings
  86.  
  87. BowIndex = 0
  88.  
  89. Button Settings
  90.  
  91. ButtonMode = MOT_JogMode
  92. ButtonPos1 = 10,0
  93. ButtonPos2 = 20,0
  94.  
  95. Potentiometer Settings
  96.  
  97. FPControls = True
  98. PotZeroWnd = 1
  99. PotVel1 = 5,0
  100. PotWnd1 = 50
  101. PotVel2 = 10,0
  102. PotWnd2 = 80
  103. PotVel3 = 15,0
  104. PotWnd3 = 100
  105. PotVel4 = 20,0
  106.  
  107.  
  108. */
  109.  
  110. //CVI Add dll path to: Options>Environment>Include Path> C:\Program Files\Thorlabs\Kinesis
  111. #include <stdio.h>
  112. #include <stdlib.h>
  113. #include <stdbool.h>
  114. #include <windows.h>
  115. #include <userint.h>
  116. #include <utility.h>
  117. #include "ThorlabsLTS_ui.h"
  118.  
  119.  
  120. #include "ThorlabsMotionControlIntegratedStepperMotors.h"
  121.  
  122.  
  123. void LTS_waitMove(int i, int timeout);
  124. void LTS_waitHome(int i, int timeout);
  125. char serialNumbers[][9] = {"45388004", "45387934","45388034"};  
  126.  
  127. // Set number of microsteps, found in APT communications protocol. Should be changed to 136533 if using K10CR1
  128. int StepsPerMm = 409600;
  129. double SingleMove=1; // in mm
  130.  
  131. int LTSTimerOut=0;
  132. int p1_h;
  133.  
  134.  
  135. int CVICALLBACK LTS_Timeout (int panel, int control, int event,
  136.                              void *callbackData, int eventData1, int eventData2) {
  137.   switch (event) {
  138.     case EVENT_TIMER_TICK:
  139.       LTSTimerOut = 1;
  140.       printf("LTS timeout\n");
  141.       break;
  142.   }
  143.   return 0;
  144. }
  145.  
  146. /*
  147. void LTS_Timerast (int signumber) {
  148.   LTSTimerOut = 1;
  149.   printf("TIMEOUT !!!\n");
  150.   SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_ENABLED, 0);
  151. }
  152. */
  153.  
  154. void LTS_Tmlnk (int tout) {
  155.   LTSTimerOut = 0;
  156.   SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_INTERVAL, (float)tout/1000.);
  157.   SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_ENABLED, 1);
  158. }
  159.  
  160. void LTS_Tmulk ( void ) {
  161.   SetCtrlAttribute (p1_h, P1_TIMEOUT, ATTR_ENABLED, 0);
  162.   LTSTimerOut = 0;
  163. }
  164.  
  165. void LTS_Home(int i,int wait){
  166.  
  167. //Set up homing parameters.
  168.                 MOT_HomingParameters homingParams;
  169.                 ISC_GetHomingParamsBlock(serialNumbers[i], &homingParams);
  170.                 homingParams.direction = MOT_Reverse;
  171.                 ISC_SetHomingParamsBlock(serialNumbers[i], &homingParams);
  172.  
  173.                 //Clear existing messages in the hardware buffer.
  174.                 ISC_ClearMessageQueue(serialNumbers[i]);
  175.  
  176.                 //Home the stage and wait for the return message before continuing.
  177.                 ISC_Home(serialNumbers[i]);
  178.                 printf( "Start Homing...\n");
  179.                 if (wait) LTS_waitHome(i, wait);
  180.                 // printf( "Homed...\n");
  181. }
  182.  
  183. int LTS_Init(int i){
  184.  
  185.   int errorReturn = ISC_Open(serialNumbers[i]);
  186.   /*
  187.   double stepsPerRev = 200;
  188.   double gearBoxRatio = 1;
  189.   double pitch = 1;
  190.   int err = ISC_SetMotorParamsExt(serialNumbers[i], stepsPerRev, gearBoxRatio, pitch);
  191.   err = ISC_GetMotorParamsExt(serialNumbers[i], &stepsPerRev, &gearBoxRatio, &pitch);
  192.   // No effect
  193.   */
  194.   Sleep(1000);
  195.   if (errorReturn == 0){
  196.           printf( "Device %d (serial %s) Connected... \n",i, serialNumbers[i]);
  197.           //Settings are loaded based on Stage Name. The integrated stepper class holds LTS and K10CR1 Information.
  198.           ISC_SetLEDswitches(serialNumbers[i], 0); // disable LED
  199.           ISC_StartPolling(serialNumbers[i], 50);
  200.           Sleep(1000);
  201.   } else {
  202.           printf( "Error connecting device %d (%s)\n",i, serialNumbers[i] );  
  203.   }
  204.   return errorReturn;
  205. }
  206.  
  207. void LTS_Close(int i){
  208. //Close the stage
  209.         ISC_StopPolling(serialNumbers[i]);
  210.         ISC_Close(serialNumbers[i]);
  211.         printf( "Device Disconnected...\n");
  212. }
  213.  
  214. void LTS_StopProfiled(int i){
  215.   ISC_StopProfiled(serialNumbers[i]);
  216. }  
  217.  
  218. void LTS_MoveAbsolute(int i, double position, int wait){
  219.         ISC_SetMoveAbsolutePosition(serialNumbers[i], (position*StepsPerMm));
  220.     ISC_MoveAbsolute(serialNumbers[i]);
  221.         if (wait) LTS_waitMove(i, wait);
  222.        
  223. }
  224.  
  225. void LTS_MoveRelative(int i, double distance, int wait){
  226.         ISC_SetMoveRelativeDistance(serialNumbers[i], (distance*StepsPerMm));
  227.     ISC_MoveRelativeDistance(serialNumbers[i]);
  228.         if (wait) LTS_waitMove(i, wait);
  229. }
  230.  
  231.  
  232. double LTS_GetPosition(int i){
  233.   int device_unit = ISC_GetPosition(serialNumbers[i]); ;
  234.   double real_unit = 1.0*device_unit / StepsPerMm;
  235.   //const int unitType = 0 ;// 0 .. distance , 1 .. velocity, 2 .. acceleration
  236.   // does not work int err = ISC_GetRealValueFromDeviceUnit(serialNumbers[i], device_unit,&real_unit, unitType);
  237.   // printf("err = 0x%x pos %d %f\n", err ,device_unit, real_unit);
  238.   return real_unit;
  239. }
  240.  
  241. unsigned int LTS_GetStatus(int i){
  242.   return ISC_GetStatusBits(serialNumbers[i]);
  243. }  
  244.  
  245.  
  246. int LTS_Enable(int i){
  247.   return ISC_EnableChannel(serialNumbers[i]);
  248. }
  249.  
  250.  
  251. int LTS_Disable(int i){
  252.   return ISC_DisableChannel(serialNumbers[i]);
  253. }
  254.  
  255.  
  256. int LTS_GetNumberPositions(int i){
  257.   return ISC_GetNumberPositions(serialNumbers[i]);
  258. }
  259.  
  260. int LTS_Open(){
  261.  
  262.   TLI_BuildDeviceList();
  263.   TLI_DeviceInfo info;
  264.   int err=0;
  265.   for (int i=0;i<3;i++){
  266.         TLI_GetDeviceInfo(serialNumbers[i], &info);
  267.         Sleep(100);
  268.         err = LTS_Init(i);
  269.         printf("%s err=%x\n", info.description, err);
  270.         if (err) return err;
  271.   }
  272.   return 0;
  273. }
  274.  
  275.  
  276. void LTS_RegisterMessageCallback(int i, void (* functionPointer)()){
  277.   ISC_RegisterMessageCallback(serialNumbers[i], functionPointer );
  278. }
  279.  
  280. void LTS_GetRealValueFromDeviceUnit(int i, int device_unit, double *real_unit, int unitType){
  281.   ISC_GetRealValueFromDeviceUnit(serialNumbers[i], device_unit, real_unit, unitType);
  282. }
  283.  
  284. void LTS_GetDeviceUnitFromRealValue(int i, double real_unit, int *device_unit, int unitType){
  285.   ISC_GetDeviceUnitFromRealValue(serialNumbers[i], real_unit, device_unit, unitType);
  286. }
  287. //Waits should only be used for Home commands. The home command has a different status return.
  288. void LTS_waitHome(int i, int tout)// Waits until a single axis is homed.
  289. {
  290.         WORD messageType=0;
  291.         WORD messageId=0;
  292.         DWORD messageData=0;
  293.         int condition=0;
  294.         LTS_Tmlnk (tout);
  295.         do {
  296.                 while (!ISC_MessageQueueSize(serialNumbers[i])){
  297.                   Sleep(250);
  298.                   if (LTSTimerOut) break;
  299.                 }
  300.                 if (LTSTimerOut){
  301.                         printf( "Timeout in axis [%d] pos: %f messageType %d, messageId %d\n",i,LTS_GetPosition(i), messageType, messageId);
  302.                         break;
  303.                 }
  304.                 ISC_GetNextMessage(serialNumbers[i], &messageType, &messageId, &messageData);
  305.                 condition = (messageType == 2) && (messageId == 0);
  306.                
  307.         } while (!condition || !LTSTimerOut);
  308.            
  309.         LTS_Tmulk();
  310. }
  311.  
  312. void LTS_waitMove(int i, int tout)// Waits until axis is stopped.
  313. {
  314.         WORD  messageType=0;
  315.         WORD  messageId=0;
  316.         DWORD messageData=0;
  317.         int condition=0;  
  318.         LTS_Tmlnk (tout);
  319.         do {
  320.                 while (!ISC_MessageQueueSize(serialNumbers[i])){
  321.                   Sleep(250);
  322.                   if (LTSTimerOut) break;
  323.                 }
  324.                 if (LTSTimerOut){
  325.                         printf( "Timeout in axis [%d] pos: %f messageType %d, messageId %d\n",i,LTS_GetPosition(i), messageType, messageId);
  326.                         break;
  327.                 }
  328.                 ISC_GetNextMessage(serialNumbers[i], &messageType, &messageId, &messageData);
  329.                 condition = (messageType == 2) && (messageId == 1);
  330.                
  331.         } while (!condition);      
  332.        
  333.          
  334.         LTS_Tmulk();
  335. }
  336. //*******************************************************************
  337.  
  338. #ifdef LTS_MAIN
  339.  
  340.  
  341. int rID, tfID;
  342.  
  343. #define MAX_THREADS 10
  344. static CmtThreadPoolHandle poolHandle = 0;
  345. int lid[][14]= {
  346.           {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},
  347.           {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},
  348.           {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}};
  349. int dstat[3]={P1_N2,P1_N2_2,P1_N2_3};
  350. int dpos[3]={P1_XP,P1_YP,P1_ZP};
  351. int ctrl_c=0;
  352.  
  353. void LTS_SetStatus(int nid){
  354.  
  355.         int status=LTS_GetStatus(nid);
  356.         SetCtrlVal (p1_h, dstat[nid], status);
  357.         SetCtrlVal (p1_h, lid[nid][12], (status & 0x20000000)>0);
  358.         SetCtrlVal (p1_h, lid[nid][13], (status & 0x80000000)>0);
  359.                  
  360.         for (int i=0; i<12; i++) {
  361.           SetCtrlVal (p1_h, lid[nid][i], status & 1);
  362.           status>>=1;
  363.         }
  364.                  
  365. }
  366.  
  367.  
  368.  
  369. void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle,
  370.                                CmtThreadFunctionID functionID, unsigned int event,
  371.                                int value, void *callbackData  ) {
  372.   SetCtrlVal (p1_h, P1_SCANLED, 0);
  373.   ctrl_c=0;
  374.   return ;
  375.  
  376. }
  377.  
  378. int CVICALLBACK daq(void *functionData) {
  379.         ctrl_c =0;
  380.         SetCtrlVal (p1_h, P1_SCANLED, 1);
  381.         int nx,ny,nz;
  382.         GetCtrlVal(p1_h,P1_NX, &nx);
  383.         GetCtrlVal(p1_h,P1_NY, &ny);
  384.         GetCtrlVal(p1_h,P1_NZ, &nz);
  385.        
  386.         double dx,dy,dz;
  387.         GetCtrlVal(p1_h,P1_DX, &dx);
  388.         GetCtrlVal(p1_h,P1_DY, &dy);
  389.         GetCtrlVal(p1_h,P1_DZ, &dz);
  390.        
  391.         double x0,y0,z0;
  392.         GetCtrlVal(p1_h,P1_X0, &x0);
  393.         GetCtrlVal(p1_h,P1_Y0, &y0);
  394.         GetCtrlVal(p1_h,P1_Z0, &z0);
  395.        
  396.         int cbx,cby,cbz;
  397.         int timeout=10000; // timeout in ms
  398.         GetCtrlVal(p1_h,P1_CBX, &cbx);
  399.         GetCtrlVal(p1_h,P1_CBY, &cby);
  400.         GetCtrlVal(p1_h,P1_CBZ, &cbz);
  401.        
  402.     if (!cbx) nx=1;
  403.         if (!cby) ny=1;
  404.         if (!cbz) nz=1;
  405.         int  nstep=0;
  406.         double totalSteps=nx*ny*nz;
  407.         for (int iz=0;iz<nz;iz++){
  408.           double zposition= z0+ iz*dz;
  409.          
  410.           SetCtrlVal(p1_h,P1_IZ, iz);
  411.           SetCtrlVal(p1_h,P1_DAQLED, 1);
  412.           LTS_MoveAbsolute(2,zposition,timeout);
  413.           SetCtrlVal(p1_h,P1_DAQLED, 0);
  414.           for (int iy=0;iy<ny;iy++){
  415.                 double yposition= y0+ iy*dy;
  416.                
  417.                 SetCtrlVal(p1_h,P1_IY, iy);
  418.                 SetCtrlVal(p1_h,P1_DAQLED, 1);
  419.                 LTS_MoveAbsolute(1,yposition,timeout);
  420.                 SetCtrlVal(p1_h,P1_DAQLED, 0);
  421.             for (int ix=0;ix<nx;ix++){
  422.                    double xposition= x0+ ix*dx;
  423.                    
  424.                    SetCtrlVal(p1_h,P1_IX, ix);
  425.                    SetCtrlVal(p1_h,P1_DAQLED, 1);
  426.                    LTS_MoveAbsolute(0,xposition,timeout);
  427.                    SetCtrlVal(p1_h,P1_DAQLED, 0);
  428.                    
  429.                    for (int k=0;k<3;k++){  
  430.              double n2 = LTS_GetPosition(k);
  431.              SetCtrlVal (p1_h, dpos[k], n2);
  432.                      LTS_SetStatus(k);
  433.                    }
  434.                    
  435.                    //printf("[%d]\n",nstep++);
  436.                    nstep++;
  437.                    double ratio = nstep/totalSteps;
  438.                    SetCtrlVal(p1_h,P1_PROGRESS, 100.*ratio);
  439.                    Delay(0.1);
  440.                    
  441.                    if (ctrl_c) break;
  442.             }
  443.                 if (ctrl_c) break;
  444.           }
  445.           if (ctrl_c) break;
  446.         }
  447.        
  448.         return 0;
  449. }
  450.  
  451.  
  452. void MessageCB(){
  453.         //printf("Message %d\n",d[0]);
  454.         return;
  455. }
  456.  
  457. int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  458.                        LPSTR lpszCmdLine, int nCmdShow) {
  459.  
  460.  
  461.   int evcontrl,evpanel,ierr;
  462.   double n2;
  463.   int comled;
  464.   int enabled=0;
  465.  
  466.  
  467.   SetSleepPolicy(VAL_SLEEP_MORE);
  468.   CmtNewThreadPool (MAX_THREADS,  &poolHandle);
  469.   SetStdioPort (CVI_STDIO_WINDOW);
  470.   if (InitCVIRTE (hInstance, 0, 0) == 0) return -1; /* out of memory */
  471.  
  472.   p1_h = LoadPanel (0,"ThorlabsLTS_ui.uir", P1);
  473.   //p1_h = BuildP1 (0);
  474.   ierr = DisplayPanel (p1_h);
  475.   ierr = SetActiveCtrl (p1_h,P1_B1);
  476.   ierr = SetActiveCtrl (p1_h,P1_B3);
  477.  
  478.   GetCtrlVal (p1_h, P1_COMLED, &comled);
  479.   if (!comled) {
  480.       //GetCtrlVal (p1_h, P1_PORT, &port);
  481.       //if (MIKRO_Open (port)) continue;
  482.       LTS_Open();
  483.        
  484.       SetCtrlVal (p1_h, P1_COMLED, 1);
  485.           for (int i=0;i<3;i++) LTS_RegisterMessageCallback(i, &MessageCB );
  486.   }
  487.  
  488.   int scanled=0;
  489.   while (1) {
  490.     ierr = GetUserEvent (1, &evpanel, &evcontrl);
  491.         //printf("GetUserEvent %d %d\n", evpanel, evcontrl);
  492.  
  493.        
  494.         if (evcontrl == P1_STOPSCAN) ctrl_c=1;
  495.         GetCtrlVal (p1_h, P1_SCANLED, &scanled);
  496.         if (scanled) continue;
  497.         if (evcontrl == P1_B1) break;
  498.     switch (evcontrl) {
  499.       case P1_BL:
  500.         LTS_MoveRelative(0,-SingleMove, 0);
  501.         break;
  502.       case P1_BR:
  503.         LTS_MoveRelative(0,+SingleMove, 0);
  504.         break;
  505.       case P1_BU:
  506.         LTS_MoveRelative(1,+SingleMove, 0);
  507.         break;
  508.       case P1_BD:
  509.         LTS_MoveRelative(1,-SingleMove, 0);
  510.         break;
  511.       case P1_BF:
  512.         LTS_MoveRelative(2,+SingleMove, 0);
  513.         break;
  514.       case P1_BB:
  515.         LTS_MoveRelative(2,-SingleMove, 0);
  516.         break;
  517.       case P1_HO:
  518.         LTS_Home(0,0);
  519.         break;
  520.           case P1_HO_2:
  521.         LTS_Home(1,0);
  522.         break;
  523.           case P1_HO_3:
  524.         LTS_Home(2,0);
  525.         break;
  526.       case P1_GX:
  527.         GetCtrlVal (p1_h, P1_XG, &n2);
  528.                 LTS_MoveAbsolute(0,n2,0);
  529.         break;
  530.       case P1_GY:
  531.         GetCtrlVal (p1_h, P1_YG, &n2);
  532.         LTS_MoveAbsolute(1,n2,0);
  533.         break;
  534.       case P1_GZ:
  535.         GetCtrlVal (p1_h, P1_ZG, &n2);
  536.         LTS_MoveAbsolute(2,n2,0);
  537.         break;
  538.       case P1_G:
  539.         GetCtrlVal (p1_h, P1_XG, &n2);
  540.         LTS_MoveAbsolute(0,n2,0);
  541.         GetCtrlVal (p1_h, P1_YG, &n2);
  542.         LTS_MoveAbsolute(1,n2,0);
  543.         GetCtrlVal (p1_h, P1_ZG, &n2);
  544.         LTS_MoveAbsolute(2,n2,0);
  545.                 break;
  546.       case P1_B3: // reset
  547.       case P1_B3_2: // reset
  548.           case P1_B3_3: // reset
  549.                 printf("RST Not yet implemented\n");
  550.         break;
  551.           case P1_STOP:
  552.         LTS_StopProfiled(0);
  553.         break;
  554.           case P1_STOP_2:
  555.         LTS_StopProfiled(1);
  556.         break;
  557.           case P1_STOP_3:
  558.         LTS_StopProfiled(2);
  559.         break; 
  560.       case P1_EN:
  561.         LTS_Enable(0);
  562.         break;
  563.           case P1_EN_2:
  564.         LTS_Enable(1);
  565.         break;
  566.           case P1_EN_3:
  567.         LTS_Enable(2);
  568.         break;
  569.           case P1_DIS:
  570.         LTS_Disable(0);
  571.         break;
  572.           case P1_DIS_2:
  573.         LTS_Disable(1);
  574.         break;
  575.           case P1_DIS_3:
  576.         LTS_Disable(2);
  577.         break;
  578.           case P1_TIMER:
  579.                 for (int k=0;k<3;k++){  
  580.           double position = LTS_GetPosition(k);
  581.           SetCtrlVal (p1_h, dpos[k], position);
  582.                   LTS_SetStatus(k);
  583.                 }
  584.         break;
  585.           case P1_SCAN:
  586.                  
  587.                 enabled=1;
  588.                 const int LTS_Enabled = 0x80000000;
  589.                 for (int i=0;i<3;i++) if (!(LTS_GetStatus(i)& LTS_Enabled)) enabled =0;
  590.                 if (enabled){  
  591.                   SetCtrlVal(p1_h,P1_DAQLED, 0);
  592.                   CmtScheduleThreadPoolFunctionAdv (poolHandle, daq, &rID,
  593.                                         DEFAULT_THREAD_PRIORITY,
  594.                                         EndOfThread,
  595.                                         EVENT_TP_THREAD_FUNCTION_END,
  596.                                         NULL, RUN_IN_SCHEDULED_THREAD,
  597.                                         &tfID);
  598.                 } else {
  599.                   MessagePopup ("Error", "Enable LTS Stages First");
  600.                 }        
  601.                 break;
  602.       default:
  603.         break;
  604.     }
  605.     Delay(0.001);
  606.    
  607.   }
  608.  
  609.   GetCtrlVal (p1_h, P1_COMLED, &comled);
  610.   if (comled) for (int i=0;i<3;i++) LTS_Close (i);
  611.  
  612.   return 0;
  613. }
  614.  
  615.  
  616.  
  617.  
  618. int CVICALLBACK TimerCB (int panel, int control, int event,
  619.                                                  void *callbackData, int eventData1, int eventData2)
  620. {
  621.         int isrunning;
  622.         switch (event)
  623.         {
  624.                 case EVENT_TIMER_TICK:
  625.                         GetCtrlVal (p1_h, P1_SCANLED, &isrunning);
  626.                         if (!isrunning) QueueUserEvent (1, p1_h, P1_TIMER);
  627.                         break;
  628.         }
  629.         return 0;
  630. }
  631.  
  632.  
  633. #else
  634. // *************************************
  635.  
  636. int main(int argc, char ** argv)
  637. {
  638.         //Sets up simulations. Comment in if running on physical hardware.
  639.         //TLI_InitializeSimulations();
  640.  
  641.         //Input serial number. Change for your specific device.
  642.         //serials = ["45388004", "45387934","45388034"]
  643.  
  644.  
  645.         //Build Device List and open device.
  646.         TLI_BuildDeviceList();
  647.         TLI_DeviceInfo info;
  648.         int err=0;
  649.         for (int i=0;i<3;i++){
  650.           TLI_GetDeviceInfo(serialNumbers[i], &info);
  651.           printf("%s\n", info.description);
  652.           Sleep(1000);
  653.           err |= LTS_Init(i);
  654.         }  
  655.        
  656.        
  657.         for (int i=0;i<3;i++){
  658.  
  659.                 //Move the stage and wait for the return message before continuing.
  660.                 for (int k=0;k<10;k++){
  661.                   LTS_MoveAbsolute(i,k);
  662.                   printf( "Moving ...\n");
  663.                   waitMove(i);
  664.                   printf( "Move Complete...\n");
  665.                 }
  666.                
  667.          
  668.         }
  669.                
  670.         for (int i=0;i<3;i++){
  671.            LTS_Close(i);
  672.         }
  673.        
  674.         //Closes simulations. Comment if running on physical hardware.
  675.         //TLI_UninitializeSimulations();
  676.         Delay(10);
  677.         return 0;
  678. }
  679. #endif
  680.