Exposure time is the first setting you change when a machine vision image is too dark or a moving part blurs, and on a GenICam-standard camera it is also one of the easiest to set from code. Every GigE Vision and USB3 Vision camera we sell carries the same standard feature names, so one Python sequence — open the camera, disable auto exposure, write ExposureTime, read it back — works across models and interfaces. This how-to shows the full sequence, the errors you meet when you skip a step, and how to confirm the value the camera actually used per frame. For what exposure does to the image, read industrial camera image quality settings: exposure, gain, balance first.
What you need
- A GenICam-compliant area scan camera over GigE Vision or USB3 Vision, for example a GigE model such as the LS-CMR-0053 or a USB3 model such as the LS-CMR-0166.
- A Python GenICam transport library or the vendor SDK's Python binding; any of them exposes the same feature nodes described by the camera's XML device description.
- A short camera data cable run — a 3 m high-flex cable like the LS-CBL-0199 is typical for a bench set-up.
- A way to see readback values: a print statement is enough; chunk-data metadata is better.
The feature nodes involved
GenICam cameras describe every controllable setting as a node in an XML register map. Four nodes matter for exposure:
-
ExposureMode—Timed(sensor integrates for the set time),TriggerWidth(exposure follows the trigger pulse length) orOff. -
ExposureAuto—Off,OnceorContinuous. -
ExposureTime— the target in microseconds, withMin,MaxandInc(increment) properties. -
ExposureTimeRaw/ExposureTimeBaseAbs— an older integer style where the effective time is raw × base.
If a node you expect is missing, the naming varies by firmware generation; see GenICam exposure feature discovery for missing attributes for how to enumerate what the camera actually publishes.
Set the exposure time: step by step
- Discover and open the device. Most cameras keep their feature map read-only until the transport is open. Opening also claims exclusive access where the transport enforces it.
cam = tl.CreateFirstDevice()
cam.Open()
- Set ExposureMode to Timed. Without this the exposure may follow a trigger pulse width and ignore your value entirely.
cam.ExposureMode.SetValue("Timed")
-
Disable auto exposure. Write
ExposureAuto = Offbefore touching the time. WithContinuousthe auto loop overwrites you every frame; withOnceit overwrites you until its cycle finishes.
cam.ExposureAuto.SetValue("Off")
-
Read the valid range and increment. The maximum depends on your current frame rate, so do this after setting
AcquisitionFrameRate. Clamp your target to[Min, Max]and snap it toInc:
lo = cam.ExposureTime.GetMin()
hi = cam.ExposureTime.GetMax()
inc = cam.ExposureTime.GetInc()
target = min(max(1000.0, lo), hi)
target = round(target / inc) * inc
- Write the value in microseconds.
cam.ExposureTime.SetValue(1000) # 1 ms
cam.Close()
The open-set-close order matters: writing before Open() fails on most transports, and leaving the camera open blocks other tools from testing it. If a saved user set restores old values at startup and your limit is ignored, the diagnosis in auto exposure upper limit not applied: check startup settings applies to manual values too.
Verify the applied value per frame
A successful SetValue call only means the register accepted the number. To confirm what each image used, enable chunk data and read exposure from the frame metadata:
- Set
ChunkModeActive = True. - Enable
ChunkSelector = ExposureTime(andChunkEnable = Truefor each selector you want). - Grab a frame and read the chunk value attached to the buffer.
The workflow, pitfalls and metadata cross-checks are the subject of per-frame exposure and gain: verifying camera metadata. If you trigger from hardware instead of free-running, combine this with hardware triggered image acquisition in Python so the exposure, trigger and grab sequencing line up.
Choosing a sensible value
Two limits pick the number for you:
Worked example: a part moves at 200 mm/s across a field where one pixel covers 0.05 mm, and you tolerate 1 pixel of blur. Allowed blur is 0.05 mm, so exposure must be under 0.05 / 200 = 0.25 ms = 250 µs. Start at 250 µs; if the histogram peaks below 40% of full scale, widen the lighting or the aperture before adding gain. For the trade-off between exposure and shutter terminology, see exposure time vs shutter speed for moving-part inspection.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
SetValue raises a range error |
Value outside Min–Max, or not a multiple of Inc | Clamp and snap to Inc as in step 4 |
| Value applied, then drifts | ExposureAuto still Once or Continuous | Set ExposureAuto Off first |
| Write protected / access error | Camera not opened, or another client holds it | Open before writing; close other tools |
| Exposure ignored in trigger mode | ExposureMode is TriggerWidth | Set ExposureMode Timed |
| Frame rate drops after writing | Exposure exceeds the frame period | Shorten exposure or lower the frame rate first |
| Node name not found | Firmware uses ExposureTimeAbs or Raw naming | Enumerate nodes; see the feature discovery article |
If writes fail only after the camera reconnects mid-session, that is a lock-state problem, not an exposure problem — camera feature write-protect errors after reconnection covers it.
Before you order or integrate
- Check the camera's minimum exposure if you need to freeze fast motion or use a strobed light: a minimum of tens of microseconds is normal, and strobe on-time must fit inside it. For matching strobe pulse width to exposure control, this strobe on-time configuration guide goes deeper.
- Confirm the exposure you need fits your target frame rate: divide 1,000,000 by the frame rate to get the frame period in microseconds, and keep exposure below it.
- Prefer cameras whose SDK documents chunk-data exposure so verification is possible in production, not just at set-up.
- Use a stable mount for the benchmark — a camera stand removes hand-held variance while you tune values.
When you have the number, run the whole sequence — open, auto off, set, verify — through the camera finder on the model you plan to use, or start at the camera step of the system configurator to build the complete set. If a specific camera's feature names puzzle you, contact our support team with the model number.
Quick checklist
- Open the camera before writing any feature.
-
ExposureMode = Timed. -
ExposureAuto = OffbeforeExposureTime. - Clamp to Min/Max and snap to Inc after setting the frame rate.
- Write in microseconds.
- Read back the value; verify per frame with chunk data.
- Close the camera when the tuning tool exits.
Set the value once, verify it every frame, and exposure stops being a mystery in your pipeline.
Questions
Why do I have to disable ExposureAuto before setting the exposure time?
While ExposureAuto is set to Once or Continuous, the camera's auto exposure loop keeps rewriting the exposure every frame or cycle, so your value is either rejected or silently overwritten a few frames later. Set ExposureAuto to Off first, then write ExposureTime. If you use Once, wait until the auto cycle completes before writing your value, otherwise the result depends on timing.
What units does the GenICam ExposureTime feature use?
Microseconds, per the GenICam standard feature naming convention. A value of 100000 means 100 ms. The related ExposureTimeAbs name appears on some older firmwares and means the same thing. Some interfaces also expose ExposureTimeRaw, an integer in units defined by ExposureTimeBaseAbs; convert before comparing values across those two styles.
Why does the camera reject my exposure value with a range error?
Every camera publishes a minimum and maximum exposure, and the maximum also shrinks at high frame rate because the exposure must fit inside the frame period. Read ExposureTime.Min and ExposureTime.Max after configuring the frame rate, then clamp your target. Asking for 100 ms at 60 fps cannot work, since the frame period is only about 16.7 ms.
How can I confirm the exposure was really applied to the frames I am analysing?
Read the value back with ExposureTime.GetValue immediately after writing it, and where the camera supports it, enable per-frame chunk data and read ExposureTime from each image's metadata. That catches cases where a saved user set or startup default overrides your setting. We cover that check in the article on verifying per-frame exposure and gain from camera metadata.
Does the same code work for GigE and USB3 cameras?
Yes, as long as both follow the GenICam standard feature names and you open them through an interface that maps those features. The feature access sequence — open, ExposureAuto Off, ExposureTime set, readback — is identical; only device discovery and transport settings such as packet size or bandwidth allocation differ between GigE Vision and USB3 Vision.