Hi everyone, I’m working on a photobooth project and my camera suddenly started producing pictures that are way too dark to use. EV, ISO, and Exposure settings don’t seem to do anything - it’s like the commands are ignored. Settings that touch register 0x30 also appear ignored, but brightness and contrast still work fine. The camera worked before and the images were brighter, then it somehow quit working.
Thanks for the details. Can you tell me a bit more about your setup - which camera module and microcontroller, how it’s wired, and what library you’re using? Also, what have you already tried?
Sure. It’s an ARDUCAM SPI CAM Mega 5MP on an ESP32-S3. The camera has its own dedicated SPI bus, and a separate SPI bus runs the screen. I’m using the ArduCam libraries.
Things I’ve tried so far:
- Added 10 dummy frames when changing WhiteBalance or Exposure
- Tried 1 minute between shots
- Tried a series of images in quick succession: no change
- Tried warming up with 10 dummy shots before the snapshot: no change
- Tried 1 minute between shots when testing different settings: no change
- Looped ISO from 10 to 1023 and exposure from 1000 to 30000 with no visible change in the image
Could you paste the dummy-frame and auto-setting functions you’re using? I want to see how the auto flags are being toggled around captures.
Here they are:
void DummyPicture() {
byte i;
for (i=0; i<10;i++) {
myCAM.takePicture(Config.definition,CAM_IMAGE_PIX_FMT_JPG);
delay(10);
}
}
void EnableAutoISOSensitive() {myCAM.setAutoISOSensitive(1);DummyPicture();}
void EnableAutoExposure() {myCAM.setAutoExposure(1);DummyPicture();}
void DisableAutoISOSensitive() {
myCAM.setAutoISOSensitive(0);delay(10);
myCAM.setAutoExposure(0);delay(10);
myCAM.setAutoWhiteBalance(0);delay(10);
DummyPicture();
}
void DisableAutoExposure() {
myCAM.setAutoISOSensitive(0);delay(10);
myCAM.setAutoExposure(0);delay(10);
myCAM.setAutoWhiteBalance(0);delay(10);
DummyPicture();
}
Thanks. Can you also share the testISO() and testExposure() loops you used for the ISO/exposure sweep?
Sure, here are both:
void testISO(){
int i;
tft.setTextColor(TFT_WHITE);
tft.println("Test ISO");
tft.println("10 to 1023 in 10 steps");
DisableAutoISOSensitive();
delay(2000);
i=10;
while (i <= 1023) {
myCAM.setISOSensitivity(i);
delay(5000);
tft.fillScreen(TFT_BLACK);
myCAM.takePicture(Config.definition,CAM_IMAGE_PIX_FMT_JPG);
imageSize = myCAM.getReceivedLength();
ReadArduCamBurst();
updateDisplay();
tft.setCursor(0, 20);tft.println(String(i));
if (i==10) i=100; else i+=200;
if (i==900) i=1023;
}
myCAM.reset();
}
void testExposure(){
uint32_t i;
tft.setTextColor(TFT_WHITE);
tft.println("Test Exposure");
//tft.println("0 to 16'777'215 in 10 steps");
tft.println("1000 to 30000 in 10 steps");
DisableAutoExposure();
delay(2000);
i=1000L;
//while (i <= 16777215) {
while (i <= 30000) {
delay(5000);
myCAM.setAbsoluteExposure(i);
tft.fillScreen(TFT_BLACK);
myCAM.takePicture(Config.definition,CAM_IMAGE_PIX_FMT_JPG);
imageSize = myCAM.getReceivedLength();
ReadArduCamBurst(); //Read ArduCam
updateDisplay();
tft.setCursor(0, 20);tft.println(String(i));
//i+=1600000;
if (i==1000) i=5000;
else i+=5000;
}
myCAM.reset();
}
One more thing - when you call setISOSensitivity or setAbsoluteExposure, are you checking the return value? Any error logs or messages printed on the screen during those loops?
No explicit error logs. The setting calls report success (CAM_ERR_SUCCESS) as far as I can tell, but the images still look identical. That’s the confusing part.
Based on what you’ve described, this looks like the behavior of the AE and AWB algorithms rather than the commands being ignored. The exposure pipeline needs roughly 5-10 frames to stabilize after a setting change. The first frames shouldn’t be used as a reference. With a large time gap between snapshots, the camera may not get enough frames to adjust exposure properly before you evaluate the image.
So it might not actually be broken? What should I change in my test code to give it a fair chance?
Right, I’d try this before assuming the camera is damaged:
- Capture a series of images in quick succession; expect improvement in brightness after the first few frames.
- If possible, allow the camera to “warm up” by capturing several frames before taking the desired snapshot.
- When testing different settings, make sure to give the camera enough time (and frames) to adjust before evaluating the results.
- If issues persist after these suggestions, contact support for further troubleshooting.
I also reworked your ISO and exposure loops so each iteration prints whether the set calls actually succeeded. That helps separate “ignored” from “not stabilized yet.”
void testISO() { int i; tft.setTextColor(TFT_WHITE); for (i=0;i<=1000;i=i+20) { tft.fillScreen(TFT_BLACK); tft.setCursor(0, 20); // Set cursor near top left corner of screen: xpos=0; ypos=20; tft.println("ISO"); if ((myCAM.setAutoISOSensitive(1)) != CAM_ERR_SUCCESS) tft.println("Disable Auto ERROR"); else tft.println("Disable Auto OK"); if ((myCAM.setISOSensitivity(i)) != CAM_ERR_SUCCESS) tft.println("ISO set to" + String(i) + " ERROR"); else tft.println("ISO set to" + String(i) + " OK"); delay(400); myCAM.takePicture(Config.definition,CAM_IMAGE_PIX_FMT_JPG); imageSize = myCAM.getReceivedLength(); ReadArduCamBurst(); //Read ArduCam updateDisplay(); } }
void testExposure(){ int i; tft.setTextColor(TFT_WHITE); for (i=0;i<=1000;i=i+20) { tft.fillScreen(TFT_BLACK); tft.setCursor(0, 20); // Set cursor near top left corner of screen: xpos=0; ypos=20; tft.println("Exposure"); if ((myCAM.setAutoExposure(1)) != CAM_ERR_SUCCESS) tft.println("Disable Auto ERROR"); else tft.println("Disable Auto OK"); if ((myCAM.setAbsoluteExposure(i)) != CAM_ERR_SUCCESS) tft.println("Exposure set to" + String(i) + " ERROR"); else tft.println("Exposure set to" + String(i) + " OK"); delay(400); myCAM.takePicture(Config.definition,CAM_IMAGE_PIX_FMT_JPG); imageSize = myCAM.getReceivedLength(); ReadArduCamBurst(); //Read ArduCam updateDisplay(); } }
The key takeaway: the dark images are likely because AE/AWB need several frames to stabilize exposure, not because the camera is damaged or the exposure/ISO commands are being ignored.