Subversion Repositories f9daq

Rev

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