Skip to content

Instantly share code, notes, and snippets.

@gebi
Last active May 28, 2021
Embed
What would you like to do?
Fixed up LiveFrameSample from QHYCCD SDK

Short summary of QHY462C Problems under Linux

After a bit of debugging it seems the problems are not related to firecapture for the QHY5III462C camera:

  • cam freeze after a short period of time
  • only 30 fps

Test environment

  • Lenovo T480 laptop on usb3 ports without hub
  • Linux Kernel 5.10
  • libusb package version 2:1.0.24-3
  • Distribution: Debian amd64

Tested with the following qhyccd sdk versions:

  • sdk_linux64_21.02.01
  • sdk_linux64_21.03.13

Debugging the freezing

This helped to make it work for more than a few frames, though still breaks down after a few seconds:

echo 200 >/sys/module/usbcore/parameters/usbfs_memory_mb

Though, after a single stalled libusb transfer the only thing to get the camera working again is plugging it in again. This means it's "dead"

QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_STALL

I debugged it via modifying the testapp/LiveFrameMode example from the SDK to compile on a modern linux and make it actually show more than one frame. (I've uploaded the code for people who need it here: https://gist.github.com/gebi/f85de8444d81961fb432d3fa1f23ddeb )

Then set debug output to true in qhyccd.ini

[debug]
debugOutPut = true

Partial log (full log attached)

QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>3.1.0  14020 >= 4  sig=-755884904 sigLen=4
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|sigDetected = true the usb pack length =14020
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen = 2143940 2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>2.1.0  2143940 = (4+2143936+0) =2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>2.1.1  2143940 = (4+2143936+0) =2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|*RawDataLen = 2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|frameLen = 2143936
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|cydev[index].rawFrameHeight = 1112
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|cydev[index].rawFrameWidth = 1928
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|imagequeue.GetDataLen() 2143936 frameLen 2143936
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>2.1.3
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|imagequeue.GetDataLen() 2143936 frameLen 2143936
QHYCCD|UNLOCKIMAGEQUEUE.CPP|Put.1|f len 20b6c0   2143936      m_nSize = 16777216   m_nIn = 57886272   m_nOut = 55742336
QHYCCD|UNLOCKIMAGEQUEUE.CPP|Put.2| len 20b6c0  2143936      m_nSize = 16777216   m_nIn = 60030208   m_nOut = 55742336
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|put image data to imagequeue
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>2.1.5
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>3.1.0  4 >= 4  sig=-755884904 sigLen=4
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|sigDetected = true the usb pack length =4
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen = 4 2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen =================================>2.1.0  4 = (4+2143936+0) =2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen = 16384 2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen = 32768 2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen = 49152 2143940
QHYCCDRD|CMOSDLL.CPP|QCamImageParsing|RawDataLen = 65536 2143940
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_STALL
QHYCCD|QHY5IIIBASE.CPP|GetLiveFrame|*pW,*pH,*bBpp,*pChannels 1920 1080 8 1
QHYCCD|CMOSDLL.CPP|ReadAsyQCamLiveFrame 4287872 >= 2143936
QHYCCD|CMOSDLL.CPP|ReadAsyQCamLiveFrame| END  SUCCESS
QHYCCD|UNLOCKIMAGEQUEUE.CPP|Put|Get len 20b6c0
QHYCCD|QHY5IIIBASE.CPP|GetLiveFrame|GetLiveFrame ret=2143936 chipoutputsizex * chipoutputsizey * chipoutputbits_t / 8=137211904
QHYCCD|3A QHY5IIIBASE.CPP|GetLiveFrame|readnum,badframenum 1 0
QHYCCD|QHY5IIIBASE.CPP|GetLiveFrame|no debayer
QHYCCD|QHY5IIIBASE.CPP|GetLiveFrame|GetLiveFrame pW=1920 pH=1080 pBpp=8 pChannels=1
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|LIBUSBIO.CPP|asyImageDataCallBack|LIBUSB_TRANSFER_ERROR
QHYCCD|QHY5IIIBASE.CPP|GetLiveFrame|*pW,*pH,*bBpp,*pChannels 1920 1080 8 1
QHYCCD|CMOSDLL.CPP|ReadAsyQCamLiveFrame 2143936 >= 2143936
QHYCCD|CMOSDLL.CPP|ReadAsyQCamLiveFrame| END  SUCCESS
QHYCCD|UNLOCKIMAGEQUEUE.CPP|Put|Get len 20b6c0

I'm at a bit of a loss here, seems really like some problem with the transfer, then the camera does not recognize the cmd and then there is the error recovering missing in the lib and possible cam firmware to get it working again 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <qhyccd.h>
#include <sys/time.h>
//#define OPENCV_SUPPORT
#ifdef OPENCV_SUPPORT
#include <opencv2/core/types_c.h>
#include <opencv2/highgui/highgui_c.h>
#endif
void SDKVersion()
{
unsigned int YMDS[4];
unsigned char sVersion[80];
memset ((char *)sVersion,0x00,sizeof(sVersion));
GetQHYCCDSDKVersion(&YMDS[0],&YMDS[1],&YMDS[2],&YMDS[3]);
if ((YMDS[1] < 10)&&(YMDS[2] < 10))
{
sprintf((char *)sVersion,"V20%d0%d0%d_%d\n",YMDS[0],YMDS[1],YMDS[2],YMDS[3] );
}
else if ((YMDS[1] < 10)&&(YMDS[2] > 10))
{
sprintf((char *)sVersion,"V20%d0%d%d_%d\n",YMDS[0],YMDS[1],YMDS[2],YMDS[3] );
}
else if ((YMDS[1] > 10)&&(YMDS[2] < 10))
{
sprintf((char *)sVersion,"V20%d%d0%d_%d\n",YMDS[0],YMDS[1],YMDS[2],YMDS[3] );
}
else
{
sprintf((char *)sVersion,"V20%d%d%d_%d\n",YMDS[0],YMDS[1],YMDS[2],YMDS[3] );
}
fprintf(stderr,"QHYCCD SDK Version: %s\n", sVersion);
}
void FirmWareVersion(qhyccd_handle *h)
{
int i = 0;
unsigned char fwv[32],FWInfo[256];
unsigned int ret;
memset (FWInfo,0x00,sizeof(FWInfo));
ret = GetQHYCCDFWVersion(h,fwv);
if(ret == QHYCCD_SUCCESS)
{
if((fwv[0] >> 4) <= 9)
{
sprintf((char *)FWInfo,"Firmware version:20%d_%d_%d\n",((fwv[0] >> 4) + 0x10),
(fwv[0]&~0xf0),fwv[1]);
}
else
{
sprintf((char *)FWInfo,"Firmware version:20%d_%d_%d\n",(fwv[0] >> 4),
(fwv[0]&~0xf0),fwv[1]);
}
}
else
{
sprintf((char *)FWInfo,"Firmware version:Not Found!\n");
}
fprintf(stderr,"%s\n", FWInfo);
}
int main(int argc,char *argv[])
{
int num = 0;
qhyccd_handle *camhandle;
int ret;
char id[32];
//char camtype[16];
int found = 0;
unsigned int w,h,bpp,channels;
unsigned char *ImgData;
//int camtime = 10000,camgain = 0,camspeed = 2,cambinx = 1,cambiny = 1;
SDKVersion();
ret = InitQHYCCDResource();
if(ret == QHYCCD_SUCCESS)
{
printf("Init SDK success!\n");
}
else
{
goto failure;
}
num = ScanQHYCCD();
if(num > 0)
{
printf("Yes!Found QHYCCD,the num is %d \n",num);
}
else
{
printf("Not Found QHYCCD,please check the usblink or the power\n");
goto failure;
}
for(int i = 0;i < num;i++)
{
ret = GetQHYCCDId(i,id);
if(ret == QHYCCD_SUCCESS)
{
printf("connected to the first camera from the list,id is %s\n",id);
found = 1;
break;
}
}
if(found == 1)
{
camhandle = OpenQHYCCD(id);
if(camhandle != NULL)
{
printf("Open QHYCCD success!\n");
}
else
{
printf("Open QHYCCD failed \n");
goto failure;
}
FirmWareVersion(camhandle);
// check camera support live frame
ret = IsQHYCCDControlAvailable(camhandle, CAM_LIVEVIDEOMODE);
if (QHYCCD_ERROR == ret)
{
printf("The detected camera is not support live frame.\n");
// release sdk resources
ret = ReleaseQHYCCDResource();
if (QHYCCD_SUCCESS == ret)
{
printf("SDK resources released.\n");
}
else
{
printf("Cannot release SDK resources, error %d.\n", ret);
}
return 1;
}
ret = SetQHYCCDStreamMode(camhandle,1);
ret = InitQHYCCD(camhandle);
if(ret == QHYCCD_SUCCESS)
{
printf("Init QHYCCD success!\n");
}
else
{
printf("Init QHYCCD fail code:%d\n",ret);
goto failure;
}
double chipw,chiph,pixelw,pixelh;
ret = GetQHYCCDChipInfo(camhandle,&chipw,&chiph,&w,&h,&pixelw,&pixelh,&bpp);
if(ret == QHYCCD_SUCCESS)
{
printf("GetQHYCCDChipInfo success!\n");
printf("CCD/CMOS chip information:\n");
printf("Chip width %3f mm,Chip height %3f mm\n",chipw,chiph);
printf("Chip pixel width %3f um,Chip pixel height %3f um\n",pixelw,pixelh);
printf("Chip Max Resolution is %d x %d,depth is %d\n",w,h,bpp);
}
else
{
printf("GetQHYCCDChipInfo fail\n");
goto failure;
}
ret = IsQHYCCDControlAvailable(camhandle,CONTROL_TRANSFERBIT);
if(ret == QHYCCD_SUCCESS)
{
ret = SetQHYCCDBitsMode(camhandle,8);
if(ret != QHYCCD_SUCCESS)
{
printf("SetQHYCCDParam CONTROL_GAIN failed\n");
getchar();
return 1;
}
}
ret = SetQHYCCDResolution(camhandle,0,0,w,h);
if(ret == QHYCCD_SUCCESS)
{
printf("SetQHYCCDResolution success!\n");
}
else
{
printf("SetQHYCCDResolution fail\n");
goto failure;
}
ret = BeginQHYCCDLive(camhandle);
if(ret == QHYCCD_SUCCESS)
{
printf("BeginQHYCCDLive success!\n");
}
else
{
printf("BeginQHYCCDLive failed\n");
goto failure;
}
int length = GetQHYCCDMemLength(camhandle);
printf("GetQHYCCDMemLength = %d\n", length);
if(length > 0)
{
ImgData = (unsigned char *)malloc(length);
memset(ImgData,0,length);
}
else
{
printf("Get the min memory space length failure \n");
goto failure;
}
int t_start,t_end;
t_start = time(NULL);
int fps = 0;
#ifdef OPENCV_SUPPORT
IplImage *img = NULL;
cvNamedWindow("show", CV_WINDOW_AUTOSIZE);
#endif
ret = QHYCCD_ERROR;
//while(ret != QHYCCD_SUCCESS)
while(true)
{
ret = GetQHYCCDLiveFrame(camhandle,&w,&h,&bpp,&channels,ImgData);
if(ret == QHYCCD_SUCCESS)
{
#ifdef OPENCV_SUPPORT
if(img == NULL)
{
img = cvCreateImageHeader(cvSize(w,h),bpp,1);
img->imageData = (char *)ImgData;
}
cvShowImage("show",img);
cvWaitKey(30);
#endif
fps++;
t_end = time(NULL);
if(t_end - t_start >= 5)
{
printf("fps = %d\n",fps / 5);
fps = 0;
t_start = time(NULL);
}
}
}
delete(ImgData);
}
else
{
printf("The camera is not QHYCCD or other error \n");
goto failure;
}
if(camhandle)
{
StopQHYCCDLive(camhandle);
ret = CloseQHYCCD(camhandle);
if(ret == QHYCCD_SUCCESS)
{
printf("Close QHYCCD success!\n");
}
else
{
goto failure;
}
}
ret = ReleaseQHYCCDResource();
if(ret == QHYCCD_SUCCESS)
{
printf("Rlease SDK Resource success!\n");
}
else
{
goto failure;
}
return 0;
failure:
printf("some fatal error happened\n");
return 1;
}
# Makefile for zlib, derived from Makefile.dj2.
# Modified for mingw32 by C. Spieler, 6/16/98.
# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
# Last updated: Mar 2012.
# Tested under Cygwin and MinGW.
# Copyright (C) 1995-2003 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile, or to compile and test, type from the top level zlib directory:
#
# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
#
# To use the asm code, type:
# cp contrib/asm?86/match.S ./match.S
# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
#
# To install libz.a, zconf.h and zlib.h in the system directories, type:
#
# make install -fwin32/Makefile.gcc
#
# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
#
# To install the shared lib, append SHARED_MODE=1 to the make command :
#
# make install -fwin32/Makefile.gcc SHARED_MODE=1
# Note:
# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
# the DLL name should be changed from "zlib1.dll".
EXEC = LiveFrameSample
#
# Set to 1 if shared object needs to be installed
#
SHARED_MODE=0
COMP_INC1 = /usr/include/
COMP_INC2 = ../../include
COMP_LIB = /usr/local/lib/
QHY_LIB = ../../lib/libqhyccd.so
CXX = g++
CXXFLAGS = -Wall -Wsign-compare -std=c++11 -I. -I $(COMP_INC1) -I$(COMP_INC2) -I/usr/include/opencv4 -DOPENCV_SUPPORT
EXTRALIBS = -Wl,${QHY_LIB} -lusb-1.0 -lopencv_core -lopencv_highgui -pthread
CP = cp -f
OBJA = LiveFrameSample.o
all: $(EXEC)
.cpp.o:
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(EXEC): $(OBJA)
$(CXX) -o LiveFrameSample $(OBJA) $(EXTRALIBS)
install:
# $(CP) $(EXEC)
clean:
-$(RM) $(EXEC)
-$(RM) *.o
-$(RM) *~
-$(RM) *.orig
; SDK settings file, you Can Ignore this file ,it not necessary.
[image] ; image process
name = imageName pat ; Spaces around '=' are stripped
reverseX=false ; reverse
reverseY=false ; reverse
[debug]
debugOutPut = false ;set it to true if you need debug info, and will lose some performance
is_test_sdk = false ;keep it false
beep_all = false ;set beep_all=true to produce a beep sound single frame exp and read actions
[user_config]
turn_off_ddr_after_conn = false ;some software do not have full camera settings, can do here
#!/bin/bash
LD_LIBRARY_PATH=../../lib/ exec ./LiveFrameSample
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment