Project

General

Profile

Application does not receive callback from hardware trigger input

Added by Omar Rahim almost 13 years ago

Customer reports that their application does not receive a callback from the camera hardware trigger.
"It's not clear from the documentation if we need to call CLSetGPIO() before CLSetTrigger(). But either way, the application does not receive a callback upon setting the trigger line either high or low. Please review test program below:"

-------------------------program using camera trigger to start exposure but never getting callback-----------------------

#include "stdafx.h" 
#include "clcamiface.h" 

extern "C" {
void processHeartBeat(int c, HEARTBEAT_DATA* h);
void processImage(int c, tsImageData* i);
}

int _tmain(int argc, _TCHAR* argv[])
{
printf("hello");
int c = CLOpenHSUSBCamera(0);
int r = CLEnableFan(c, 0);
Sleep(200);
r = CLEnableFan(c, 1);

#if 0
r = CLSetGPIO(c, 0, eeINPUT);
r = CLSetGPIO(c, 1, eeINPUT);
r = CLSetGPIO(c, 2, eeINPUT);
r = CLSetGPIO(c, 3, eeINPUT);
#endif
r = CLSetTrigger(c, 1);

int numSettings;
int currentSettings;
float gains[MAX_GAIN_SETTINGS ];
r = CLGetGainConfig(c, &numSettings, gains, &currentSettings);

r = CLSetImageInterval(c, 0);

r = CLSetHeartBeatCallback(c, processHeartBeat);
r = CLSetImageDataCallback(c, processImage);

if (CLisCameraReady(c) != CL_CAMERA_READY) {
printf("<camera not ready>");
}

r = CLSetExposure(c, 1);
r = CLSetGain(c, 0);
//CLReadCCDArea(c, NULL, 1, 1);
for (int i = 0; i < 1000; ++i) {
r = CLGetGPIO(c);
CLClearCCD(c, 1, 0);
printf("\n<count=%d, GPIO=0x%x>", i, r);
Sleep(400);
}
    r = CLCloseCamera(c);
return 0;
}

void processHeartBeat(int c, HEARTBEAT_DATA* h) {
printf("<h%d>", h->errorByte);
}

void processImage(int c, tsImageData* i) {
printf("<i>");
}


Replies (4)

RE: Application does not receive callback from hardware trigger input - Added by Michael Williamson almost 13 years ago

Why is the CLReadCCDArea() call commented out? You need to leave that call in place to get an image.

Do you see the printf show the GPIO pin in question change?

Do you get heartbeat callbacks?

Try removing the CLClearCCD() command in your loop.

-Mike

RE: Application does not receive callback from hardware trigger input - Added by Gary Scott almost 13 years ago

The following line: r = CLReadCCDArea(c, NULL, 0, 0); // results in many callbacks
causes many callback with image data but they aren't tied to the hardware trigger. It looks like using a 0 for the number of images causes it to free-run.
The printf does show the GPIO line changing.
Heartbeats get a callback. About 1/sec.
I'll try removing the CLClearCCD() command in the loop. Will post the results in a few hours since I'm still at home.
Many thanks for your response.
-Gary

Here's the latest code I used. Taking out the reset caused the noops error to go away. Sorry, the formatting has been lost in the copy:

@--------------------C++ code used with MityCCD-H70310906-BS. Trying to get hardware triggers to work.------------
// mityccd.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "clcamiface.h"

extern "C" {
void processHeartBeat(int c, HEARTBEAT_DATA* h);
void processImage(int c, tsImageData* i);
void processError(int c, unsigned char severity, unsigned char code, char* str);
}

#define CAMERA_TRIGGER_LINE (1) //1
#define CAMERA_NO_TRIGGER_LINE (-1)
#define CAMERA_SYNC_LINE (0) // 0
#define CAMERA_ROWS (64)
#define CAMERA_COLUMNS (512)

#define NUM_IMAGEPIXELS (32)

void cameraStatus(int result, char* callerStr);

int _tmain(int argc, _TCHAR* argv[]) {
printf("hello");
int c = CLOpenHSUSBCamera(0);
int r;
#if 0
// This takes too long for the camera to reboot.
r = CLCameraReset(c);
cameraStatus(r, "CLCameraReset");
Sleep(200);
#endif
r = CLEnableFan(c, 0);
cameraStatus(r, "CLEnableFan");
Sleep(200);
r = CLEnableFan(c, 1);
cameraStatus(r, "CLEnableFan");
r = CLSetCCDOffset(c, 200, 0);
cameraStatus(r, "CLSetCCDOffset");

// Set vertical binning
unsigned char verticalBins[CAMERA_ROWS];
for (int i = 0; i < CAMERA_ROWS; ++i) {
verticalBins[i] = BINCODE_BIN;
}
r = CLSetBinParam(c, verticalBins, 0);
cameraStatus(r, "CLSetBinParam");

// Set horizontal binning
unsigned char horizontalBins[CAMERA_COLUMNS];
int pixelsPerBin = CAMERA_COLUMNS / NUM_IMAGEPIXELS;
int index = 0;
for (int i = 0; i < NUM_IMAGEPIXELS; i++) {
for (int j = 0; j < pixelsPerBin - 1; j++) {
horizontalBins[index++] = BINCODE_SUM;
}
horizontalBins[index++] = BINCODE_SEND;
}
r = CLSetHorBinParam(c, horizontalBins, 0);
cameraStatus(r, "CLSetHorBinParam");

#if 0
r = CLSetGPIO(c, 1, eeINPUT);
r = CLSetGPIO(c, 2, eeINPUT);
r = CLSetGPIO(c, 3, eeINPUT);
#endif
r = CLSetGPIO(c, CAMERA_SYNC_LINE, eeINPUT);
cameraStatus(r, "CLSetGPIO");
r = CLSetGPIO(c, CAMERA_TRIGGER_LINE, eeINPUT);
cameraStatus(r, "CLSetGPIO");
r = CLSetTrigger(c, CAMERA_TRIGGER_LINE);
cameraStatus(r, "CLSetTrigger");

r = CLSetShutterParams(c, 0, 0, 1);
cameraStatus(r, "CLSetShutterParams");

int numSettings;
int currentSettings;
float gains[MAX_GAIN_SETTINGS ];
r = CLGetGainConfig(c, &numSettings, gains, &currentSettings);
cameraStatus(r, "CLGetGainConfig");
r = CLSetImageInterval(c, 0);
cameraStatus(r, "CLSetImageInterval");

r = CLClearCCD(c, 1, 0);
cameraStatus(r, "CLClearCCD");
r = CLSetImageDataCallback(c, processImage);
cameraStatus(r, "CLSetImageDataCallback");
r = CLSetHeartBeatCallback(c, processHeartBeat);
cameraStatus(r, "CLSetHeartBeatCallback");
r = CLSetErrorCallback(c, processError);
cameraStatus(r, "CLSetErrorCallback");

#if 0
long RawBinned[NUM_IMAGEPIXELS];
r = CLReadCCDBinned(c, RawBinned, 0, 1, 3);
cameraStatus(r, "CLReadCCDBinned");
r = CLWaitCompletion(c, 5000);
cameraStatus(r, "CLWaitCompletion");
#endif

if (CLisCameraReady(c) != CL_CAMERA_READY) {
printf("<camera not ready>");
}

r = CLSetExposure(c, 2);
cameraStatus(r, "CLSetExposure");
r = CLSetGain(c, 0);
cameraStatus(r, "CLSetGain");

#if 1
//r = CLReadCCDArea(c, NULL, 1, 0); // results one callback
r = CLReadCCDArea(c, NULL, 0, 0); // results in many callbacks
cameraStatus(r, "CLReadCCDArea");
#else
r = CLReadCCDBinned(c, NULL, NULL, 1, 0); // results in many callbacks, then "missed my noops"
cameraStatus(r, "CLReadCCDBinned");
#endif

for (int i = 0; i < 1000; ++i) {
r = CLGetGPIO(c);
CLClearCCD(c, 1, 0);
printf("\n<count=%d, GPIO=0x%x>", i, r);
Sleep(1000);
}
r = CLCloseCamera(c);
return 0;
}

void processHeartBeat(int c, HEARTBEAT_DATA* h) {
printf("<h%d>", h->errorByte);
}

void processImage(int c, tsImageData* i) {
printf("<i>");
}

void processError(int c, unsigned char severity, unsigned char code, char* str) {
printf("<SEVERITY:%d, %s>", severity, str);
}

void cameraStatus(int result, char* callerStr) {
if (result == CL_CAMERA_OK) {
printf("<%s>", callerStr);
} else {
printf("\n<ERROR: %s, %d>", callerStr, result);
}
}@

RE: Application does not receive callback from hardware trigger input - Added by Gary Scott almost 13 years ago

Following up with some code that may be useful to others. The image callback works with this code using GPIO line 1. The change from the above code was to make sure the BINCODE_SEND flag was set appropriately.
Note that this code will crash if you call CLGetGPIO() from within the callback function. We'll try signalling to another thread from within the callback to get around this limitation. Anyway, here's the C++ code:

@// mityccd.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "clcamiface.h"

extern "C" {
void processHeartBeat(int c, HEARTBEAT_DATA* h);
void processImage(int c, tsImageData* i);
void processError(int c, unsigned char severity, unsigned char code, char* str);
}

#define CAMERA_TRIGGER_LINE (1) //1
#define CAMERA_NO_TRIGGER_LINE (-1)
#define CAMERA_SYNC_LINE (0) // 0
#define CAMERA_ROWS (64)
#define CAMERA_COLUMNS (512)

#define NUM_IMAGEPIXELS (32)
#define ZERO_CLEARS (0)
#define PICTURES_PER_CYCLE (120)
#define EXPOSURE_TIME (0)

int c = -1; // Camera handle

void cameraStatus(int result, char* callerStr);

int _tmain(int argc, _TCHAR* argv[]) {
printf("hello");
c = CLOpenHSUSBCamera(0);
if (c < 0) {
printf("ERROR opening camera");
}
int r;
#if 0
// This takes too long for the camera to reboot.
r = CLCameraReset(c);
cameraStatus(r, "CLCameraReset");
Sleep(200);
#endif
r = CLEnableFan(c, 0);
cameraStatus(r, "CLEnableFan");
Sleep(200);
r = CLEnableFan(c, 1);
cameraStatus(r, "CLEnableFan");
r = CLSetCCDOffset(c, 200, 0);
cameraStatus(r, "CLSetCCDOffset");

// Set vertical binning
unsigned char verticalBins[CAMERA_ROWS];
for (int i = 0; i < CAMERA_ROWS; ++i) {
verticalBins[i] = BINCODE_BIN;
}
verticalBins[CAMERA_ROWS - 1] = BINCODE_SEND;
r = CLSetBinParam(c, verticalBins, 0);
cameraStatus(r, "CLSetBinParam");
// Set horizontal binning
unsigned char horizontalBins[CAMERA_COLUMNS];
int pixelsPerBin = CAMERA_COLUMNS / NUM_IMAGEPIXELS;
int index = 0;
for (int i = 0; i < NUM_IMAGEPIXELS; i++) {
for (int j = 0; j < pixelsPerBin - 1; j++) {
horizontalBins[index++] = BINCODE_SUM;
}
horizontalBins[index++] = BINCODE_SEND;
}
r = CLSetHorBinParam(c, horizontalBins, 0);
cameraStatus(r, "CLSetHorBinParam");

#if 0
r = CLSetGPIO(c, 1, eeINPUT);
r = CLSetGPIO(c, 2, eeINPUT);
r = CLSetGPIO(c, 3, eeINPUT);
#endif
r = CLSetGPIO(c, CAMERA_SYNC_LINE, eeINPUT);
cameraStatus(r, "CLSetGPIO");
r = CLSetGPIO(c, CAMERA_TRIGGER_LINE, eeINPUT);
cameraStatus(r, "CLSetGPIO");
r = CLSetTrigger(c, CAMERA_TRIGGER_LINE);
cameraStatus(r, "CLSetTrigger");

#if 0
int numSettings;
int currentSettings;
float gains[MAX_GAIN_SETTINGS ];
r = CLGetGainConfig(c, &numSettings, gains, &currentSettings);
cameraStatus(r, "CLGetGainConfig");
#endif

r = CLSetExposure(c, EXPOSURE_TIME);
cameraStatus(r, "CLSetExposure");
r = CLSetImageInterval(c, 0);
cameraStatus(r, "CLSetImageInterval");
//r = CLSetShutterParams(c, 0, 0, 1);
//cameraStatus(r, "CLSetShutterParams");

r = CLClearCCD(c, 1, 0);
cameraStatus(r, "CLClearCCD");
r = CLSetImageDataCallback(c, processImage);
cameraStatus(r, "CLSetImageDataCallback");

//r = CLSetHeartBeatCallback(c, processHeartBeat);
//cameraStatus(r, "CLSetHeartBeatCallback");
//r = CLSetErrorCallback(c, processError);
//cameraStatus(r, "CLSetErrorCallback");

#if 0
long RawBinned[NUM_IMAGEPIXELS];
r = CLReadCCDBinned(c, RawBinned, 0, 1, 3);
cameraStatus(r, "CLReadCCDBinned");
r = CLWaitCompletion(c, 5000);
cameraStatus(r, "CLWaitCompletion");
#endif

if (CLisCameraReady(c) != CL_CAMERA_READY) {
printf("<camera not ready>");
}

r = CLSetExposure(c, 2);
cameraStatus(r, "CLSetExposure");
r = CLSetGain(c, 0);
cameraStatus(r, "CLSetGain");

#if 0
//r = CLReadCCDArea(c, NULL, 1, ZERO_CLEARS); // results one callback
r = CLReadCCDArea(c, NULL, 0, ZERO_CLEARS); // results in many callbacks
cameraStatus(r, "CLReadCCDArea");

#else
r = CLReadCCDBinned(c, NULL, 0, PICTURES_PER_CYCLE, ZERO_CLEARS);
//r = CLReadCCDBinned(c, NULL, NULL, 1, ZERO_CLEARS); // results in many callbacks, then "missed my noops"
cameraStatus(r, "CLReadCCDBinned");
#endif

for (int i = 0; i < 1000; ++i) {
r = CLGetGPIO(c);
//CLClearCCD(c, 1, 0);
printf("\n<count=%d, GPIO=0x%x>", i, r);
Sleep(1000);
}
r = CLCloseCamera(c);
return 0;
}

void processHeartBeat(int c, HEARTBEAT_DATA* h) {
printf("<h%d>", h->errorByte);
}

void processImage(int c, tsImageData* i) {
static int callbackCount = 0;

printf("&lt;i=%d&gt;", callbackCount++);
//CLGetGPIO(c); // This call crashes the system
}

void processError(int c, unsigned char severity, unsigned char code, char* str) {
printf("<SEVERITY:%d, %s>", severity, str);
}

void cameraStatus(int result, char* callerStr) {
if (result CL_CAMERA_OK) {
if (callerStr NULL) {
printf("<OK>");
} else {
printf("\n<%s>", callerStr);
}
} else {
printf("\n<ERROR: %s, %d>", callerStr, result);
}
}
@

RE: Application does not receive callback from hardware trigger input - Added by Omar Rahim almost 13 years ago

It's best to avoid making calls to camera DLL functions from within the callback routine. The best approach is to setting a flag in the callback routine which gets checked (and processed) in a different thread.

    (1-4/4)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)