Application does not receive callback from hardware trigger input
Added by Omar Rahim over 12 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, ¤tSettings); 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 over 12 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 over 12 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, ¤tSettings);
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 over 12 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, ¤tSettings);
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("<i=%d>", 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 over 12 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.