Hi all, I’m trying to get manual white balance and exposure control working on an Arducam CSI-USB UVC adapter board (B0278) with the 12MP IMX477 HQ camera on a Jetson. My goal is to set white balance and exposure from code, but so far I never got it to work. I’ve already tried opencv-python (CAP_PROP_WHITE_BALANCE_BLUE_U / RED_V, CAP_PROP_EXPOSURE, etc.) and the v4l2-ctl commands under Linux. The camera streams fine, but the parameters don’t seem to change the image at all. Any guidance on a way to control these manually would be appreciated.
Thanks for the details. Can you share a bit more about your environment? Which JetPack/L4T version are you on, and how does the adapter enumerate? Please run:
v4l2-ctl --list-devices
and
v4l2-ctl -d /dev/video0 --all
and paste the output, especially the UVC controls section. Also, which exact v4l2-ctl commands did you already try?
I’m on JetPack 5.1.2, and the camera shows up on /dev/video0 as something like ‘Arducam IMX477’. I tried:
v4l2-ctl -d /dev/video0 -c white_balance_temperature_auto=0
v4l2-ctl -d /dev/video0 -c white_balance_temperature=4500
v4l2-ctl -d /dev/video0 -c exposure_auto=1
v4l2-ctl -d /dev/video0 -c exposure_absolute=100
The commands run without error, but the image doesn’t change. OpenCV set() sometimes returns true, but the frame looks identical.
Interesting. First let’s confirm the controls actually exist and check their current state. Run:
v4l2-ctl -d /dev/video0 --list-ctrls
v4l2-ctl -d /dev/video0 --list-ctrls-menus
Sometimes with these UVC adapters the auto controls need to be disabled in a specific order, and some controls are only exposed through an extension unit. Can you paste the output?
Here’s the relevant part of the output:
white_balance_temperature_auto (bool): default=1 value=1
white_balance_temperature (int): min=2800 max=6500 step=1 default=4600 value=4600
exposure_auto (menu): min=0 max=3 default=0 value=0
exposure_absolute (int): min=3 max=2047 step=1 default=156 value=156
I set white_balance_temperature_auto=0, then set white_balance_temperature=3500. v4l2-ctl reports the new value when I query it, but the stream doesn’t change at all. Same for exposure. It’s like the values are accepted but ignored.
That confirms the controls are being advertised. ‘Accepted but ignored’ usually means the UVC control is mapped on the host side but not actually applied to the sensor. Can you check whether the value sticks after a stream restart, and capture with something like:
v4l2-ctl -d /dev/video0 --set-ctrl=white_balance_temperature_auto=0 --set-ctrl=white_balance_temperature=3500 --stream-mmap --stream-count=1 --stream-to=test.jpg
Then compare the captured frame against an auto one. Also, does guvcview or qv4l2 show the controls having any effect?
Tried that. The value does stick when I query it again, but the captured frame is identical to the auto one. In guvcview the sliders move and the values update in the UI, but the preview doesn’t react. So it looks like the host thinks it set the control, but the sensor or the firmware on the adapter isn’t actually applying it.
Thanks, that’s a useful data point. This points to a UVC descriptor/firmware behavior on the B0278 where the standard white balance and exposure controls are advertised but not properly routed to the IMX477’s ISP. Let me check with the engineering team on the expected way to control these. There may be a firmware update or an extended-unit (UVC XU) control path needed for the Jetson. I’ll send you the specifics by private message once I have them confirmed.
Understood. I mainly need a code-able way to set white balance and exposure, so if there’s a custom extension unit or a firmware that exposes the right controls, that would work for me. I’d rather not rely on GUI tools. Let me know what you find.
Quick summary of where we are: the B0278 adapter with the IMX477 enumerates standard UVC white balance and exposure controls, but setting them via v4l2-ctl or opencv-python is accepted and reported yet has no visible effect on the stream, so it’s likely not being applied at the sensor level. The root cause is still being confirmed. I’ll follow up next week with a concrete method (firmware or extension-unit approach) for controlling WB and exposure from code, and I’ll send any files privately so you can test on your Jetson.