/* * The Spectral LMM5 has a silly difference between USB and serial communication: * Commands can be sent straight to USB. Commands to the serial port need to converted in some kind of weird ASCI: The command "0x1A0xFF0x000x12<CR>" becomes "1AFF0012<CR>". Presumably, the same weird conversion takes place on the way back. We handle this translation in this function */ int SpectralLMM5Interface::ExecuteCommand(MM::Device& device, MM::Core& core, unsigned char* buf, unsigned long bufLen, unsigned char* answer, unsigned long answerLen, unsigned long& read) { int ret; if (portType_ == MM::SerialPort) { std::string serialCommand; char tmp[3]; tmp[2] = 0; for (unsigned long i=0; i<bufLen; i++) { sprintf(tmp, "%.2x", buf[i]); serialCommand += tmp; } ret = core.SetSerialCommand(&device, port_.c_str(), serialCommand.c_str(), "\r"); } else // check for USB port { unsigned char c[2]; c[0]=0x01; c[1]=0x02; ret = core.WriteToSerial(&device, port_.c_str(), c, 2); //ret = core.WriteToSerial(&device, port_.c_str(), buf, bufLen); } if (ret != DEVICE_OK) return ret; if (portType_ == MM::SerialPort) { char strAnswer[128]; read = 0; ret = core.GetSerialAnswer(&device, port_.c_str(), 128, strAnswer, "\r"); if (ret != DEVICE_OK) return ret; std::ostringstream os; os << "LMM5 answered: " << strAnswer << " Port status: " << ret; core.LogMessage(&device, os.str().c_str(), true); // 'translate' back into numbers: std::string tmp = strAnswer; for (unsigned int i=0; i < tmp.length()/2; i++) { char * end; long j = strtol(tmp.substr(i*2,2).c_str(), &end, 16); answer[i] = (unsigned char) j; // printf("c:%x i:%u j:%ld\n", answer[i], i, j); read++; } } else // TODO: check that we have a USB port { // The USB port will attempt to read up to answerLen characters ret = core.ReadFromSerial(&device, port_.c_str(), answer, answerLen, read); if (ret != DEVICE_OK) return ret; std::ostringstream os; os << "LMM5 answered: "; for (unsigned int i=0; i < read; i++) os << std::hex << answer[i]; os << std::endl; core.LogMessage(&device, os.str().c_str(), true); } return DEVICE_OK; }
// // General utility function // int ClearPort(MM::Device& device, MM::Core& core, const char* sPort) { // Clear contents of serial port const int nBufSize = 255; unsigned char sClear[nBufSize]; unsigned long lRead = nBufSize; int ret; // reset the communication port buffer while ((int) lRead == nBufSize) { // reading from the serial port ret = core.ReadFromSerial(&device, sPort, sClear, nBufSize, lRead); std::ostringstream sMessage; sMessage << "<nPC400::ClearPort> port = (" << sPort << ") :: clearBuffer(" << lRead << ") = (" << sClear << ")"; core.LogMessage(&device, sMessage.str().c_str(), false); // verify the read operation if (ret != DEVICE_OK) return ret; } // upon successful restting the port return DEVICE_OK; }
/* * The Spectral LMM5 has a silly difference between USB and serial communication: * Commands can be sent straight to USB. Commands to the serial port need to converted in some kind of weird ASCI: The command "0x1A0xFF0x000x12<CR>" becomes "1AFF0012<CR>". Presumably, the same weird conversion takes place on the way back. We handle this translation in this function */ int SpectralLMM5Interface::ExecuteCommand(MM::Device& device, MM::Core& core, unsigned char* buf, unsigned long bufLen, unsigned char* answer, unsigned long answerLen, unsigned long& read) { int ret; if (portType_ == MM::SerialPort) { std::string serialCommand; char tmp[3]; tmp[2] = 0; for (unsigned long i=0; i<bufLen; i++) { sprintf(tmp, "%.2x", buf[i]); serialCommand += tmp; } ret = core.SetSerialCommand(&device, port_.c_str(), serialCommand.c_str(), "\r"); } else // check for USB port { ret = core.WriteToSerial(&device, port_.c_str(), buf, bufLen); } if (ret != DEVICE_OK) return ret; if (portType_ == MM::SerialPort) { char strAnswer[128]; read = 0; ret = core.GetSerialAnswer(&device, port_.c_str(), 128, strAnswer, "\r"); if (ret != DEVICE_OK) return ret; std::ostringstream os; os << "LMM5 answered: " << strAnswer << " Port status: " << ret; core.LogMessage(&device, os.str().c_str(), true); // 'translate' back into numbers: std::string tmp = strAnswer; for (unsigned int i=0; i < tmp.length()/2; i++) { char * end; long j = strtol(tmp.substr(i*2,2).c_str(), &end, 16); answer[i] = (unsigned char) j; read++; } } else if (portType_ == MM::HIDPort) { // The USB port will attempt to read up to answerLen characters ret = core.ReadFromSerial(&device, port_.c_str(), answer, answerLen, read); if (ret != DEVICE_OK) return ret; /* // Uncomment for debugging (although port should give the same info) std::ostringstream os; os << "LMM5 answered: " << std::hex << std::setfill('0'); for (unsigned int i=0; i < read; i++) os << std::setw(2) << (unsigned int) answer[i] << " "; core.LogMessage(&device, os.str().c_str(), true); */ } return DEVICE_OK; }
int ASIFW1000Hub::FilterWheelBusy(MM::Device& device, MM::Core& core, bool& busy) { busy = false; ClearAllRcvBuf(device, core); int ret = core.SetSerialCommand(&device, port_.c_str(), "?", ""); if (ret != DEVICE_OK) { std::ostringstream os; os << "ERROR: SetSerialCommand returned error code: " << ret; core.LogMessage(&device, os.str().c_str(), false); return ret; } unsigned long read = 0; MM::TimeoutMs timerOut(core.GetCurrentMMTime(), 200 ); while (read == 0 && ( !timerOut.expired(core.GetCurrentMMTime()) ) ) { ret = core.ReadFromSerial(&device, port_.c_str(), (unsigned char*)rcvBuf_, 1, read); } if (ret != DEVICE_OK) { std::ostringstream os; os << "ERROR: ReadFromSerial returned error code: " << ret; core.LogMessage(&device, os.str().c_str(), false); return ret; } if (read != 1) { std::ostringstream os; os << "ERROR: Read " << read << " characters instead of 1"; core.LogMessage(&device, os.str().c_str(), false); return ERR_NO_ANSWER; } if (rcvBuf_[0] == '0' || rcvBuf_[0] == '1' || rcvBuf_[0] =='2') busy = false; else if (rcvBuf_[0] == '3') busy = true; return DEVICE_OK; }
/* * Queries CSU for current Magnifier position * 0 = Position 1 * 1 = Position 2 */ int CSUW1Hub::GetMagnifierPosition(MM::Device& device, MM::Core& core, int nr, int& pos) { ClearAllRcvBuf(device, core); ostringstream os; os << "EOS_POS," << nr << ",?"; int ret = ExecuteCommand(device, core, os.str().c_str()); ret = core.GetSerialAnswer(&device, port_.c_str(), RCV_BUF_LENGTH, rcvBuf_, "\r"); if (ret != DEVICE_OK) return ret; ret = Acknowledge(); if (ret != DEVICE_OK) return ret; std::ostringstream os2; os2 << "Get Magnifier answer is: " << rcvBuf_; core.LogMessage(&device, os2.str().c_str(), false); pos = atoi(rcvBuf_) - 1; return DEVICE_OK; }
/* * Queries CSU for current Aperture position * 0 = Position 1 * 1 = Position 2 * *** * 9 = Position 10 */ int CSUW1Hub::GetAperturePosition(MM::Device& device, MM::Core& core, int& pos) { ClearAllRcvBuf(device, core); std::string cmd; cmd = "AP_WIDTH,1,?"; int ret = ExecuteCommand(device, core, cmd.c_str()); ret = core.GetSerialAnswer(&device, port_.c_str(), RCV_BUF_LENGTH, rcvBuf_, "\r"); if (ret != DEVICE_OK) return ret; ret = Acknowledge(); if (ret != DEVICE_OK) return ret; std::ostringstream os; os << "Get Aperture answer is: " << rcvBuf_; core.LogMessage(&device, os.str().c_str(), false); pos = atoi(rcvBuf_) - 1; return DEVICE_OK; }
/* * Queries CSU for current BrightFieldPort position * 0 - Confocal * 1 - BrightfieldPort */ int CSUXHub::GetBrightFieldPort(MM::Device& device, MM::Core& core, int& pos) { ClearAllRcvBuf(device, core); std::string cmd; cmd = "BF_POS, ?"; int ret = ExecuteCommand(device, core, cmd.c_str()); ret = core.GetSerialAnswer(&device, port_.c_str(), RCV_BUF_LENGTH, rcvBuf_, "\r"); if (ret != DEVICE_OK) return ret; ret = Acknowledge(); if (ret != DEVICE_OK) return ret; std::ostringstream os; os << "Get BrightFieldPort answer is: " << rcvBuf_; core.LogMessage(&device, os.str().c_str(), false); if (strstr(rcvBuf_, "OFF") != 0) pos = 0; else pos = 1; return DEVICE_OK; }
/* * Queries CSU for current disk position * -1 - Bright Field * 0 - Disk 1 * 1 - Disk 2 */ int CSUW1Hub::GetDiskPosition(MM::Device& device, MM::Core& core, int& pos) { ClearAllRcvBuf(device, core); std::string cmd; cmd = "DC_SLCT, ?"; int ret = ExecuteCommand(device, core, cmd.c_str()); ret = core.GetSerialAnswer(&device, port_.c_str(), RCV_BUF_LENGTH, rcvBuf_, "\r"); if (ret != DEVICE_OK) return ret; ret = Acknowledge(); if (ret != DEVICE_OK) return ret; std::ostringstream os; os << "Get Disk Position answer is: " << rcvBuf_; core.LogMessage(&device, os.str().c_str(), false); if (strstr(rcvBuf_, "-1") != 0) pos = -1; // Bright Field else if (strstr(rcvBuf_, "1") != 0) pos = 0; // Disk 1 else pos = 1; // Disk 2 return DEVICE_OK; }
MM::DeviceDetectionStatus FocalPointCheckSerialPort(MM::Device& device, MM::Core& core, std::string portToCheck, double answerTimeoutMs) { // all conditions must be satisfied... MM::DeviceDetectionStatus result = MM::Misconfigured; char answerTO[MM::MaxStrLength]; try { std::string portLowerCase = portToCheck; 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; core.GetDeviceProperty(portToCheck.c_str(), "AnswerTimeout", answerTO); // device specific default communication parameters // for ASI Stage core.SetDeviceProperty(portToCheck.c_str(), MM::g_Keyword_Handshaking, "Off"); core.SetDeviceProperty(portToCheck.c_str(), MM::g_Keyword_StopBits, "1"); std::ostringstream too; too << answerTimeoutMs; core.SetDeviceProperty(portToCheck.c_str(), "AnswerTimeout", too.str().c_str()); core.SetDeviceProperty(portToCheck.c_str(), "DelayBetweenCharsMs", "0"); MM::Device* pS = core.GetDevice(&device, portToCheck.c_str()); std::vector< std::string> possibleBauds; possibleBauds.push_back("9600"); for( std::vector< std::string>::iterator bit = possibleBauds.begin(); bit!= possibleBauds.end(); ++bit ) { core.SetDeviceProperty(portToCheck.c_str(), MM::g_Keyword_BaudRate, (*bit).c_str() ); pS->Initialize(); core.PurgeSerial(&device, portToCheck.c_str()); // check status const char* command = "/"; int ret = core.SetSerialCommand( &device, portToCheck.c_str(), command, "\r"); if( DEVICE_OK == ret) { char answer[MM::MaxStrLength]; ret = core.GetSerialAnswer(&device, portToCheck.c_str(), MM::MaxStrLength, answer, "\r\n"); if( DEVICE_OK != ret ) { char text[MM::MaxStrLength]; device.GetErrorText(ret, text); core.LogMessage(&device, text, true); } else { // to succeed must reach here.... result = MM::CanCommunicate; } } else { char text[MM::MaxStrLength]; device.GetErrorText(ret, text); core.LogMessage(&device, text, true); } pS->Shutdown(); if( MM::CanCommunicate == result) break; else // try to yield to GUI CDeviceUtils::SleepMs(10); } // always restore the AnswerTimeout to the default core.SetDeviceProperty(portToCheck.c_str(), "AnswerTimeout", answerTO); } } catch(...) { core.LogMessage(&device, "Exception in DetectDevice!",false); } return result; }