System designTroubleshooting

Chunk data exposure time error: enable the Image chunk first

Fix the chunk data exposure time error: enable the Image chunk first, then ExposureTime and Gain, set ChunkModeActive, and read ChunkExposureTime per frame.

LumaSpec Vision8 min read Share on LinkedIn

On this page 8 sections
  1. 01The symptom: decoding dies the moment chunk mode activates
  2. 02The rule: Image first, then each data chunk, then activate
  3. 03Read the exposure from the frame, not the register
  4. 04Worked example: an auto-exposure loop that trusts the frame
  5. 05Other faults that crash the same way
  6. 06When the usual answer is wrong
  7. 07Checklist before you call it done
  8. 08Questions

You enabled the ExposureTime chunk, set ChunkModeActive to True, and the first buffer fetch now dies with a KeyError on the pixel format — on a mono camera, KeyError: 'Mono8' — even though the same client showed images seconds earlier. The camera is fine and chunk data is allowed. The GenICam chunk layout turns the whole payload into a chunk stream, and the image itself is the Image chunk; enable a data chunk without it and the payload your client parses has no image where it expects one. Below: the enable order that fixes the crash, the nodes to read per frame, a worked auto-exposure loop with arithmetic, and the faults that fail the same way.

The symptom: decoding dies the moment chunk mode activates

Acquisition ran cleanly until you set ChunkSelector to ExposureTime, set ChunkEnable to True, and set ChunkModeActive to True. The next fetch throws inside payload construction, at the line that maps the payload's format value to a pixel-format name, and no image comes back. The trigger is enabling a data chunk without the image. The same failure appears across camera makers and across GigE and USB3 transports, which points at the payload layout the standard defines, not at one camera. Some clients raise it as buffer is smaller than requested size instead of a pixel-format KeyError.

The rule: Image first, then each data chunk, then activate

Three SFNC nodes work as a set. ChunkSelector picks one entry. ChunkEnable includes the selected chunk in the image payload, and it belongs to that selection — the same selector pattern every selector-based feature uses. ChunkModeActive switches the camera from plain image payloads to chunk payloads. Once chunk mode is active, the pixels travel as the Image entry, so leaving that entry disabled leaves the frame with no image component at all. The producer reports a chunk payload, a client built for plain images looks up a format value that is not a pixel format, and the lookup dies on the name.

The working sequence, in order:

  1. Stop acquisition.
  2. Set ChunkSelector to Image, then set ChunkEnable to True.
  3. Repeat select-and-enable for every data chunk you will read: ExposureTime, Gain, Timestamp.
  4. Set ChunkModeActive to True once, last.
  5. Start acquisition.
nm = acquirer.remote_device.node_map  # acquirer is your GenTL client's image acquirer

nm.ChunkSelector.value = 'Image'        # SFNC enumeration entry
nm.ChunkEnable.value = True             # include the selected chunk in the payload
nm.ChunkSelector.value = 'ExposureTime'
nm.ChunkEnable.value = True
nm.ChunkSelector.value = 'Gain'
nm.ChunkEnable.value = True
nm.ChunkModeActive.value = True         # activate chunk mode after the entries

nm and acquirer are illustrative names; the node names are the standard's. Writing values through a node map this way is the pattern setting camera exposure time through a GenICam API in Python walks through in detail.

Read the exposure from the frame, not the register

Every enabled chunk rides inside the buffer. After a fetch, your client's chunk parser writes the values into the device node map's Chunk* nodes, so ChunkExposureTime.value is the exposure of the frame in your hand — in microseconds, the same unit as ExposureTime. ChunkGain.value is in decibels. Under auto exposure this is the only trustworthy source, because a register read between frames belongs to no frame in particular; that argument is made in reading exposure from frame metadata under auto exposure and in per-frame exposure and gain: verifying camera metadata.

buffer = acquirer.fetch_buffer()          # fetch first: the parser runs on this buffer
exposure_us = nm.ChunkExposureTime.value  # µs, from the buffer just fetched
gain_db = nm.ChunkGain.value              # dB, from the buffer just fetched

ChunkTimestamp gives the camera's time at exposure end; chunk data timestamps and how to latch them covers using them for frame timing.

Worked example: an auto-exposure loop that trusts the frame

The loop below runs on the host and works with any of the area scan cameras that expose a GenICam node map. As the camera, take the MV-CS200-10UM, a 20 MP USB3 area scan camera with a 1" sensor and C-mount, or the LS-CMR-0166, a 12 MP USB3 camera at 30 fps with 4000 × 3000 resolution. For host-side exposure control, any of these streams into a GenTL client:

Area scan camerasHikrobot MV-CS200-10UM 20 MP Area Scan Camera, USB3.0, IMX183, 2nd Gen., MonoMV-CS200-10UM
Sensor format
1"
Lens mount
C-mount
$759.00View part
Area scan cameras12 MP USB3 area scan camera, IMX226, 1/1.7" rolling shutter, 30 fps, 4000 × 3000 resolution (LS-CMR-0166)LS-CMR-0166
Sensor format
1/1.7"
Interface
USB3
$560.00View part
Area scan camerasHikrobot MV-CU020-90GC 2.5 MP Area Scan Camera, GigE, GMAX4002, ColorMV-CU020-90GC
Sensor format
1/1.7"
Lens mount
C-mount
$309.00View part

Two USB3 candidates side by side:

Specification MV-CS200-10UM LS-CMR-0166
Sensor model Sony® IMX183 Sony IMX226
Pixel size 2.4 μm × 2.4 μm 1.85 μm
Sensor size 1" 1/1.7"
Resolution 5472 × 3648 4000 × 3000 (12MP)
Max. frame rate 19.2 fps @ 5472 × 3648 Mono 8 30 fps
Data interface USB3.0, compatible with USB2.0 USB 3.0
Price $759.00 $560.00

Values as printed in each product's data sheet; open a part for its drawing and full specifications.

Now the numbers, with the loop constants as an example. The target is a mean gray of 128 on an 8-bit image. One frame measures a mean of 110 while ChunkExposureTime reads 8000 µs, so 8 ms produced that image. Gray mean scales with exposure while the sensor stays linear and unsaturated, so:

new_exposure = current_exposure × target_mean / measured_mean new_exposure = 8.0 ms × 128 / 110 = 9.31 ms → write 9309 µs

At 30 fps the frame period is 1000 ms / 30 = 33.3 ms. Exposure changes are not instant: in one reported case a camera needed about 200 ms to move from 11 ms to 12 ms while streaming, which is 200 / 33.3 ≈ 6 frames before the new value reaches the metadata. Two decisions follow. Correct every 8 to 10 frames, not every frame, and treat the register write as a request whose confirmation arrives in ChunkExposureTime.

The test that proves the pipeline: with auto exposure off and ExposureTime written to 9309 µs, the next fetched frame reads ChunkExposureTime 9309 µs and its mean climbs from 110 toward 128. A register that says 9.31 ms while the chunk still reads 8000 µs means the change has not landed, or you read before the fetch. When exposure reaches ExposureTime.max, stop raising it and raise gain instead.

Other faults that crash the same way

Four faults produce the same crash or its close cousins, ordered by how often each one bites:

Symptom Likely cause Test Fix
Pixel-format KeyError right after ChunkModeActive The Image entry was never enabled Set ChunkSelector to Image and read ChunkEnable back Enable Image, restart acquisition
Crash persists with Image enabled Client release predates chunk-payload parsing Turn chunks off; plain images decode again Update the GenTL client to a current release
buffer is smaller than requested size Buffers were announced before the payload grew Compare payload size with chunks off and on Configure chunks before acquisition starts
ChunkEnable write refused mid-stream Chunk nodes are locked while acquiring Stop acquisition, retry the write Configure while idle, then start

The last row is why order matters as much as values; set manual exposure before streaming: initialization order applies the same discipline to exposure itself.

When the usual answer is wrong

Not every node map is identical. Print ChunkSelector's valid entries before setting it — check GenICam enumeration symbolics before you set them is the habit, and set a GenICam enumeration by integer value is the fallback when a producer accepts only numbers. If the payload decodes but the image is wrong — no color, strange layout — you have a pixel-format problem, not a chunk problem; fix the GigE camera pixel-format default is the right track.

Cameras with a sequencer can alternate exposure and gain per frame and stamp both, which replaces half of a host-side loop; see camera sequencer control: alternating exposure and gain per frame. On smart cameras that run inspection on the device, ChunkModeActive may be absent from the node map: no node, no feature, and exposure logging belongs on the device side.

Checklist before you call it done

  • All chunk writes made with acquisition stopped.
  • Image enabled first, plus every data entry you plan to read.
  • ChunkModeActive set once, last.
  • The first fetched buffer decodes at the expected width and height.
  • With auto exposure off, ChunkExposureTime equals the ExposureTime you wrote.
  • Writes clamped between ExposureTime.min and ExposureTime.max, gain raised only after exposure maxes out.

To pick the hardware for this pipeline, filter by interface and mount in the camera finder or start at the camera step of the system configurator. If a camera's node map refuses the sequence above, send us its chunk-related nodes through the contact page and we will name the entries it implements.

Questions

Do I always have to enable the Image chunk?

Yes, on any camera that follows the GenICam chunk payload layout. ChunkModeActive turns the whole frame into a chunk stream, and the pixels travel in the Image entry. Leave it out and the client has no image component to decode, whatever other chunks you enabled. Enable Image first, then the data chunks you plan to read, then activate.

Why does ChunkExposureTime still show the old value after I write ExposureTime?

Two reasons. The Chunk nodes describe the last buffer you fetched, so fetch again before reading. And cameras apply a new exposure slowly: in one reported case a camera needed about 200 ms to move from 11 ms to 12 ms while streaming, roughly six frames at 30 fps. Treat the chunk value as the truth and the register write as a request.

What units are ChunkExposureTime and ChunkGain in?

ChunkExposureTime is in microseconds, the same base unit as ExposureTime, so 8000 means 8 ms; divide by 1000 in your loop math. ChunkGain is in decibels. Clamp every write to the range between the node's minimum and maximum before sending it, or the camera refuses the write.

Does enabling chunk data cost frame rate?

Nothing you can measure. Each enabled chunk adds tens of bytes per frame; against a 4000 × 3000 mono frame, which is 12 MB of pixels, the overhead is a rounding error. The real risk is a client that must re-announce buffers when the payload size changes, so configure chunks once, before acquisition starts.

Can I enable chunks while the camera is acquiring?

No. On most cameras the chunk nodes are writable only while acquisition is stopped, and changing the payload size mid-stream is what produces buffer-size errors. Stop, configure, start. If a ChunkEnable write is refused during acquisition, that lock is the reason, not a bug in your sequence.