/**
 * Gets and sets the Acceleration of the Prior stage travels
 */
int XYStage::OnAcceleration(MM::PropertyBase* pProp, MM::ActionType eAct) 
{
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   if (eAct == MM::BeforeGet) 
   {
      // send command
     ret = SendSerialCommand(port_.c_str(), "SRX", "\r"); // LIN 01-01-2012 H128 USES SRX INSTEAD OF SAS
      if (ret != DEVICE_OK)
         return ret;

      // block/wait for acknowledge, or until we time out;
      std::string answer;
      ret = GetSerialAnswer(port_.c_str(), "\r", answer);
      if (ret != DEVICE_OK)
         return ret;

      int acceleration = atoi(answer.c_str());
      if (acceleration < 1 || acceleration > 100) // LIN 01-01-2012 H128 ACCELERATION VALUE MAX 100 NOT 150
         return  ERR_UNRECOGNIZED_ANSWER;

      pProp->Set((long)acceleration);

   } 
   else if (eAct == MM::AfterSet) 
   {
      long acceleration;
      pProp->Get(acceleration);

      std::ostringstream os;
      os << "SRX," <<  acceleration; // LIN 01-01-2012 H128 USES SRX,acceleration INSTEAD OF SAS,acceleration

      // send command
      ret = SendSerialCommand(port_.c_str(), os.str().c_str(), "\r");
      if (ret != DEVICE_OK)
         return ret;

      // block/wait for acknowledge, or until we time out;
      std::string answer;
      ret = GetSerialAnswer(port_.c_str(), "\r", answer);
      if (ret != DEVICE_OK)
         return ret;

      if (answer.substr(0,1).compare("0") == 0)
      {
         return DEVICE_OK; // LIN 01-03-2012 note "0" is the correct response from H128
      }
      else if (answer.substr(0, 1).compare("E") == 0 && answer.length() > 2) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
      {
         int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted, atol converts string to short integer
         return ERR_OFFSET + errNo;
      }
      return ERR_UNRECOGNIZED_ANSWER;

   }

   return DEVICE_OK;
}
//Reports coordinate the stage is at
int ZStage::GetPositionSteps(long& steps)
{
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   const char* command="PZ";

   ret = SendSerialCommand(port_.c_str(), command, "\r");
   if (ret != DEVICE_OK)
      return ret;

   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
   {
      return ret;
   }

   if (answer.length() > 2 && answer.substr(0, 1).compare("E") == 0)
   {
      int errNo = atoi(answer.substr(2).c_str());
      return ERR_OFFSET + errNo;
   }
   else if (answer.length() > 0)
   {
      steps = atol(answer.c_str());
      curSteps_ = steps;
      return DEVICE_OK;
   }

   return ERR_UNRECOGNIZED_ANSWER;
}
int XYStage::SetPositionSteps(long x, long y)
{
   MMThreadGuard guard(lock_);

   // First Clear serial port from previous stuff
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   std::ostringstream command;
   command << "G," << x << "," << y;

   // send command
   ret = SendSerialCommand(port_.c_str(), command.str().c_str(), "\r");
   if (ret != DEVICE_OK)
      return ret;

   // block/wait for acknowledge, or until we time out;
   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0,1).compare("R") == 0)
   {
      return DEVICE_OK; // LIN 01-03-2012 note "R" is the correct response from H128
   }
   else if (answer.substr(0, 1).compare("E") == 0 && answer.length() > 2) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
   {
      int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted, atol converts string to short integer
      return ERR_OFFSET + errNo;
   }

   return ERR_UNRECOGNIZED_ANSWER;   
}
//Moves stage to given absolute z coordinate
int ZStage::SetPositionSteps(long pos)
{
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   std::ostringstream command;
   command << "absz " << pos;

   ret = SendSerialCommand(port_.c_str(), command.str().c_str(), "\r");
   if (ret != DEVICE_OK)
      return ret;

   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0,1).compare("A") == 0)
   {
      curSteps_ = pos;
      return DEVICE_OK;
   }

   return ERR_UNRECOGNIZED_ANSWER;   
}
int ZStage::SetPositionSteps(long pos)
{
   // First Clear serial port from previous stuff
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   long delta = pos - curSteps_;

   // LIN 01-03-2012 ADDED C COMMAND BELOW. H128 USES C TO SET # STEPS THEN DOES U OR D WITHOUT ARGUMENTS
   std::ostringstream command;
   if (delta >= 0)
      command << "C," << delta; 
   else
      command << "C," << -delta;

   // send command
   ret = SendSerialCommand(port_.c_str(), command.str().c_str(), "\r");
   if (ret != DEVICE_OK)
      return ret;

   // block/wait for acknowledge, or until we time out;
   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0, 1).compare("E") == 0 && answer.length() > 2) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
   {
      int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted, atol converts string to short integer
      return ERR_OFFSET + errNo;
   }

   // LIN 01-03-2012 DIRECTLY SEND "U" OR "D" AS APPROPRIATE
   if (delta >= 0)
      ret = SendSerialCommand(port_.c_str(), "U", "\r");
   else
      ret = SendSerialCommand(port_.c_str(), "D", "\r");

   if (ret != DEVICE_OK)
      return ret;

   // block/wait for acknowledge, or until we time out;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0,1).compare("R") == 0)
   {
      curSteps_ = pos;
      return DEVICE_OK;
   }
   else if (answer.substr(0, 1).compare("E") == 0 && answer.length() > 2) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
   {
      int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted, atol converts string to short integer
      return ERR_OFFSET + errNo;
   }

   return ERR_UNRECOGNIZED_ANSWER;   
}
int XYStage::SetOrigin()
// LIN 01-01-2012 H128 USES Z INSTEAD OF PS TO SET ORIGIN AND IT DOES IT FOR ALL 3 AXES
{
   MMThreadGuard guard(lock_);

   // First Clear serial port from previous stuff
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   // send command
   ret = SendSerialCommand(port_.c_str(), "Z", "\r"); // LIN 01-01-2012 CHANGED COMMAND FOR ORIGIN FROM PS TO Z
   if (ret != DEVICE_OK)
      return ret;

   // block/wait for acknowledge, or until we time out;
   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0,1).compare("0") == 0)
   {
      return DEVICE_OK; // LIN 01-03-2012 note "0" is the correct response from H128
   }
   else if (answer.substr(0, 1).compare("E") == 0 && answer.length() > 2) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
   {
      int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted, atol converts string to short integer
      return ERR_OFFSET + errNo;
   }

   return ERR_UNRECOGNIZED_ANSWER; 
}
// XYStage utility functions
int XYStage::GetPositionStepsSingle(char axis, long& steps)
{
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   std::stringstream command;
   command << "P" << axis;

   ret = SendSerialCommand(port_.c_str(), command.str().c_str(), "\r");
   if (ret != DEVICE_OK)
      return ret;

   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
   {
      return ret;
   }

   if (answer.length() > 0)
   {
      steps = atol(answer.c_str());
      return DEVICE_OK;
   }

   return ERR_UNRECOGNIZED_ANSWER;
}
// Checks if stage is busy, returns true if the stage is curently moving false otherwise
// This is effected by XYStage movement
bool ZStage::Busy()
{
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return false; 

   const char* command = "s";

   ret = SendSerialCommand(port_.c_str(), command, "\r");
   if (ret != DEVICE_OK)
      return false;

   std::string answer="";
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return false;
   
   if (answer.length() >=1)
   {
      int status = atoi(answer.substr(0,1).c_str());
      if (status==0) 
         return false;
      else 
         return true;
   }

   return false;
}
//Moves stage relative to current position by given number of steps
int XYStage::SetRelativePositionSteps(long x, long y)
{
   MMThreadGuard guard(lock_);

   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   std::ostringstream command;
   command << "rel " << x << " " << y;

   ret = SendSerialCommand(port_.c_str(), command.str().c_str(), "\r");
   if (ret != DEVICE_OK)
      return ret;

   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0,1).compare("A") == 0)
   {
      return DEVICE_OK;
   }
   return ERR_UNRECOGNIZED_ANSWER;   
}
int LMM5Shutter::SetOpen(bool open)
{
   int state = 0;
   if (open)
      state = state_;
   changedTime_ = GetCurrentMMTime();
   int ret = g_Interface->SetShutterState(*this, *GetCoreCallback(), state);
   if (ret == DEVICE_OK)
      open_ = open;
   return ret;
}
int LMM5Hub::OnExposureConfig(MM::PropertyBase* pProp, MM::ActionType pAct)
{
   std::string exposureConfig;
   if (pAct == MM::BeforeGet)
   {
      int ret = g_Interface->GetExposureConfig(*this, *GetCoreCallback(), exposureConfig);
      if (ret != DEVICE_OK)
         return ret;
      pProp->Set(exposureConfig.c_str());
   }
   else if (pAct == MM::AfterSet)
   {
      pProp->Get(exposureConfig);
      int ret = g_Interface->SetExposureConfig(*this, *GetCoreCallback(), exposureConfig);
      if (ret != DEVICE_OK)
         return ret;
   }

   return DEVICE_OK;
}
int LMM5Hub::OnTransmission(MM::PropertyBase* pProp, MM::ActionType pAct, long line)
{
   double transmission;
   if (pAct == MM::BeforeGet)
   {
      int ret = g_Interface->GetTransmission(*this, *GetCoreCallback(), line, transmission);
      if (ret != DEVICE_OK)
         return ret;
      pProp->Set(transmission);
   }
   else if (pAct == MM::AfterSet)
   {
      pProp->Get(transmission);
      int ret = g_Interface->SetTransmission(*this, *GetCoreCallback(), line, transmission);
      if (ret != DEVICE_OK)
         return ret;
   }

   return DEVICE_OK;
}
Exemple #13
0
void CScionCamera::OnThreadExiting() throw()
{
   try 
   {
      LogMessage(g_Msg_SEQUENCE_ACQUISITION_THREAD_EXITING);
      GetCoreCallback()->AcqFinished(this, 0);
   }
   catch (...) 
   {
      LogMessage(g_Msg_EXCEPTION_IN_ON_THREAD_EXITING, false);
   }
}
int LMM5Hub::OnTriggerOutConfig(MM::PropertyBase* pProp, MM::ActionType pAct)
{
   if (pAct == MM::BeforeGet)
   {
      unsigned char buffer[4];
      int ret = g_Interface->GetTriggerOutConfig(*this, *GetCoreCallback(), buffer);
      if (ret != DEVICE_OK)
         return ret;
      uint16_t config;
      memcpy(&config, buffer, 2);
      config = ntohs(config);
      switch (config) {
         case 256 : pProp->Set("Enable-State"); break;
         case 257 : pProp->Set("Enable-Clock"); break;
         case 0 : pProp->Set("Disable-State"); break;
         case 1 : pProp->Set("Deisable-Clock"); break;
      }
   }
   else if (pAct == MM::AfterSet)
   {
      uint16_t config, time;
      std::string tmp;
      pProp->Get(tmp);
      std::map<std::string, uint16_t>::iterator iter = triggerConfigMap_.find(tmp.c_str());
      if (iter != triggerConfigMap_.end() )
         triggerOutConfig_ = iter->second;
      config = triggerOutConfig_;
      time = triggerOutExposureTime_;
      config = htons(config);
      time = htons(time);
      unsigned char buf[4];
      memcpy(buf, &config, 2);
      memcpy(buf + 2, &time, 2);
      int ret = g_Interface->SetTriggerOutConfig(*this, *GetCoreCallback(), buf);
      if (ret != DEVICE_OK)
         return ret;
   }
   return DEVICE_OK;
}
Exemple #15
0
//Zeros XY position
int XYStage::SetOrigin()
{
   MMThreadGuard guard(lock_);

   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   ret = SendSerialCommand(port_.c_str(), "PX 0", "\r");
   if (ret != DEVICE_OK)
      return ret;

   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
      return ret;

   if (answer.substr(0,1).compare("A") == 0)
   {
		ret = ClearPort(*this, *GetCoreCallback(), port_);
	   if (ret != DEVICE_OK)
		  return ret;

	   ret = SendSerialCommand(port_.c_str(), "PY 0", "\r");
	   if (ret != DEVICE_OK)
		  return ret;

	   std::string answer2;
	   ret = GetSerialAnswer(port_.c_str(), "\r", answer2);
	   if (ret != DEVICE_OK)
		  return ret;

	   if (answer2.substr(0,1).compare("A") == 0)
	   {
		  return DEVICE_OK;
	   }
   }
   return ERR_UNRECOGNIZED_ANSWER; 
}
int PIGCSControllerDLLDevice::Initialize()
{
	if (initialized_)
		return DEVICE_OK;

	char szLabel[MM::MaxStrLength];
	GetLabel(szLabel);
	ctrl_ = new PIGCSControllerDLL(szLabel, this, GetCoreCallback()); 

   int ret = ctrl_->LoadDLL(dllName_);
   if (ret != DEVICE_OK)
   {
      LogMessage(std::string("Cannot load dll ") + dllName_);
      Shutdown();
	  return ret;
   }

   ret = ctrl_->ConnectInterface(interfaceType_, interfaceParameter_);
   if (ret != DEVICE_OK)
   {
	   LogMessage("Cannot connect");
	   Shutdown();
	   return ret;
   }
   initialized_ = true;

   int nrJoysticks = ctrl_->FindNrJoysticks();
	if (nrJoysticks > 0)
	{
		CPropertyAction* pAct = new CPropertyAction (this, &PIGCSControllerDLLDevice::OnJoystick1);
		CreateProperty("Joystick 1", "0" , MM::Integer, false, pAct);
	}
	if (nrJoysticks > 1)
	{
		CPropertyAction* pAct = new CPropertyAction (this, &PIGCSControllerDLLDevice::OnJoystick2);
		CreateProperty("Joystick 2", "0" , MM::Integer, false, pAct);
	}
	if (nrJoysticks > 2)
	{
		CPropertyAction* pAct = new CPropertyAction (this, &PIGCSControllerDLLDevice::OnJoystick3);
		CreateProperty("Joystick 3", "0" , MM::Integer, false, pAct);
	}
	if (nrJoysticks > 3)
	{
		CPropertyAction* pAct = new CPropertyAction (this, &PIGCSControllerDLLDevice::OnJoystick4);
		CreateProperty("Joystick 4", "0" , MM::Integer, false, pAct);
	}


   return ret;
}
int SimpleAutofocus::Initialize()
{
   if(NULL == pPoints_)
   {
      pPoints_ = new SAFData();
   }
   LogMessage("SimpleAutofocus::Initialize()");
   pCore_ = GetCoreCallback();
   CPropertyAction *pAct = new CPropertyAction (this, &SimpleAutofocus::OnExposure);
   CreateProperty(MM::g_Keyword_Exposure, "0.", MM::Float, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnBinning);
   CreateProperty("Binning","0",MM::Integer, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnCoarseStepNumber);
   CreateProperty("CoarseSteps from center","5",MM::Integer, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnStepsizeCoarse);
   CreateProperty("CoarseStepSize","1.0",MM::Float, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnFineStepNumber);
   CreateProperty("FineSteps from center","5",MM::Integer, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnStepSizeFine);
   CreateProperty("FineStepSize","0.3",MM::Float, false, pAct);
   // Set the sharpness threshold
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnThreshold);
   CreateProperty("Threshold","0.1",MM::Float, false, pAct);
   // Set the cropping factor to speed up computation
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnCropFactor);
   CreateProperty("CropFactor","0.2",MM::Float, false, pAct);
   SetPropertyLimits("CropFactor",0.1, 1.0);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnSharpnessScore);
   CreateProperty("SharpnessScore","0.0",MM::Float, true, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnMean);
   CreateProperty("Mean","0",MM::Float, true, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnEnableAutoShutter);
   CreateProperty("EnableAutoshutter","0",MM::Integer, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnRecalculate);
   CreateProperty("Re-acquire&EvaluateSharpness","0",MM::Integer, false, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnStandardDeviationOverMean);
   CreateProperty("StandardDeviation/Mean","0",MM::Float, true, pAct);
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnChannel);
   CreateProperty("Channel","",MM::String, false, pAct);
   AddAllowedValue("Channel","");
   AddAllowedValue("Channel","...");
   selectedChannelConfig_ = "";
   pAct = new CPropertyAction(this, &SimpleAutofocus::OnSearchAlgorithm);
   CreateProperty("SearchAlgorithm","Brent",MM::String, false, pAct);
   AddAllowedValue("SearchAlgorithm","Brent");
   AddAllowedValue("SearchAlgorithm","BruteForce");
   searchAlgorithm_ = "Brent";
   UpdateStatus();
   return DEVICE_OK;
}
int LMM5Hub::OnTriggerOutExposureTime(MM::PropertyBase* pProp, MM::ActionType pAct)
{
   if (pAct == MM::BeforeGet)
   {

      unsigned char buffer[4];
      int ret = g_Interface->GetTriggerOutConfig(*this, *GetCoreCallback(), buffer);
      if (ret != DEVICE_OK)
         return ret;

      uint16_t time;
      memcpy(&time, buffer + 2, 2);
      time = ntohs(time);
      std::ostringstream os;
      os << time;
      printf ("ExposureTime: %s %x\n", os.str().c_str(), time);
      pProp->Set(os.str().c_str());
   } else if (pAct == MM::AfterSet)
   {
      uint16_t config, time;
      std::string tmp;
      pProp->Get(tmp);
      time = (uint16_t) atoi(tmp.c_str());
      triggerOutExposureTime_ = time;
      config = triggerOutConfig_;
      config = htons(config);
      time = htons(time);
      unsigned char buf[4];
      memcpy(buf, &config, 2);
      memcpy(buf + 2, &time, 2);
      int ret = g_Interface->SetTriggerOutConfig(*this, *GetCoreCallback(), buf);
      if (ret != DEVICE_OK)
         return ret;
   }

   return DEVICE_OK;
}
Exemple #19
0
//Gets and sets the Acceleration of the stage travels
int XYStage::OnAcceleration(MM::PropertyBase* pProp, MM::ActionType eAct) 
{
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   if (eAct == MM::BeforeGet) 
   {
      ret = SendSerialCommand(port_.c_str(), "ACC", "\r");
      if (ret != DEVICE_OK)
         return ret;

      std::string answer;
      ret = GetSerialAnswer(port_.c_str(), "\r", answer);
      if (ret != DEVICE_OK)
         return ret;

      int acceleration = atoi(answer.c_str());

      pProp->Set((long)acceleration);

   } 
   else if (eAct == MM::AfterSet) 
   {
      long acceleration;
      pProp->Get(acceleration);

      std::ostringstream os;
      os << "ACC " <<  acceleration;

      ret = SendSerialCommand(port_.c_str(), os.str().c_str(), "\r");
      if (ret != DEVICE_OK)
         return ret;

      std::string answer;
      ret = GetSerialAnswer(port_.c_str(), "\r", answer);
      if (ret != DEVICE_OK)
         return ret;

      if (answer.substr(0,1).compare("A") == 0)
      {
         return DEVICE_OK;
      }
      return ERR_UNRECOGNIZED_ANSWER;

   }

   return DEVICE_OK;
}
int LMM5Shutter::GetOpen(bool& open)
{
   int state;
   int ret = g_Interface->GetShutterState(*this, *GetCoreCallback(), state);
   if (ret != DEVICE_OK)
      return ret;

   // Only return true when all shutters corresponding to our current state are open
   //if ( (state > 0) && (state_ > 0) && (state_ & state) == state_)
   if (state > 0 && ((state_ & state) == state_)) 
      open = true;
   else
      open = false;
   //open_ = open;
  

   return DEVICE_OK;
}
Exemple #21
0
//Sends to corner and sets them postions to 0
int XYStage::Home()
{
   MMThreadGuard guard(lock_);

   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

	// move to corner
   ret = SendSerialCommand(port_.c_str(), "vj 30000 30000 0", "\r");
    if (ret != DEVICE_OK)
      return ret;
	
	std::string answer;
    ret = GetSerialAnswer(port_.c_str(), "\r", answer);
    if (ret != DEVICE_OK)
       return ret;

    if (answer.substr(0,1).compare("A") == 0)
    {
		//set x postion to 0
	    ret = SendSerialCommand(port_.c_str(), "px = 0", "\r");
		if (ret != DEVICE_OK)
		   return ret;

		//set y postion to 0
	    ret = SendSerialCommand(port_.c_str(), "py = 0", "\r");
		if (ret != DEVICE_OK)
		   return ret;

	    std::string answer;
	    ret = GetSerialAnswer(port_.c_str(), "\r", answer);
	    if (ret != DEVICE_OK)
		   return ret;

	    if (answer.substr(0,1).compare("A") == 0)
	    {
		  return DEVICE_OK;
        }
	}
   return ERR_UNRECOGNIZED_ANSWER;
}
int XYStage::GetPositionStepsSingle(char axis, long& steps) 
// LIN 01-01-2012 NOTE this function is called by function GetPositionSteps(long& x, long& y) where long& x is a variable x of type long, passed here by reference with modification rights
{
   // First Clear serial port from previous stuff
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   std::stringstream command;
   command << "P" << axis; //LIN assembles command as either PX or PY depending on whether X or Y is being asked by GetPositionSteps

   // send command
   ret = SendSerialCommand(port_.c_str(), command.str().c_str(), "\r");
   if (ret != DEVICE_OK)
      return ret;

   // block/wait for acknowledge, or until we time out;
   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
   {
      return ret;
   }

   if (answer.length() > 2 && answer.substr(0, 1).compare("E") == 0) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
   {
      int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted, atol converts string to short integer
      return ERR_OFFSET + errNo;
   }
   else if (answer.length() > 0)
   {
      steps = atol(answer.c_str()); // LIN 01-03-2012 this is where x or y is updated, atol converts string to long integer
      return DEVICE_OK;
   }

   return ERR_UNRECOGNIZED_ANSWER;
}
int ZStage::GetPositionSteps(long& steps)
{
   // First Clear serial port from previous stuff
   int ret = ClearPort(*this, *GetCoreCallback(), port_);
   if (ret != DEVICE_OK)
      return ret;

   const char* command="PZ"; // LIN 01-03-2012 SAME COMMAND FOR H128 AS NEWER CONTROLLERS

   // send command
   ret = SendSerialCommand(port_.c_str(), command, "\r");
   if (ret != DEVICE_OK)
      return ret;

   // block/wait for acknowledge, or until we time out;
   std::string answer;
   ret = GetSerialAnswer(port_.c_str(), "\r", answer);
   if (ret != DEVICE_OK)
   {
      // failed reading the port
      return ret;
   }

   if (answer.length() > 2 && answer.substr(0, 1).compare("E") == 0) // LIN 01-03-2012 note I don't think the H128 reports E## errors but we can leave this in
   {
      int errNo = atoi(answer.substr(2).c_str()); // LIN 01-03-2012 note here the error number is extracted
      return ERR_OFFSET + errNo;
   }
   else if (answer.length() > 0)
   {
      steps = atol(answer.c_str());
      curSteps_ = steps; // LIN 01-03-2012 note curSteps was passed to this function by reference and here gets modified to the reported steps number
      return DEVICE_OK;
   }

   return ERR_UNRECOGNIZED_ANSWER;
}
int CArduinoNeoPixelHub::Initialize()
{
   // Name
   int ret = CreateProperty(MM::g_Keyword_Name, g_DeviceNameArduinoNeoPixelHub, MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

   // The first second or so after opening the serial port, the Arduino is waiting for firmwareupgrades.  Simply sleep 1 second.
   CDeviceUtils::SleepMs(2000);

   MMThreadGuard myLock(lock_);

   // Check that we have a controller:
   PurgeComPort(port_.c_str());
   ret = GetControllerVersion(version_);
   if( DEVICE_OK != ret)
      return ret;

   // if (version_ < g_Min_MMVersion || version_ > g_Max_MMVersion)
   //    return ERR_VERSION_MISMATCH;

   CPropertyAction* pAct = new CPropertyAction(this, &CArduinoNeoPixelHub::OnVersion);
   std::ostringstream sversion;
   sversion << version_;
   CreateProperty(g_versionProp, sversion.str().c_str(), MM::Integer, true, pAct);

   ret = UpdateStatus();
   if (ret != DEVICE_OK)
      return ret;

   // turn on verbose serial debug messages
   GetCoreCallback()->SetDeviceProperty(port_.c_str(), "Verbose", "1");

   initialized_ = true;
   return DEVICE_OK;
}
MM::DeviceDetectionStatus CArduinoNeoPixelHub::DetectDevice(void)
{
   if (initialized_)
      return MM::CanCommunicate;

   // all conditions must be satisfied...
   MM::DeviceDetectionStatus result = MM::Misconfigured;
   char answerTO[MM::MaxStrLength];
   
   try
   {
      std::string portLowerCase = port_;
      for( std::string::iterator its = portLowerCase.begin(); its != portLowerCase.end(); ++its)
      {
         *its = (char)tolower(*its);
      }
      if( 0< portLowerCase.length() &&  0 != portLowerCase.compare("undefined")  && 0 != portLowerCase.compare("unknown") )
      {
         result = MM::CanNotCommunicate;
         // record the default answer time out
         GetCoreCallback()->GetDeviceProperty(port_.c_str(), "AnswerTimeout", answerTO);

         // device specific default communication parameters
         // for Arduino Duemilanova
         GetCoreCallback()->SetDeviceProperty(port_.c_str(), MM::g_Keyword_Handshaking, "Off");
         GetCoreCallback()->SetDeviceProperty(port_.c_str(), MM::g_Keyword_BaudRate, "9600" );
         GetCoreCallback()->SetDeviceProperty(port_.c_str(), MM::g_Keyword_StopBits, "1");
         // Arduino timed out in GetControllerVersion even if AnswerTimeout  = 300 ms
         GetCoreCallback()->SetDeviceProperty(port_.c_str(), "AnswerTimeout", "1000.0");
         GetCoreCallback()->SetDeviceProperty(port_.c_str(), "DelayBetweenCharsMs", "0");
         MM::Device* pS = GetCoreCallback()->GetDevice(this, port_.c_str());
         pS->Initialize();
         // The first second or so after opening the serial port, the Arduino is waiting for firmwareupgrades.  Simply sleep 2 seconds.
         CDeviceUtils::SleepMs(2000);
         MMThreadGuard myLock(lock_);
         PurgeComPort(port_.c_str());
         int v = 0;
         int ret = GetControllerVersion(v);
         // later, Initialize will explicitly check the version #
         if( DEVICE_OK != ret )
         {
            LogMessageCode(ret,true);
         }
         else
         {
            // to succeed must reach here....
            result = MM::CanCommunicate;
         }
         pS->Shutdown();
         // always restore the AnswerTimeout to the default
         GetCoreCallback()->SetDeviceProperty(port_.c_str(), "AnswerTimeout", answerTO);

      }
   }
   catch(...)
   {
      LogMessage("Exception in DetectDevice!",false);
   }

   return result;
}
int LMM5Shutter::Initialize()
{
   if (g_Interface == NULL)
      return DEVICE_NOT_CONNECTED;

   // Name                                                                   
   CreateProperty(MM::g_Keyword_Name, name_.c_str(), MM::String, true);      
                                                                             
   // Description                                                            
   CreateProperty(MM::g_Keyword_Description, "Spectral LMM5 Shutter", MM::String, true);

   int ret = g_Interface->DetectLaserLines(*this, *GetCoreCallback()); 
   nrLines_= g_Interface->GetNrLines();
   if (ret != DEVICE_OK)
      return ret;

   availableLines* lines = g_Interface->getAvailableLaserLines();
   unsigned long lineMask = 0;
   for (int i=0; i < nrLines_; i++) 
      if (lines[i].present) 
         lineMask = lineMask | (1 << i);
   
   
   // outputs are available only since firmware 1.30.  Our interface will always return 1 for firmware that is older
   ret = g_Interface->GetNumberOfOutputs(*this, *GetCoreCallback(), nrOutputs_);
   if (nrOutputs_ > 1) 
   {
      CPropertyAction *pAct = new CPropertyAction(this, &LMM5Shutter::OnOutputSelect);
      CreateProperty("FiberOutput", "0", MM::Integer, false, pAct);
      for (int i = 0; i < nrOutputs_; i++) {
         std::ostringstream os;
         os << i;
         AddAllowedValue("FiberOutput", os.str().c_str());
      }
   }

   // We roll our own implementation of State and Label here (since we are a Shutter device, not a State Device
   // State
   CPropertyAction* pAct = new CPropertyAction(this, &LMM5Shutter::OnState);
   ret = CreateProperty(MM::g_Keyword_State, "0", MM::Integer, false, pAct);
   if (ret != DEVICE_OK)
      return ret;
   for (unsigned long i=0; i<=lineMask; i++)
   {
      if ((i & lineMask) == i)
      {
         std::stringstream tmp;
         tmp << i;
         AddAllowedValue(MM::g_Keyword_State, tmp.str().c_str());
      }
   }

   // Label
   pAct = new CPropertyAction(this, &LMM5Shutter::OnLabel);
   ret = CreateProperty(MM::g_Keyword_Label, "", MM::String, false, pAct);
   if (ret != DEVICE_OK)
      return ret;

   for (unsigned long i=0; i<=lineMask; i++)
   {
      if ((i & lineMask) == i)
      {
         std::string label = StateToLabel(i);;
         AddAllowedValue(MM::g_Keyword_Label, label.c_str());
      }
   }

   for (long i=0; i < nrLines_; i++) 
   {
      if (lines[i].present) 
      {
         if (lines[i].waveLength >= 100 || nrOutputs_ == 1)
         {
            CPropertyActionEx *pActEx = new CPropertyActionEx(this, &LMM5Shutter::OnStateEx, i);
            CreateProperty(lines[i].name.c_str(), "0", MM::Integer, false, pActEx);
            SetPropertyLimits(lines[i].name.c_str(), 0, 1);
         }
      }
   }

   changedTime_ = GetCurrentMMTime();
 
   ret = UpdateStatus();
   if (ret != DEVICE_OK)
      return ret;

   return DEVICE_OK;
}
int LMM5Hub::Initialize()
{
   if (g_Interface == NULL)
      return DEVICE_NOT_CONNECTED;

   int ret = g_Interface->DetectLaserLines(*this, *GetCoreCallback());
   nrLines_= g_Interface->GetNrLines();
   if (ret != DEVICE_OK)
      return ret;

   // Name
   ret = CreateProperty(MM::g_Keyword_Name, g_DeviceNameLMM5Hub, MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

   // Firmware version
   std::string version;
   ret = g_Interface->GetFirmwareVersion(*this, *GetCoreCallback(), version);
   if (ret != DEVICE_OK)
      return ret;
   ret = CreateStringProperty("Firmware Version", version.c_str(), true);
   if (ret != DEVICE_OK)
      return ret;

   // Does this controller support FLICR (i.e PWM)?
   ret = g_Interface->GetFLICRAvailable(*this, *GetCoreCallback(), flicrAvailable_);
   if (ret != DEVICE_OK)
      return ret;
   std::string msg = "This controller does not support FLICR";
   if (flicrAvailable_) 
   {
      msg = "This controller supports FLICR";
   }
   LogMessage(msg.c_str());

   // For each laser line, create transmission properties 
   availableLines* lines = g_Interface->getAvailableLaserLines();
   for (int i=0; i < nrLines_; i++) 
   {
      if (lines[i].present) 
      {
			if (lines[i].waveLength >= 100) 
			{
			   CPropertyActionEx *pEx = new CPropertyActionEx(this, &LMM5Hub::OnTransmission, (long) i);
			   std::ostringstream propName;
			   propName << "Transmission (%) " << lines[i].name; 
			   ret = CreateProperty(propName.str().c_str(), "100.0", MM::Float, false, pEx);
			   if (ret != DEVICE_OK)
				   return ret;
			   SetPropertyLimits(propName.str().c_str(), 0.0, 100.0);
			}
         if (flicrAvailable_) 
         {
            // check if this line has flicr available
            ret = g_Interface->GetFLICRAvailableByLine(*this, *GetCoreCallback(), i, lines[i].flicrAvailable);
            if (ret != DEVICE_OK)
               return ret;
            if (lines[i].flicrAvailable) 
            {
               // check for maximum FLICR value
               ret = g_Interface->GetMaxFLICRValue(*this, *GetCoreCallback(), i, lines[i].maxFLICR);
               if (ret != DEVICE_OK)
                  return ret;
               std::ostringstream os;
               os << "Max FLICR for line " << i << " is: " << lines[i].maxFLICR;
               LogMessage(os.str().c_str());
               // ad FLICR/PWM property
               CPropertyActionEx *pEx = new CPropertyActionEx(this, &LMM5Hub::OnFlicr, (long) i);
               std::ostringstream fPropName;
               fPropName << "PWM (%) " << lines[i].name;
               ret = CreateProperty(fPropName.str().c_str(), "1.0", MM::String, false, pEx);
               if (ret != DEVICE_OK)
                  return ret;
               // populate with presets
               uint16_t val = 1;
               while (val <= lines[i].maxFLICR) 
               {
                  std::string valStr;
                  IntToPerc(val, valStr);
                  AddAllowedValue(fPropName.str().c_str(), valStr.c_str());
                  val = val * 10;
               }
            }
         }
      }
   }
   
   
   // Exposure Configuration
   /*
   pAct = new CPropertyAction(this, &LMM5Hub::OnExposureConfig);
   CreateProperty("ExposureConfig", "", MM::String, false, pAct);
   */

   // Some versions of the firmware, when trigger-out is unavailable, fail to
   // respond correctly when querying the trigger-out config. Only provide the
   // trigger-out properties when it appears to be working.
   unsigned char dummy[5];
   ret = g_Interface->GetTriggerOutConfig(*this, *GetCoreCallback(), dummy);
   if (ret == DEVICE_OK) {
      // Trigger configuration
      CPropertyAction *pAct = new CPropertyAction(this, &LMM5Hub::OnTriggerOutConfig);
      CreateProperty("TriggerOutConfig", "", MM::String, false, pAct);
      std::vector<std::string> triggerConfigs;
      triggerConfigs.push_back("Enable-State");
      triggerConfigMap_["Enable-State"] = 256;
      triggerConfigs.push_back("Enable-Clock");
      triggerConfigMap_["Enable-Clock"] = 257;
      triggerConfigs.push_back("Disable-State");
      triggerConfigMap_["Disable-State"] = 0;
      triggerConfigs.push_back("Disable-Clock");
      triggerConfigMap_["Disable-Clock"] = 1;
      SetAllowedValues("TriggerOutConfig", triggerConfigs);

      // Trigger Exposure Time
      pAct = new CPropertyAction(this, &LMM5Hub::OnTriggerOutExposureTime);
      CreateProperty("TriggerExpTime(0.1ms)", "", MM::Integer, false, pAct);
   }

   ret = UpdateStatus();
   if (DEVICE_OK != ret)
      return ret;

   initialized_ = true;
   return DEVICE_OK;
}