PDA

View Full Version : Acquiring more than 1 frame/trigger



Hermes
June 24, 2014, 00:54:51
Hi Stefan,

I am implementing a program in VS C++ 2010 to trigger my DMK 23U618 with another equipment. I need to make a video of few seconds after a trigger pulse happens. How can I detect a trigger pulse, so I could use it to start an acquisition (independent of other trigger pulses) in the maximum frame rate of my camera (120 fps)? I know that the trigger mode allows me to acquire only one frame/trigger, but I would turn off the trigger mode right after acquiring the first frame.

I would need something like "icImagingControl1->TRIGGERHAPPENED".

if ("icImagingControl1->TRIGGERHAPPENED")
{
icImagingControl1->DeviceTrigger=false;
icImagingControl1->LiveStart();
icImagingControl1->AviStartCapture(txtFilename->Text + ".avi", cboVideoCodec->SelectedItem->ToString());
timer1->Interval = 1000; // 1 second interval
timeLeft->Text = RecTime->Text + " seconds";
countdown = Convert::ToInt32(RecTime->Text);
timer1->Enabled = true;
}



Thanks,
Hermes

Stefan Geissler
June 24, 2014, 09:45:04
The trigger is intended to trigger one image. Otherwise the trigger wont make sense.

However, you can use the trigger input as GP In and poll its value in your program. As soon as it change from 0 to 1 you start AVI capture, when it changes back to 0, you stop AVI Capture.


bool Is_GPIO_Read_Available(Grabber* pGrabber)
{
bool bResult = false;
if( pGrabber->isDevValid() )
{
tIVCDButtonPropertyPtr pButtonItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIORead ,pButtonItf);

if( pButtonItf != NULL )
{
bResult = true;
}
}

return bResult;
}



void Push_GPIO_Read(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDButtonPropertyPtr pButtonItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIORead ,pButtonItf);

if( pButtonItf != NULL )
{
pButtonItf->push();
}
}
}

bool Is_GPIO_GP_IN_Available(Grabber* pGrabber)
{
bool bResult = false;
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
bResult = true;
}
}

return bResult;
}


long Get_GPIO_GP_IN_Value(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
return pRangeItf->getValue();
}
}

return 0;
}

void Set_GPIO_GP_IN_Value(Grabber* pGrabber, long Value)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
pRangeItf->setValue(Value);
}
}
}

long Get_GPIO_GP_IN_Min(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
return pRangeItf->getRangeMin();
}
}

return 0;
}

long Get_GPIO_GP_IN_Max(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
return pRangeItf->getRangeMax();
}
}

return 0;
}


You call "Push_GPIO_Read(Grabber* pGrabber)" to query the value from the camera and receive the value by calling "Get_GPIO_GP_IN_Max(Grabber* pGrabber)". You call both functions.

Hermes
June 25, 2014, 17:41:20
The trigger is intended to trigger one image. Otherwise the trigger wont make sense.

However, you can use the trigger input as GP In and poll its value in your program. As soon as it change from 0 to 1 you start AVI capture, when it changes back to 0, you stop AVI Capture.


bool Is_GPIO_Read_Available(Grabber* pGrabber)
{
bool bResult = false;
if( pGrabber->isDevValid() )
{
tIVCDButtonPropertyPtr pButtonItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIORead ,pButtonItf);

if( pButtonItf != NULL )
{
bResult = true;
}
}

return bResult;
}



void Push_GPIO_Read(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDButtonPropertyPtr pButtonItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIORead ,pButtonItf);

if( pButtonItf != NULL )
{
pButtonItf->push();
}
}
}

bool Is_GPIO_GP_IN_Available(Grabber* pGrabber)
{
bool bResult = false;
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
bResult = true;
}
}

return bResult;
}


long Get_GPIO_GP_IN_Value(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
return pRangeItf->getValue();
}
}

return 0;
}

void Set_GPIO_GP_IN_Value(Grabber* pGrabber, long Value)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
pRangeItf->setValue(Value);
}
}
}

long Get_GPIO_GP_IN_Min(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
return pRangeItf->getRangeMin();
}
}

return 0;
}

long Get_GPIO_GP_IN_Max(Grabber* pGrabber)
{
if( pGrabber->isDevValid() )
{
tIVCDRangePropertyPtr pRangeItf;
tIVCDPropertyItemsPtr pItems = pGrabber->getAvailableVCDProperties();
pItems->findInterfacePtr(VCDID_GPIO, VCDElement_GPIOIn ,pRangeItf);

if( pRangeItf != NULL )
{
return pRangeItf->getRangeMax();
}
}

return 0;
}


You call "Push_GPIO_Read(Grabber* pGrabber)" to query the value from the camera and receive the value by calling "Get_GPIO_GP_IN_Max(Grabber* pGrabber)". You call both functions.


Thank you for the prompt answer. I think this may work for me.
I see that I need to instantiating the grabber, right? But, I'm using VS express 2010 edition and the documentation of the support doesn't match for this version. For example in the "First Steps", I don't have the "MFC Application" option. I'm a bit confused how to initiate the library and use the grabber. Do you have a guideline for VS express to do it?

Thanks,
Hermes

Stefan Geissler
June 26, 2014, 09:39:19
Hermes,

without instantiating the DShowLib::Grabber nothing will happen at all.



You are right, the VS Express does not contain MFC. Therefore, it is for free.

But you can create a console application. Many of the IC Imaging Control samples in your Documents\IC Imagign Control 3.3. directly are console application.

Hermes
July 11, 2014, 21:44:04
Hi Stefan,

Thanks for you help! I am replying just to leave a feedback on how I implemented the trigger detection. It may be useful for other users.

I used the grabber only to detect the trigger pulse using your functions mentioned before. I decided to keep the icImagingControl class to record and control the camera, because all my code used that before.

Now, I can trigger videos with any time duration after 1 trigger pulse happens.



// Capture button
private: System::Void cmdRecord_Click(System::Object^ sender, System::EventArgs^ e)
{
if (RecTime->Text == "")
{
MessageBox::Show("Please type a valid recording time!");
}
else
{
// Live mode needs to be off in order to control the grabber options
if (icImagingControl1->LiveVideoRunning)
{
StopLiveVideo();
}
// Choose the current camera
pGrabber->openDev("DMK 23U618");
// If it is a different camera, choose in the list the correct one
if( !pGrabber->isDevValid() )
{
labelTeste->Text= "Device not selected or invalid!";
pGrabber->showDevicePage();
}
else
{
labelTeste->Text= icImagingControl1->Device;
}

// Turn on the trigger mode
icImagingControl1->DeviceTrigger=true;

////////// Loop to wait for the trigger pulse.
Push_GPIO_Read(pGrabber); // Query the value from the camera
while(1 > Get_GPIO_GP_IN_Value(pGrabber)){ // Receive the trigger value from the camera
if (GetAsyncKeyState(VK_CONTROL)){ // Preventing to be stuck in the loop. Press "Ctrl" to get out of the loop. Add "#include <Windows.h>" in the beginning of your code.
return;
}
Push_GPIO_Read(pGrabber); // Query the value from the camera every loop round.
}
// Turn off trigger mode, so the video can be recorded in the any chosen frame rate independent on the trigger pulses
icImagingControl1->DeviceTrigger=false;
// Turn off the grabber. The grabber was used only to query the trigger from the camera.
pGrabber->closeDev();
// Start function to acquire video
StartAcquistionWithTrigger();
}
}

private :Void StartAcquistionWithTrigger()
{
// Get the date and time to save as part of the video file name
SYSTEMTIME st;
GetLocalTime(&st);
filename->Text = "Filename: " + txtFilename->Text + Convert::ToString(st.wYear) + "_" + Convert::ToString(st.wMonth)+ "_" + Convert::ToString(st.wDay) + "_" + "_" + Convert::ToString(st.wHour) + "_" + Convert::ToString(st.wMinute) + "_" + Convert::ToString(st.wSecond) + ".avi";
// Start live mode
icImagingControl1->LiveStart();
cmdLive->Text = "Stop Live";
// Save avi file
icImagingControl1->AviStartCapture(filename->Text, cboVideoCodec->SelectedItem->ToString());
txtFilename->Text = "";
// Shows in the form the countdown
timeLeft->Text = RecTime->Text + " seconds";timer1->Interval = 1000; // 1 second interval
timeLeft->Text = RecTime->Text + " seconds";
countdown = Convert::ToInt32(RecTime->Text);
// Starts timer
timer1->Enabled = true;
}

// Countdown
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
if (countdown > 0)
{
// Display the new time left
// by updating the Time Left label.
countdown = countdown - 1;
timeLeft->Text = countdown + " seconds";
currFramerate->Text = Convert::ToString(icImagingControl1->DeviceFrameRate);
}
else
{
// If the user ran out of time, stop the timer, show
// a MessageBox, and fill in the answers.
timer1->Stop();
icImagingControl1->AviStopCapture();
StopLiveVideo();
MessageBox::Show("Video " + txtFilename->Text + " recording completed!");
}
}

Best regards,
Hermes

Stefan Geissler
July 14, 2014, 10:39:40
Hermes,

Thank you very much for your feedback!