Please enable JavaScript to view this site.

IDS peak 2.8.0 / uEye+ firmware 3.33

Before you can receive an event from the camera, you must activate it in the camera, e.g. the start of the exposure ("ExposureStart").

genericC++

nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventSelector")->SetCurrentEntry("ExposureStart");
 
// Enable continuous notification
nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")->SetCurrentEntry("On");
 
// Enable one time notification
nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")->SetCurrentEntry("Once");
 
// Disable notification
nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")->SetCurrentEntry("Off");

Receiving camera events on the host PC works similarly to waiting for images. It should be done in a separate thread. Here, a thread is used under Qt and first a worker class is defined (see also Receiving images).

Additionally, the camera object (std::shared_ptr<peak::core::Device>) and the EventController are required.

genericC++

class EventWorker : public QObject
{
  Q_OBJECT
 
public:
 
  EventWorker(std::shared_ptr<peak::core::Device> device, QObject parent);
  ~EventWorker();
 
private:
 
  std::shared_ptr<peak::core::Device> m_device;
  std::unique_ptr<peak::core::EventController> m_eventController;
  std::shared_ptr<peak::core::NodeMap> m_nodemapRemoteDevice;
  bool m_running;
 
public slots:
 
  void Start();
};

Implementing the worker class

genericC++

EventWorker::EventWorker(std::shared_ptr<peak::core::Device> device, QObject parent) : QObject(parent)
{
  m_device = device;
  m_eventController = nullptr;
  m_nodemapRemoteDevice = m_device->RemoteDevice()->NodeMaps().at(0);
  m_running = false;
}
 
EventWorker::~EventWorker()
{
}
 
void EventWorker::Start()
{
  try
  {
      // Enable events from the camera (remote device)
      m_eventController = m_device->EnableEvents(EventType::RemoteDevice);
      if (!m_eventController)
      {
          // ...
          return;
      }
  }
  catch (std::exception& e)
  {
      // ...
      return;
  }
 
  m_running = true;
 
  while (m_running)
  {
      try
      {
          // Wait an infinite time for events
          auto event = m_eventController->WaitForEvent(peak::core::Timeout::INFINITE_TIMEOUT);
 
          // Insert event into tree
          m_nodemapRemoteDevice->UpdateEventNodes(event);
 
          auto type = peak::core::ToString(event->Type());
           
          if (peak::core::EventType::RemoteDevice == event->Type())
          {
              // Get unique identifier of the exposure start event and check if the received event has the same id
              uint64_t exposureStartID = static_cast<uint64_t>(m_camera->GetNodemapRemoteDevice()->FindNode<peak::core::nodes::IntegerNode>("EventExposureStart")->Value());
              if (event->ID() == exposureStartID)
              {
                  // ...
              }
          }
      }
      catch (std::exception& e)
      {
          // ...
      }
  }
}

Creating and starting the worker thread in main program

genericC++

void mainProgram()
{
  // ...
   
  // Create worker thread
  EventWorker* m_eventWorker = new EventWorker();
  QThread m_eventThread;
 
  // Move the worker to a new thread
  m_eventWorker ->moveToThread(&m_eventThread);
 
  // Call Start() slot of the worker when QThread starts
  connect(&m_eventThread, SIGNAL(started()), m_eventWorker , SLOT(Start()));
 
  // Start QThread
  m_eventThread.start();
}

Alternative solution in C++ with a standard thread

genericC++

class EventWorker
{
public:
 
  EventWorker(const std::shared_ptr<peak::core::Device>& device);
  ~EventWorker();
 
  EventWorker(const EventWorker& o) = delete;
  EventWorker& operator=(const EventWorker& o) = delete;
  EventWorker(EventWorker&& o) = default;
  EventWorker& operator=(EventWorker&& o) = default;
 
 
private:
  void run();
 
  std::shared_ptr<peak::core::Device> m_device;
  std::unique_ptr<peak::core::EventController> m_eventController;
  std::shared_ptr<peak::core::NodeMap> m_nodemapRemoteDevice;
 
  std::atomic_bool m_running{ false };
  std::thread m_listenerThread;
};

genericC++

EventWorker::EventWorker(const std::shared_ptr<peak::core::Device>& device)
  : m_device(device)
{
  // Enable events from the camera (remote device)
  m_eventController = std::move(m_device->EnableEvents(peak::core::EventType::RemoteDevice));
  m_nodemapRemoteDevice = m_device->RemoteDevice()->NodeMaps().at(0);
 
  // Enable "ExposureStart" event on the camera
  m_nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventSelector")
      ->SetCurrentEntry("ExposureStart");
  m_nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")
      ->SetCurrentEntry("On");
 
  // Enable additional events
  // ...
 
  // Start the event listener thread
  m_listenerThread = std::thread([this]() {
      run();
      });
}
 
EventWorker::~EventWorker()
{
  // Stop the event listener thread
  m_running = false;
  if (m_listenerThread.joinable()) {
      try {
          // Stop the current WaitForEvent()
          m_eventController->KillWait();
      }
      catch (const peak::core::Exception&) {
          // ignore
      }
      m_listenerThread.join();
  }
}
 
void EventWorker::run()
{
  m_running = true;
  while (m_running) {
      try {
          auto event = m_eventController->WaitForEvent(
              peak::core::Timeout::INFINITE_TIMEOUT);
 
          if (event->Type() != peak::core::EventType::RemoteDevice)
          {
              // error ...
          }
 
          m_nodemapRemoteDevice->UpdateEventNodes(event);
 
          // Get unique identifier of the exposure start event and check if the received event has the same id
          uint64_t exposureStartID = static_cast<uint64_t>(m_nodemapRemoteDevice->FindNode<peak::core::nodes::IntegerNode>("EventExposureStart")->Value());
          if (event->ID() == exposureStartID)
          {
              // Handle event ...
          }
          // Handle additional events
          // ...
      }
      catch (const peak::core::Exception& e) {
          // ...
      }
  }
}

genericC++

void mainProgram() {
  // ...
   
  // Create worker thread
  EventWorker eventWorker(device);
}

© 2024 IDS Imaging Development Systems GmbH