Created
May 9, 2013 14:39
-
-
Save clarle/5547861 to your computer and use it in GitHub Desktop.
Standa device adapter for Micro-Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////////////////////////////////////////////// | |
// FILE: Standa.cpp | |
// PROJECT: Micro-Manager | |
// SUBSYSTEM: DeviceAdapters | |
//----------------------------------------------------------------------------- | |
// DESCRIPTION: Standa device adapters: 8SMC1-USBhF Microstep Driver | |
// | |
// COPYRIGHT: Leslie Lab, McGill University, Montreal, 2013 | |
// | |
// LICENSE: This file is distributed under the BSD license. | |
// | |
// This file is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty | |
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
// | |
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES. | |
// | |
// AUTHOR: Clarence Leung, clarence.leung@mail.mcgill.ca, 2013 | |
// | |
#ifdef WIN32 | |
#include <windows.h> | |
#define snprintf _snprintf | |
#endif | |
#include "Standa.h" | |
#include <cstdio> | |
#include <string> | |
const char* StandaZStage::DeviceName_ = "ZStage"; | |
const char* g_Standa_ZStageAxisLimitUm = "Limit_um"; | |
const char* g_Standa_ZStageSerialNumber = "Serial Number"; | |
USMC_Devices deviceList; | |
/////////////////////////////////////////////////////////////////////////////// | |
// Exported MMDevice API | |
/////////////////////////////////////////////////////////////////////////////// | |
MODULE_API void InitializeModuleData() | |
{ | |
AddAvailableDeviceName(StandaZStage::DeviceName_, "Standa Z Stage"); | |
} | |
MODULE_API MM::Device* CreateDevice(const char* deviceName) | |
{ | |
if (deviceName == 0) | |
return 0; | |
if (strcmp(deviceName, StandaZStage::DeviceName_) == 0) | |
{ | |
StandaZStage* s = new StandaZStage(); | |
return s; | |
} | |
return 0; | |
} | |
MODULE_API void DeleteDevice(MM::Device* pDevice) | |
{ | |
delete pDevice; | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
/////////////////////////////////////////////////////////////////////////////// | |
// ZStage | |
StandaZStage::StandaZStage() : | |
initialized_(false), | |
stepSizeUm_(0.001), | |
axisLimitUm_(500.0), | |
stepDivisor_(8), | |
stageSpeed_(2000.0), | |
serialNumber_(""), | |
deviceNumber_(NULL) | |
{ | |
InitializeDefaultErrorMessages(); | |
// create pre-initialization properties | |
// ------------------------------------ | |
// Name | |
CreateProperty(MM::g_Keyword_Name, StandaZStage::DeviceName_, MM::String, true); | |
// Description | |
CreateProperty(MM::g_Keyword_Description, "Standa Z-stage driver adapter", MM::String, true); | |
CPropertyAction* pAct; | |
// Serial Number | |
pAct = new CPropertyAction (this, &StandaZStage::OnSerialNumber); | |
CreateProperty(g_Standa_ZStageSerialNumber, "Undefined", MM::String, false, pAct, true); | |
// Axis Limit in um | |
pAct = new CPropertyAction (this, &StandaZStage::OnAxisLimit); | |
CreateProperty(g_Standa_ZStageAxisLimitUm, "500.0", MM::Float, false, pAct, true); | |
} | |
StandaZStage::~StandaZStage() | |
{ | |
Shutdown(); | |
} | |
void StandaZStage::GetName(char* Name) const | |
{ | |
CDeviceUtils::CopyLimitedString(Name, StandaZStage::DeviceName_); | |
} | |
bool StandaZStage::Busy() | |
{ | |
return false; | |
} | |
int StandaZStage::Initialize() | |
{ | |
// Initialize the list of devices to search for the stage | |
if (USMC_Init(deviceList)) | |
return DEVICE_ERR; | |
// Iterate through the list of devices and find the one matching our serial number | |
for (DWORD i = 0; i < deviceList.NOD; i++) { | |
if (strcmp(deviceList.Serial[i], serialNumber_.c_str()) == 0) { | |
deviceNumber_ = i; | |
} | |
} | |
// If device not found, fail fast | |
if (deviceNumber_ == NULL) | |
return DEVICE_INVALID_PROPERTY_TYPE; | |
// Attempt to get the current state of the device | |
if (USMC_GetState(deviceNumber_, currentState_)) | |
return DEVICE_ERR; | |
// Attempt to get the current position, in steps | |
int ret = GetPositionSteps(curSteps_); | |
if (ret != DEVICE_OK) | |
return ret; | |
initialized_ = true; | |
return DEVICE_OK; | |
} | |
int StandaZStage::Shutdown() | |
{ | |
if (initialized_) | |
{ | |
initialized_ = false; | |
} | |
return DEVICE_OK; | |
} | |
int StandaZStage::GetPositionUm(double &pos) | |
{ | |
long steps; | |
int ret = GetPositionSteps(steps); | |
if (ret != DEVICE_OK) | |
return ret; | |
pos = steps * stepSizeUm_; | |
return DEVICE_OK; | |
} | |
int StandaZStage::SetPositionUm(double pos) | |
{ | |
long steps = (long) (pos / stepSizeUm_ + 0.5); | |
return SetPositionSteps(steps); | |
} | |
int StandaZStage::GetPositionSteps(long& steps) { | |
if (USMC_GetState(deviceNumber_, currentState_)) | |
return DEVICE_ERR; | |
steps = (long) currentState_.CurPos; | |
return DEVICE_OK; | |
} | |
int StandaZStage::SetPositionSteps(long steps) | |
{ | |
// Get the initial starting parameters | |
if (USMC_GetStartParameters(deviceNumber_, startParameters_)) | |
return DEVICE_ERR; | |
// Set the step divisor to our desired step divisor | |
startParameters_.SDivisor = stepDivisor_; | |
// Start the movement of the stepper motor | |
if (USMC_Start(deviceNumber_, (int) steps, stageSpeed_, startParameters_)) | |
return DEVICE_ERR; | |
return DEVICE_OK; | |
} | |
int StandaZStage::SetOrigin() | |
{ | |
return DEVICE_UNSUPPORTED_COMMAND; | |
} | |
int StandaZStage::GetLimits(double& min, double& max) | |
{ | |
min = 0; | |
max = axisLimitUm_; | |
return DEVICE_OK; | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
// Action handlers | |
/////////////////////////////////////////////////////////////////////////////// | |
int StandaZStage::OnAxisLimit(MM::PropertyBase *pProp, MM::ActionType eAct) | |
{ | |
if (eAct == MM::BeforeGet) | |
{ | |
pProp->Set(axisLimitUm_); | |
SetPropertyLimits(MM::g_Keyword_Position, 0, axisLimitUm_); | |
} | |
else if (eAct == MM::AfterSet) | |
{ | |
pProp->Get(axisLimitUm_); | |
} | |
return DEVICE_OK; | |
} | |
int StandaZStage::OnSerialNumber(MM::PropertyBase *pProp, MM::ActionType eAct) | |
{ | |
if (eAct == MM::BeforeGet) | |
{ | |
pProp->Set(serialNumber_.c_str()); | |
} | |
else if (eAct == MM::AfterSet) | |
{ | |
pProp->Get(serialNumber_); | |
} | |
return DEVICE_OK; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////////////////////////////////////////////// | |
// FILE: Standa.h | |
// PROJECT: Micro-Manager | |
// SUBSYSTEM: DeviceAdapters | |
//----------------------------------------------------------------------------- | |
// DESCRIPTION: Standa device adapters: 8SMC1-USBhF Microstep Driver | |
// | |
// COPYRIGHT: Leslie Lab, McGill University, Montreal, 2013 | |
// | |
// LICENSE: This file is distributed under the BSD license. | |
// | |
// This file is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty | |
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
// | |
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES. | |
// | |
// AUTHOR: Clarence Leung, clarence.leung@mail.mcgill.ca, 2013 | |
// | |
#ifndef _STANDA_H_ | |
#define _STANDA_H_ | |
// Standa headers | |
#include "../../../3rdparty/Standa/USMCDLL.h" | |
// MM headers | |
#include "../../MMDevice/MMDevice.h" | |
#include "../../MMDevice/DeviceBase.h" | |
#include "../../MMDevice/ModuleInterface.h" | |
////////////////////////////////////////////////////////////////////////////// | |
// StandaZStage class | |
// (device adapter) | |
////////////////////////////////////////////////////////////////////////////// | |
class StandaZStage : public CStageBase<StandaZStage> | |
{ | |
public: | |
StandaZStage(); | |
~StandaZStage(); | |
// Device API | |
// ---------- | |
int Initialize(); | |
int Shutdown(); | |
static const char* DeviceName_; | |
void GetName(char* pszName) const; | |
bool Busy(); | |
// Stage API | |
// --------- | |
int SetPositionUm(double pos); | |
int GetPositionUm(double& pos); | |
int SetPositionSteps(long steps); | |
int GetPositionSteps(long& steps); | |
int SetOrigin(); | |
int GetLimits(double& min, double& max); | |
int IsStageSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} | |
bool IsContinuousFocusDrive() const {return false;} | |
// action interface | |
// ---------------- | |
int OnAxisLimit(MM::PropertyBase* pProp, MM::ActionType eAct); | |
int OnSerialNumber(MM::PropertyBase* pProp, MM::ActionType eAct); | |
private: | |
bool initialized_; | |
long curSteps_; | |
double stepSizeUm_; | |
double axisLimitUm_; | |
int stepDivisor_; | |
float stageSpeed_; | |
std::string serialNumber_; | |
DWORD deviceNumber_; | |
USMC_State currentState_; | |
USMC_StartParameters startParameters_; | |
}; | |
#endif //_STANDA_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment