bool XYStage::Busy() { // TODO: figure out how to get a busy signal on MF firmware if (firmware_ == "MF") return false; const char * commandX = "NPXm1"; const char * commandY = "NPYm1"; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), commandX); if (ret != DEVICE_OK) { this->LogMessage("ExecuteCommand failed in XYStage::Busy"); return false; // error, so say we're not busy } // first two chars should read 'PN' string response; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) { this->LogMessage("GetAnswer failed in XYStage::Busy"); return false; // error, so say we're not busy } // Note: if the controller reports that the motors are moving or settling, we'll consider the z-drive to be busy if (response.substr(0,2) == "PN") { unsigned long status = strtol(response.substr(2,1).c_str(), NULL, 16); status &= 0x01; if (status != 0) return true; } // Repeat for Y ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), commandY); if (ret != DEVICE_OK) { this->LogMessage("ExecuteCommand failed in XYStage::Busy"); return false; // error, so say we're not busy } // first two chars should read 'PN' ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) { this->LogMessage("GetAnswer failed in XYStage::Busy"); return false; // error, so say we're not busy } // Note: if the controller reports that the motors are moving or settling, we'll consider the z-drive to be busy if (response.substr(0,2) == "PN") { unsigned long status = strtol(response.substr(2,1).c_str(), NULL, 16); status &= 0x01; if (status != 0) return true; } return false; }
int XYStage::SetPositionSteps(long stepsX, long stepsY) { // the hard part is to get the formatting of the string right. // it is a hex number from 800000 .. 7FFFFF, where everything larger than 800000 is a negative number!? // We can speed up communication by skipping leading 0s, but that makes the following more complicated: char tmp[98]; // convert the steps into a twos-complement 6bit number if (stepsX < 0) stepsX = stepsX + 0xffffff + 1; snprintf(tmp, 9, "%08lX", stepsX); string tmp2 = tmp; ostringstream cmdX; cmdX << "NPXT" << tmp2.substr(2,6).c_str(); int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmdX.str().c_str()); if (ret != DEVICE_OK) return ret; // do the same for YAxis if (stepsY < 0) stepsY = stepsY + 0xffffff + 1; snprintf(tmp, 9, "%08lX", stepsY); tmp2 = tmp; ostringstream cmdY; cmdY << "NPYT" << tmp2.substr(2,6).c_str(); ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmdY.str().c_str()); if (ret != DEVICE_OK) return ret; return DEVICE_OK; }
/* * Requests current z postion from the controller. This function does the actual communication */ int ZStage::GetPositionSteps(long& steps) { const char* cmd ="HPZp" ; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd); if (ret != DEVICE_OK) return ret; string response; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) return ret; if (response.substr(0,2) == "PH") { steps = strtol(response.substr(2).c_str(), NULL, 16); } else return ERR_UNEXPECTED_ANSWER; // To 'translate' 'negative' numbers according to the Zeiss schema (there must be a more elegant way of doing this: long sign = strtol(response.substr(2,1).c_str(), NULL, 16); if (sign > 7) // negative numbers { steps = steps - 0xFFFFFF - 1; } return DEVICE_OK; }
/* * Requests current z postion from the controller. This function does the actual communication */ int XYStage::GetPositionSteps(long& stepsX, long& stepsY) { const char* cmdX ="NPXp" ; const char* cmdY ="NPYp" ; // retrieve x axis int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmdX); if (ret != DEVICE_OK) return ret; string response; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) return ret; if (response.substr(0,2) == "PN") { stepsX = strtol(response.substr(2).c_str(), NULL, 16); } else return ERR_UNEXPECTED_ANSWER; // To 'translate' 'negative' numbers according to the Zeiss schema (there must be a more elegant way of doing this: long sign = strtol(response.substr(2,1).c_str(), NULL, 16); if (sign > 7) // negative numbers { stepsX = stepsX - 0xFFFFFF - 1; } // retrieve y axis ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmdY); if (ret != DEVICE_OK) return ret; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) return ret; if (response.substr(0,2) == "PN") { stepsY = strtol(response.substr(2).c_str(), NULL, 16); } else return ERR_UNEXPECTED_ANSWER; // To 'translate' 'negative' numbers according to the Zeiss schema (there must be a more elegant way of doing this: sign = strtol(response.substr(2,1).c_str(), NULL, 16); if (sign > 7) // negative numbers { stepsY = stepsY - 0xFFFFFF - 1; } return DEVICE_OK; }
int XYStage::Stop() { const char* cmdX ="NPXS" ; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmdX); if (ret != DEVICE_OK) return ret; const char* cmdY ="NPYS" ; ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmdY); if (ret != DEVICE_OK) return ret; return DEVICE_OK; }
int ZStage::SetOrigin() { const char* cmd ="HPZP0" ; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd); if (ret != DEVICE_OK) return ret; return DEVICE_OK; }
/* * Set stage in load sample mode */ int ZStage::OnLoadSample(MM::PropertyBase* pProp, MM::ActionType eAct) { //1: up //0: down. but can also return 4. if (eAct == MM::BeforeGet) { const char* cmd = "HPZw"; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd); if (ret != DEVICE_OK) return ret; string response; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) return ret; if (response.substr(0,2) == "PH") { long state = strtol(response.substr(2).c_str(), NULL, 10); state=state==0 || state==4; pProp->Set(state); } else return ERR_UNEXPECTED_ANSWER; return DEVICE_OK; } else if (eAct == MM::AfterSet) { long state; pProp->Get(state); ostringstream cmd; cmd << "HPZW" << (!state); int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd.str().c_str()); if (ret != DEVICE_OK) return ret; return DEVICE_OK; } return DEVICE_OK; }
int PhotoModule::SetUpperPrism(int position) { ostringstream cmd; cmd << "EPPO" << position; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd.str().c_str()); if (ret != DEVICE_OK) return ret; return DEVICE_OK; }
int PhotoModule::GetTurretPosition(int& /* position */) { string cmd = "EPPo"; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd.c_str()); if (ret != DEVICE_OK) return ret; string answer; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), answer); if (ret != DEVICE_OK) return ret; // I have no idea how the answer will be formatted. For now, just log: ostringstream log; log << "Answer from scope: " << answer; this->LogMessage(log.str().c_str()); return DEVICE_OK; }
// TODO: this doesn't work for MCU28 int XYStage::GetXYFirmwareVersion() { // get firmware info const char * command = "NPTv0"; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), command); if (ret != DEVICE_OK) return ret; // first two chars should read 'PN' string response; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) return ret; if (response.substr(0,2).compare("PN") == 0) { xyFirmware_ = response.substr(2); firmware_ = response.substr(2,2); } return DEVICE_OK; }
int ZStage::GetLowerLimit() { const char* cmd = "HPZl"; int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd); if (ret != DEVICE_OK) return ret; string response; ret = g_hub.GetAnswer(*this, *GetCoreCallback(), response); if (ret != DEVICE_OK) return ret; if (response.substr(0,2) == "PH") { long steps = strtol(response.substr(2).c_str(), NULL, 16); lowerLimit_ = steps * stepSize_um_; } else return ERR_UNEXPECTED_ANSWER; return DEVICE_OK; }
/* * Requests movement to new z postion from the controller. This function does the actual communication */ int ZStage::SetPositionSteps(long steps) { // the hard part is to get the formatting of the string right. // it is a hex number from 800000 .. 7FFFFF, where everything larger than 800000 is a negative number!? // We can speed up communication by skipping leading 0s, but that makes the following more complicated: char tmp[98]; // convert the steps into a twos-complement 6bit number if (steps<0) steps = steps+0xffffff+1; snprintf(tmp, 9, "%08lX", steps); string tmp2 = tmp; ostringstream cmd; cmd << "HPZT" << tmp2.substr(2,6).c_str(); int ret = g_hub.ExecuteCommand(*this, *GetCoreCallback(), cmd.str().c_str()); if (ret != DEVICE_OK) return ret; CDeviceUtils::SleepMs(100); return DEVICE_OK; }