Software triggered acquisition failing after around 300 cycles

Hi,

I am using two H-spectral cameras, Specim FX10 and FX17. Both are line cameras. I wrote a C++ code for cameras to capture images and then it moves stepper motor a step and then cameras capture the images again and so on. Basically, I am intended to make a spectral cube.

The issue is, FX10 is working fine but FX17 stops to acquire images after around 270-300 cycles with following error:
[ERROR] Acquisition timeout (Is the device waiting for a trigger?)

I am unable to understand what goes wrong when everything works fine for 300 times. I am pasting my code below:

int fx17Viewer::ScanON()
{
  MotorSetup();

  cout << "Load cameras" << endl;
  Cvb::Camera camera("%CVB%/drivers/GenICam.vin");

  // get GenICam access
  Cvb::GenICam genICam(camera);
        
  cvbval_t exposureTime = 30000;
  genICam.setExposureTime(exposureTime); // setting exposure time Camera 1

  camera.switchCamPort(1);
  Cvb::GenICam genICam2(camera);
  genICam2.setExposureTime(exposureTime);

  int m = 0;
  int k= 1;

  while(k<401 && scan_request == true)
  {
    camera.switchCamPort(0);
    cout << "switching to port 0 (Camera 1)" << endl;

    // Activate TriggerMode
    if(!genICam.setTriggerMode(true))
    {
      LogError("Activating TriggerMode was not possible");
    }
    else
    {
      // Set "TriggerSource" to "Software"
      if(!genICam.setTriggerSource("Software"))
      {
        LogError("Changing TriggerSource to Software was not possible");
      }
      else
      {
        TriggeredAcquisition(camera, genICam);
      }
      saveImage(camera, "NIR" , k);

      // Disable TriggerMode
      if(!genICam.setTriggerMode(false))
        LogError("Disabling TriggerMode was not possible");
      }

      //*********************** Change of camera port now ***************************************//

      cout << "switching to port 1 (camera 2)" << endl;
      camera.switchCamPort(1);

      // Activate TriggerMode
      if(!genICam.setTriggerMode(true))
      {
        LogError("Activating TriggerMode was not possible");
      }
      else
      {
        // Set "TriggerSource" to "Software"
        if(!genICam.setTriggerSource("Software"))
        {
          LogError("Changing TriggerSource to Software was not possible");
        }
        else
        {
          TriggeredAcquisition(camera, genICam);
         }
         saveImage(camera, "VNIR" , k);

         // Disable TriggerMode
         if(!genICam.setTriggerMode(false))
           LogError("Disabling TriggerMode was not possible");

       }

       Cvb::this_thread::sleep(300);

       MoveMotor(k);
       cout<< "Moving motor " << k << " step" <<endl;
       m=k;
       k++;
     }
  MoveMotorBack(0);
  msec_sleep( 30000 );
  StopMotor();
  return 0;
} 

Any help is highly appreciated! :slight_smile:

Hi @Saad ,

could you try to set the timeout in the driver to infinite?
You can do this in the CVBManagementConsole under the “General Settings” Tab.

Hi @Chris

Thanks for the response. I am using GeniCam browser to configure driver. Here I can configure heartbeat timeout parameter but I am not sure what exactly it is.

I am unfamiliar with CVBManagementConsole. But I assume there must be a way to configure timeout parameter in Genicam browser

Hi @Saad,
I am not sure if the HeartbeatTimeout is exactly what we are looking for.
You should be able to get a tooltip when hovering over the selected option.

Hi @Saad,

I think your problem might happen because you change the camera port so often and so many times. This is slow and creates a lot of overhead. You can and in this case, should, open both cameras at the same time and keep them open.
You had another question about the FX cameras and my colleague answered you this:

"Basically when you need the images from both configured cameras using GenICam.vin, you should use the following code:

auto path = Cvb::InstallPath();
path += CVB_LIT("drivers/GenICam.vin");
// open  devices
auto device = Cvb::DeviceFactory::Open(path, 0, 0);
auto device2 = Cvb::DeviceFactory::Open(path, 1, 0);

"
Now device is FX10 and device2 is FX17 (depends on how you configured them in Genicam Browser).
In your code you can get rid of all these switchcamports function calls and you dont need to set the parameters all the time.

Generally you should.
Open both cameras like described simultaniously. Get the Genicam access for both cameras, set the parameters needed like exposure time and triggermode once and after that loop over the acquision of the number of images you want.

Hi @Dr.Slump

thanks for the response. I really want to implement it the way you suggested: Keeping both devices open and acquire the desired number of images in the loop. I maybe wrong here but It seems like the piece of code you gave me is not supposed to work on Linux (ubuntu). I am getting errors:

However, I modified the code to work with only FX17 (the device giving timeout error). But it is failing the same way. Following is my modified code that runs only with FX17:

int fx17Viewer::ScanON()

{

MotorSetup(); // this is stepper motor, ignore it plz

       Cvb::Camera camera("%CVB%/drivers/GenICam.vin");

        cvbval_t exposureTime = 30000;

        // get GenICam access
        Cvb::GenICam genICam(camera);
        genICam.setExposureTime(exposureTime); // setting exposure time Camera 1
        genICam.setTriggerMode(true);
        genICam.setTriggerSource("Software");

int k= 1;

while(k<701 && scan_request == true)

{
        TriggeredAcquisition(camera, genICam);
        saveImage(camera, "NIR" , k);

        Cvb::this_thread::sleep(300);
        MoveMotor(k); // stepper motor , ignore plz
        cout<< "Moving motor " << k << " step" <<endl;
        k++;
}

genICam.setTriggerMode(false);
MoveMotorBack(0);
msec_sleep( 30000 );
StopMotor();
return 0;
} 

This made it clear that switching ports is not the reason of error (trigger signal timeout). So what else it can be?

Always thankful for your responses :slight_smile:

The issue is disappeared with the following code. I tested with only one device and the timeout error was there (last comment). I continued with hit and trial approach. Finally, I reduced the sleep time in the loop and tried with both devices and it worked.

int fx17Viewer::ScanON()

{   
        Cvb::Camera camera("%CVB%/drivers/GenICam.vin");

        cvbval_t exposureTime = 30000;

        // get GenICam access
        Cvb::GenICam genICam(camera);
        genICam.setExposureTime(exposureTime); // setting exposure time Camera 1
        genICam.setTriggerMode(true);
        genICam.setTriggerSource("Software");

        camera.switchCamPort(1);
        Cvb::GenICam genICam2(camera);
        genICam2.setExposureTime(exposureTime);
        genICam2.setTriggerMode(true);
        genICam2.setTriggerSource("Software");


int k= 1;

while(k<641 && scan_request == true)

{
             TriggeredAcquisition(camera, genICam);
            saveImage(camera, "NIR" , k);

                      //*********************** Change of camera now *****************************************//

             TriggeredAcquisition(camera, genICam2);
              saveImage(camera, "VNIR" , k);

                       MoveMotor(k);
                       cout<< "Moving motor " << k << " step" <<endl;
                       Cvb::this_thread::sleep(100);
                        k++;
}

genICam.setTriggerMode(false);
genICam2.setTriggerMode(false);

MoveMotorBack(0);
msec_sleep( 50000 );
StopMotor();
return 0;
}

Please let me know if you can guess what was the issue and how it can be relevant to the sleep time?

And is there a better a way to get genicam access to both devices? I am still switching ports one time before loop.

Many thanks for your support! :slight_smile:

when I process the data (images) I realized the above code is only acquiring images from FX10. That’s why the error disappeared. It is acquiring images from only FX17 beacause I changed to port 1 before the loop.

The code to open both devices simultaneously, provided by @Dr.Slump is not working (perhaps not supposed to work on linux based system).

How I can acquire images from both devices without switching ports on linux based system?

Hi @Saad ,

maybe you could try the following code:

#include <cvb/device_factory.hpp> 
#include <cvb/utilities/system_info.hpp> 
#include <cvb/driver/stream.hpp> 
#include <iostream>   

using namespace std; 
using namespace Cvb;   

int main(int argc, char* argv[]) 
{ 
  auto path = InstallPath(); 
  path += CVB_LIT("drivers/GenICam.vin");   

  // open a device 
  auto device1 = DeviceFactory::Open(path,1);   
  auto device2 = DeviceFactory::Open(path);   

  // get the first stream of the device 
  auto stream1 = device1->Stream(); 
  stream1->Start();
  auto stream2 = device2->Stream(); 
  stream2->Start();  
} 

I have not tested this here its just from my memories but this should leave you with 2 streams that you can get your images from independently.