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