<< Click to Display Table of Contents >> Navigation: CVB with GenICam > SDK > Connection Monitoring |
With our GenICam architecture it is possible to be informed if a device disconnects or reconnects.
This is called Connection Monitoring and is supported with GigE Vision.
This feature can be useful if a device temporarily loose its power and the connection needs to be re-established.
The Connection Monitoring is realized over the INotify interface with its DEVICE_DISCONNECTED and DEVICE_RECONNECT event.
Important Notes:
•Configure the devices with a persistent IP address and do not use DHCP to be able to get reconnected events.
•When the camera is reconnected the driver should be reloaded to ensure if camera and driver are in correct status again.
•There is no need to reload the driver when you do not use special driver configuration (working with defaults).
•Do not unload (ReleaseObject) the camera IMG inside the callback thread.
•Do not call G2Freeze() and G2Grab() within the callback itself.
•The callback functions should only be used to inform your acquisition state that it need to be stopped or started.
•The INotify callbacks are fired from an internal thread context, thus be careful when accessing the GUI.
Sample code how to use the INotify Interface for Connection Monitoring:
C++ Connection Monitoring Example (CVB 2017 - 13.x.x)
#include <atomic> #include <cassert> #include <iostream> #include <sstream> #include <stdexcept> #include <thread>
#include <iCVCImg.h> #include <iCVCDriver.h> #include <iDC_GenICam.h>
// main function is below // vvvvvvvvvvvvvvvvvvvvvv
class Camera { IMG handle_; // the driver image std::atomic<bool> isConnected_; // the connection state
public: Camera() : handle_(OpenCamera()) , isConnected_(true) { InitCamera(); }
Camera(const Camera &) = delete; // no copy Camera &operator =(const Camera &) = delete; // no copy
virtual ~Camera() { Unload(); }
bool IsConnected() const { return isConnected_; }
void Reload() { // this method cannot be implemented with any exception safety: // to get a clean start we need to unload first Unload();
handle_ = OpenCamera(); InitCamera(); }
private: // opens the first camera and returns its handle; throws on error static IMG OpenCamera() { if(const char *cvbDir = std::getenv("CVB")) { std::stringstream path; path << cvbDir << "Drivers/GenICam.vin"; IMG handle = nullptr; if(LoadImageFile(path.str().c_str(), handle)) return handle; }
throw std::runtime_error("Error opening GenICam.vin"); }
void InitCamera() { assert(CanNotify(handle_)); assert(IsEventAvailable(CVNO_EID_DEVICE_DISCONNECTED)); assert(IsEventAvailable(CVNO_EID_DEVICE_RECONNECT));
RegisterEvent(CVNO_EID_DEVICE_DISCONNECTED, &Camera::OnDisconnectedDispatcher); RegisterEvent(CVNO_EID_DEVICE_RECONNECT, &Camera::OnReconnectDispatcher); }
bool IsEventAvailable(CVNotifyEvent_t id) const { cvbint64_t status = 0; if(cvbres_t error = NOGetStatus(handle_, id, CVNO_INFO_IS_AVAILABLE, status)) throw std::runtime_error("Error getting INotify event availability");
return status != 0; }
void RegisterEvent(CVNotifyEvent_t id, CVBDRIVER_NOTIFY_CB callback) { intptr_t ignored = 0; // we do not want to unregister the event if(cvbres_t error = NORegister(handle_, id, callback, this, ignored)) throw std::runtime_error("Error registering INotify event"); }
static void __stdcall OnDisconnectedDispatcher(CVNotifyEvent_t /*id*/, void * /*buffer*/, size_t /*bufferSize*/, CVNotifyDatatype_t /*bufferDataType*/, void *pThis) { // called from non-main thread context reinterpret_cast<Camera *>(pThis)->OnDisconnected(); }
void OnDisconnected() { isConnected_ = false; }
static void __stdcall OnReconnectDispatcher(CVNotifyEvent_t /*id*/, void * /*buffer*/, size_t /*bufferSize*/, CVNotifyDatatype_t /*bufferDataType*/, void *pThis) { // called from non-main thread context reinterpret_cast<Camera *>(pThis)->OnReconnect(); }
void OnReconnect() { isConnected_ = true; }
void Unload() { ReleaseObject(handle_); assert(handle_ == nullptr); } };
int main() { try { Camera camera;
std::cout << "Opened first GenICam camera (connected)...\n";
bool connected = true; while(true) { if(connected != camera.IsConnected()) { connected = !connected; // toggle local state
if(!connected) { std::cout << "Disconnected! Waiting for reconnect...\n"; } else { std::cout << "Reconnected! Reloading..."; camera.Reload(); std::cout << " done.\n"; } }
std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } catch(std::exception &ex) { std::cerr << ex.what() << "\n"; }
return 0; }
|
C# Connection Monitoring Example (CVB 2017 - 13.x.x)
{{{
|