Skip to content

Commit

Permalink
Added auto-reconnect feature
Browse files Browse the repository at this point in the history
Driver now automatically reconnects if the USB connection drops
  • Loading branch information
mueller-physics committed May 25, 2017
1 parent 907c24d commit cc583bf
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 35 deletions.
129 changes: 98 additions & 31 deletions IDS_uEye.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ int CIDS_uEye::Initialize()
nRet = CreateProperty(MM::g_Keyword_Offset, "0", MM::Integer, false);
assert(nRet == DEVICE_OK);

// readout time
// ReadoutTime
pAct = new CPropertyAction (this, &CIDS_uEye::OnReadoutTime);
nRet = CreateProperty(MM::g_Keyword_ReadoutTime, "0", MM::Float, false, pAct);
assert(nRet == DEVICE_OK);
Expand Down Expand Up @@ -605,6 +605,20 @@ int CIDS_uEye::Initialize()
if (nRet != DEVICE_OK)
return nRet;


// Number to retries on USB connection error
pAct = new CPropertyAction (this, &CIDS_uEye::OnUsbRetryMax);
nRet = CreateProperty("USB maximum retry", "20", MM::Integer, false, pAct);
SetPropertyLimits("USB maximum retry", 10, 1000);
assert(nRet == DEVICE_OK);

// Sleep time after USB connection error
pAct = new CPropertyAction (this, &CIDS_uEye::OnUsbRetrySleep);
nRet = CreateProperty("USB sleep before retry", "2", MM::Integer, false, pAct);
SetPropertyLimits("USB sleep before retry", 0, 100);
assert(nRet == DEVICE_OK);



// synchronize all properties
// --------------------------
Expand Down Expand Up @@ -1292,7 +1306,19 @@ int CIDS_uEye::StopSequenceAcquisition()
if (ret != IS_SUCCESS)
LogMessage("IDS_uEye: Camera failed to set frame buffer address");
*/


// directly signal on external pin that acq. has stopped
if (gpioOutputMode_ == 1 ) {

IO_GPIO_CONFIGURATION gpioConfiguration;
gpioConfiguration.u32Gpio = IO_GPIO_1;
gpioConfiguration.u32Configuration = IS_GPIO_OUTPUT;
gpioConfiguration.u32State = 0;

is_IO(hCam, IS_IO_CMD_GPIOS_SET_CONFIGURATION, (void*)&gpioConfiguration,
sizeof(gpioConfiguration));
}

ringBufOutputActive_ = false;
//SetImageMemory();
}
Expand Down Expand Up @@ -1417,7 +1443,7 @@ int CIDS_uEye::InsertImage()

//md.put(MM::g_Keyword_Label, tStamp);


imageCounter_++;

char buf[MM::MaxStrLength];
Expand Down Expand Up @@ -1625,8 +1651,12 @@ int MySequenceThread::svc(void) throw()
// initialize the video

camera_->LogMessage("IDS_uEye: Starting 'is_CaptureVideo'");
//int nret = is_CaptureVideo(camera_->hCam, ACQ_TIMEOUT);
int nret = is_CaptureVideo(camera_->hCam, IS_DONT_WAIT);
int nret = IS_SUCCESS;
if ( camera_->gpioOutputMode_ == 1 )
nret = is_CaptureVideo(camera_->hCam, IS_DONT_WAIT);
else
nret = is_CaptureVideo(camera_->hCam, ACQ_TIMEOUT);

if (nret != IS_SUCCESS) {
char err[128];
snprintf(err,127,"IDS_uEye: Error starting up async video mode, err #%d", nret);
Expand All @@ -1639,12 +1669,8 @@ int MySequenceThread::svc(void) throw()
// trigger external hardware via GPIO
if ( camera_->gpioOutputMode_ == 1 ) {
int nRet = IS_SUCCESS;


// busy-wait for 5 ms
MM::MMTime startTime = camera_->GetCurrentMMTime();
MM::MMTime waitLength(5000);
while (waitLength > (camera_->GetCurrentMMTime() - startTime)) {}

// set the pin high
IO_GPIO_CONFIGURATION gpioConfiguration;
gpioConfiguration.u32Gpio = IO_GPIO_1;
Expand All @@ -1653,24 +1679,8 @@ int MySequenceThread::svc(void) throw()

nRet = is_IO(camera_->hCam, IS_IO_CMD_GPIOS_SET_CONFIGURATION, (void*)&gpioConfiguration,
sizeof(gpioConfiguration));

// busy-wait for 500 us
startTime = camera_->GetCurrentMMTime();
MM::MMTime pulseLength(500);
while (pulseLength > (camera_->GetCurrentMMTime() - startTime)) {}

// set the pin low
gpioConfiguration.u32Gpio = IO_GPIO_1;
gpioConfiguration.u32Configuration = IS_GPIO_OUTPUT;
gpioConfiguration.u32State = 0;

nRet = is_IO(camera_->hCam, IS_IO_CMD_GPIOS_SET_CONFIGURATION, (void*)&gpioConfiguration,
sizeof(gpioConfiguration));


}




// loop for images
try
Expand All @@ -1685,16 +1695,28 @@ int MySequenceThread::svc(void) throw()
retryCount++;
ret = DEVICE_OK;
char err[128];
snprintf(err,127,"IDS_uEye: ERR 3, dev not connected, retry %d / %d", retryCount, UEYE_MAX_ASYNC_RETRIEVE_RETRY);
snprintf(err,127,"IDS_uEye: ERR 3, dev not connected, retry %d / %d", retryCount, camera_->usbRetryMax_);
camera_->LogMessage(err);
CDeviceUtils::SleepMs(3);

CDeviceUtils::SleepMs(camera_->usbRetrySleep_);
} else {
retryCount=0;
imageCounter_++;
}

} while (DEVICE_OK == ret && !IsStopped() && (imageCounter_ < numImages_) && !(retryCount > UEYE_MAX_ASYNC_RETRIEVE_RETRY));
} while (DEVICE_OK == ret && !IsStopped() && (imageCounter_ < numImages_) && !(retryCount >= camera_->usbRetryMax_));

// set the output pin low again
if (camera_->gpioOutputMode_ == 1 ) {

// set the pin low
IO_GPIO_CONFIGURATION gpioConfiguration;
gpioConfiguration.u32Gpio = IO_GPIO_1;
gpioConfiguration.u32Configuration = IS_GPIO_OUTPUT;
gpioConfiguration.u32State = 0;

is_IO(camera_->hCam, IS_IO_CMD_GPIOS_SET_CONFIGURATION, (void*)&gpioConfiguration,
sizeof(gpioConfiguration));
}

if (IsStopped())
camera_->LogMessage("IDS_uEye: SeqAcquisition interrupted by the user", true);
Expand Down Expand Up @@ -2149,6 +2171,51 @@ int CIDS_uEye::OnReadoutTime(MM::PropertyBase* pProp, MM::ActionType eAct)
return DEVICE_OK;
}


/**
* Handles "UsbRetryMax" property.
*/
int CIDS_uEye::OnUsbRetryMax(MM::PropertyBase* pProp, MM::ActionType eAct)
{

if (eAct == MM::AfterSet)
{
long usbRetry;
pProp->Get(usbRetry);

usbRetryMax_ = (usbRetry>10)?(usbRetry):(10);
}
else if (eAct == MM::BeforeGet)
{
pProp->Set(usbRetryMax_);
}

return DEVICE_OK;
}

/**
* Handles "UsbRetrySleep" property.
*/
int CIDS_uEye::OnUsbRetrySleep(MM::PropertyBase* pProp, MM::ActionType eAct)
{

if (eAct == MM::AfterSet)
{
long usbSleep;
pProp->Get(usbSleep);

usbRetrySleep_ = (usbSleep>0)?(usbSleep):(0);
}
else if (eAct == MM::BeforeGet)
{
pProp->Set(usbRetrySleep_);
}

return DEVICE_OK;
}



int CIDS_uEye::OnDropPixels(MM::PropertyBase* pProp, MM::ActionType eAct)
{

Expand Down
14 changes: 10 additions & 4 deletions IDS_uEye.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ using namespace std;
#define EXPOSURE_MAX 10000 //maximal exposure (ms) to use, even if the camera reports higher values
#define UEYE_RINGBUFFER_SIZE 128 //maximum size of async ringbuffer, in MB
#define UEYE_MAX_RINGBUFFER_ELEMENTS 128 //maximum number of images in ringbuffer
#define UEYE_MAX_ASYNC_RETRIEVE_RETRY 20 //maximum number of retries when async image wait fails with "IS_CANT_OPEN_DEVICE"

// This has been replaced by runtime-settable usbRetryMax_
//#define UEYE_MAX_ASYNC_RETRIEVE_RETRY 20 //maximum number of retries when async image wait fails with "IS_CANT_OPEN_DEVICE"

//////////////////////////////////////////////////////////////////////////////
// Error codes
Expand Down Expand Up @@ -314,6 +316,8 @@ class CIDS_uEye : public CCameraBase<CIDS_uEye>
int OnFlashMode(MM::PropertyBase* pProp, MM::ActionType eAct);
int OnVideoSyncMode(MM::PropertyBase* pProp, MM::ActionType eAct);
int OnGpioSeqTrigger(MM::PropertyBase* pProp, MM::ActionType eAct);
int OnUsbRetryMax(MM::PropertyBase* pProp, MM::ActionType eAct);
int OnUsbRetrySleep(MM::PropertyBase* pProp, MM::ActionType eAct);


private:
Expand Down Expand Up @@ -377,9 +381,11 @@ class CIDS_uEye : public CCameraBase<CIDS_uEye>
string binModeName_; //name of the current binning mode


bool videoFastMode_;
int gpioOutputMode_;

bool videoFastMode_; // if to run in async buffered video mode
int gpioOutputMode_; // how to set the GPIO output
long usbRetryMax_; // retry how often on USB transfer error
long usbRetrySleep_; // retry after x milliseconds

bool dropPixels_;
bool saturatePixels_;
double fractionOfPixelsToDropOrSaturate_;
Expand Down

0 comments on commit cc583bf

Please sign in to comment.