I'm developing an INDI client to run a DMK CCD from The Imaging Source (a video 4 linux compatible camera) and noticed a bug in the v4l2driver that I am unable to take non-integer exposure times. For instance, I set the element CCD_EXPOSURE_VALUE (in property CCD_EXPOSURE) to 0.5 and it results in Exposure (Absolute) being set to 0 and a 0 second exposure. If I set CCD_EXPOSURE_VALUE to 1.5, it seets Exposure (Absolute) to 10000 and takes a 1 second exposure.
I looked through your source code and found out where the problem is. In drivers/video/v4ldriver.h, in your struct img_t, you define expose to be an int. Then in v4l2driver.cpp, in method V4L2_Driver::ISNewNumber, you set V4LFrame->expose = values[0]; where V4LFrame is a struct of type img_t. This implicitly casts values[0], which is a double, and the value input into CCD_EXPOSURE_VALUE, as an int, truncating the value. After this, you call rc = setManualExposure(V4LFrame->expose);. The method setManualExposure already takes a double (duration) as its argument and sets AbsExposureN->value = duration * 10000; where AbsExposureN is the Exposure (Absolute) element and the actual exposure time in 1/10000s of a second sent to the CCD.
Therefore to me it looks like this issue would be completely fixed by simply changing expose from an into to a double in the struct img_t. Thanks!
Craig Warner
University of Florida
*from an int to a double
v4ldriver.h is used only by legacy V4L1 drivers. indi_v4l2_ccd driver (which is used for DMK) uses v4l2driver.h which already has exposre as double. What driver are you using with your DMK?
Hmm, you're right about that. Somehow its being cast as an int somewhere else then. I'm using the v4l2_ccd driver:
indiserver -vvv indi_lx200gps indi_v4l2_ccd
Here is some output from very very verbose mode showing the problem:
set CCD_EXPOSURE_VALUE = 1.5
2014-11-07T21:14:14: Client 0: read newNumberVector V4L2 CCD CCD_EXPOSURE
CCD_EXPOSURE_VALUE='1.5'
2014-11-07T21:14:14: Driver indi_v4l2_ccd: queuing responsible for <newnumbervector device="V4L2 CCD" name="CCD_EXPOSURE">
2014-11-07T21:14:14: Client 8: queuing <newnumbervector device="V4L2 CCD" name="CCD_EXPOSURE"></newnumbervector></newnumbervector>
Image header shows EXPTIME = 1.5
EXPTIME = 1.5 / Total Exposure Time (s)
However it sets Exposure (Absolute) to 10000:
2014-11-07T21:14:14: Driver indi_v4l2_ccd: read defNumberVector V4L2 CCD Image Adjustments Idle rw
Brightness='0'
Gamma='100'
Gain='260'
Exposure (Absolute)='10000'
2014-11-07T21:14:14: Client 0: queuing <defnumbervector device="V4L2 CCD" name="Image Adjustments">
....
2014-11-07T21:14:14: Client 8: sending msg copy 1 nq 28:
<newnumbervector device="V4L2 CCD" name="CCD_EXPOSURE">
<onenumber name="CCD_EXPOSURE_VALUE">
1.5
</onenumber>
</newnumbervector>
....
2014-11-07T21:14:14: Client 8: sending msg copy 1 nq 20:
<defnumbervector device="V4L2 CCD" name="Image Adjustments" label="" group="V4L2 Control" state="Idle" perm="rw" timeout="60" timestamp="2014-11-07T21:14:14">
<defnumber name="Brightness" label="Brightness" format="%0.f" min="0" max="63" step="1">
0
</defnumber>
<defnumber name="Gamma" label="Gamma" format="%0.f" min="1" max="500" step="1">
100
</defnumber>
<defnumber name="Gain" label="Gain" format="%0.f" min="260" max="1023" step="1">
260
</defnumber>
<defnumber name="Exposure (Absolute)" label="Exposure (Absolute)" format="%0.f" min="1" max="36000000" step="1">
10000
</defnumber>
</defnumbervector></defnumbervector>
The actual counts are the same level as when I do a 1 second exposure (and half that of when I take a 2 second exposure) so it definitely exposed for the time contained in Exposure (Absolute). I'll continue to look through the code to see if I can figure out where it is getting cast as an int. For the record, here's the version I'm using:
INDI Library: 0.9.8
Code $Revision: 726523 $. Protocol 1.7.
Thanks!