mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Fix bugs with sensor auto gain control.
This commit is contained in:
parent
b1e84d9955
commit
1cf5211efb
@ -625,7 +625,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
|||||||
|
|
||||||
ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
|
ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
|
||||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||||
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 1.0);
|
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, COM9, ®);
|
ret |= cambus_readb(sensor->slv_addr, COM9, ®);
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM9, (reg & 0x1F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 5));
|
ret |= cambus_writeb(sensor->slv_addr, COM9, (reg & 0x1F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 5));
|
||||||
@ -641,15 +641,19 @@ static int get_gain_db(sensor_t *sensor, float *gain_db)
|
|||||||
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg | BANK_SEL_SENSOR);
|
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg | BANK_SEL_SENSOR);
|
||||||
ret |= cambus_readb(sensor->slv_addr, COM8, ®);
|
ret |= cambus_readb(sensor->slv_addr, COM8, ®);
|
||||||
|
|
||||||
if (reg & COM8_AGC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, reg & (~COM8_AGC_EN));
|
// if (reg & COM8_AGC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, reg & (~COM8_AGC_EN));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, GAIN, &gain);
|
ret |= cambus_readb(sensor->slv_addr, GAIN, &gain);
|
||||||
|
|
||||||
if (reg & COM8_AGC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AGC_EN);
|
// if (reg & COM8_AGC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AGC_EN);
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
*gain_db = 20.0 * (fast_log((((gain >> 4) & 0xF) + 1.0) * (1.0 + (((gain >> 0) & 0xF) / 16.0))) / fast_log(10.0));
|
*gain_db = 20.0 * (fast_log((((gain >> 4) & 0xF) + 1.0) * (1.0 + (((gain >> 0) & 0xF) / 16.0))) / fast_log(10.0));
|
||||||
|
|
||||||
@ -710,17 +714,21 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
|||||||
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg | BANK_SEL_SENSOR);
|
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg | BANK_SEL_SENSOR);
|
||||||
ret |= cambus_readb(sensor->slv_addr, COM8, ®);
|
ret |= cambus_readb(sensor->slv_addr, COM8, ®);
|
||||||
|
|
||||||
if (reg & COM8_AEC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, reg & (~COM8_AEC_EN));
|
// if (reg & COM8_AEC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, reg & (~COM8_AEC_EN));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG04, &aec_10);
|
ret |= cambus_readb(sensor->slv_addr, REG04, &aec_10);
|
||||||
ret |= cambus_readb(sensor->slv_addr, AEC, &aec_92);
|
ret |= cambus_readb(sensor->slv_addr, AEC, &aec_92);
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG45, &aec_1510);
|
ret |= cambus_readb(sensor->slv_addr, REG45, &aec_1510);
|
||||||
|
|
||||||
if (reg & COM8_AEC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AEC_EN);
|
// if (reg & COM8_AEC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AEC_EN);
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, COM7, ®);
|
ret |= cambus_readb(sensor->slv_addr, COM7, ®);
|
||||||
int t_line = 0;
|
int t_line = 0;
|
||||||
|
|||||||
@ -373,7 +373,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
|||||||
|
|
||||||
ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
|
ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
|
||||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||||
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 32.0), 1.0);
|
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 32.0), 2.0);
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, COM9, ®);
|
ret |= cambus_readb(sensor->slv_addr, COM9, ®);
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM9, (reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
|
ret |= cambus_writeb(sensor->slv_addr, COM9, (reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
|
||||||
@ -387,15 +387,19 @@ static int get_gain_db(sensor_t *sensor, float *gain_db)
|
|||||||
uint8_t reg, gain;
|
uint8_t reg, gain;
|
||||||
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
||||||
|
|
||||||
if (reg & COM8_AGC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, 0));
|
// if (reg & COM8_AGC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, 0));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, GAIN, &gain);
|
ret |= cambus_readb(sensor->slv_addr, GAIN, &gain);
|
||||||
|
|
||||||
if (reg & COM8_AGC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, 1));
|
// if (reg & COM8_AGC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, 1));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
*gain_db = 20.0 * (fast_log((((gain >> 4) & 0xF) + 1.0) * (1.0 + (((gain >> 0) & 0xF) / 16.0))) / fast_log(10.0));
|
*gain_db = 20.0 * (fast_log((((gain >> 4) & 0xF) + 1.0) * (1.0 + (((gain >> 0) & 0xF) / 16.0))) / fast_log(10.0));
|
||||||
|
|
||||||
@ -445,16 +449,20 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
|||||||
uint8_t reg, aec_l, aec_h;
|
uint8_t reg, aec_l, aec_h;
|
||||||
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
||||||
|
|
||||||
if (reg & COM8_AEC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AEC(reg, 0));
|
// if (reg & COM8_AEC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AEC(reg, 0));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, AEC, &aec_l);
|
ret |= cambus_readb(sensor->slv_addr, AEC, &aec_l);
|
||||||
ret |= cambus_readb(sensor->slv_addr, AECH, &aec_h);
|
ret |= cambus_readb(sensor->slv_addr, AECH, &aec_h);
|
||||||
|
|
||||||
if (reg & COM8_AEC_EN) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AEC(reg, 1));
|
// if (reg & COM8_AEC_EN) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AEC(reg, 1));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, COM7, ®);
|
ret |= cambus_readb(sensor->slv_addr, COM7, ®);
|
||||||
|
|
||||||
|
|||||||
@ -351,7 +351,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
|||||||
ret |= cambus_readb(sensor->slv_addr, REG_VREF, ®);
|
ret |= cambus_readb(sensor->slv_addr, REG_VREF, ®);
|
||||||
ret |= cambus_writeb(sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F));
|
ret |= cambus_writeb(sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F));
|
||||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||||
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 1.0);
|
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_COM9, ®);
|
ret |= cambus_readb(sensor->slv_addr, REG_COM9, ®);
|
||||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM9, (reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
|
ret |= cambus_writeb(sensor->slv_addr, REG_COM9, (reg & 0x8F) | ((fast_ceilf(fast_log2(gain_ceiling)) - 1) << 4));
|
||||||
@ -365,18 +365,22 @@ static int get_gain_db(sensor_t *sensor, float *gain_db)
|
|||||||
uint8_t reg, gain_lo, gain_hi;
|
uint8_t reg, gain_lo, gain_hi;
|
||||||
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
||||||
|
|
||||||
if (reg & REG_COM8_AGC) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AGC));
|
// if (reg & REG_COM8_AGC) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AGC));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_GAIN, &gain_lo);
|
ret |= cambus_readb(sensor->slv_addr, REG_GAIN, &gain_lo);
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_VREF, &gain_hi);
|
ret |= cambus_readb(sensor->slv_addr, REG_VREF, &gain_hi);
|
||||||
|
|
||||||
if (reg & REG_COM8_AGC) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AGC);
|
// if (reg & REG_COM8_AGC) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AGC);
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
int gain = ((gain_hi & 0xC0) << 8) | gain_lo;
|
int gain = ((gain_hi & 0xC0) << 2) | gain_lo;
|
||||||
*gain_db = 20.0 * (fast_log((((gain >> 4) & 0x3F) + 1.0) * (1.0 + (((gain >> 0) & 0xF) / 16.0))) / fast_log(10.0));
|
*gain_db = 20.0 * (fast_log((((gain >> 4) & 0x3F) + 1.0) * (1.0 + (((gain >> 0) & 0xF) / 16.0))) / fast_log(10.0));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -421,17 +425,21 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
|||||||
uint8_t reg, aec_10, aec_92, aec_1510;
|
uint8_t reg, aec_10, aec_92, aec_1510;
|
||||||
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
||||||
|
|
||||||
if (reg & REG_COM8_AEC) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AEC));
|
// if (reg & REG_COM8_AEC) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AEC));
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_COM1, &aec_10);
|
ret |= cambus_readb(sensor->slv_addr, REG_COM1, &aec_10);
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_AECH, &aec_92);
|
ret |= cambus_readb(sensor->slv_addr, REG_AECH, &aec_92);
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_AECHM, &aec_1510);
|
ret |= cambus_readb(sensor->slv_addr, REG_AECHM, &aec_1510);
|
||||||
|
|
||||||
if (reg & REG_COM8_AEC) {
|
// DISABLED
|
||||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AEC);
|
// if (reg & REG_COM8_AEC) {
|
||||||
}
|
// ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AEC);
|
||||||
|
// }
|
||||||
|
// DISABLED
|
||||||
|
|
||||||
ret |= cambus_readb(sensor->slv_addr, REG_COM7, ®);
|
ret |= cambus_readb(sensor->slv_addr, REG_COM7, ®);
|
||||||
int t_line = 0, t_pclk = (reg & REG_COM7_RGB) ? 2 : 1;
|
int t_line = 0, t_pclk = (reg & REG_COM7_RGB) ? 2 : 1;
|
||||||
|
|||||||
@ -38,12 +38,8 @@ sensor.set_auto_gain(True, gain_db_ceiling = 16.0) # Default gain.
|
|||||||
sensor.skip_frames(time = 2000) # Wait for settings take effect.
|
sensor.skip_frames(time = 2000) # Wait for settings take effect.
|
||||||
clock = time.clock() # Create a clock object to track the FPS.
|
clock = time.clock() # Create a clock object to track the FPS.
|
||||||
|
|
||||||
# Note! You can't read the gain/exposure values in the loop while AGC/AEC is on
|
|
||||||
# since we have to disable the sensor auto control in order to read the values
|
|
||||||
# (they are spread accross registers and can't be read atomically if the control is on).
|
|
||||||
|
|
||||||
while(True):
|
while(True):
|
||||||
clock.tick() # Update the FPS clock.
|
clock.tick() # Update the FPS clock.
|
||||||
img = sensor.snapshot() # Take a picture and return the image.
|
img = sensor.snapshot() # Take a picture and return the image.
|
||||||
print(clock.fps()) # Note: OpenMV Cam runs about half as fast when connected
|
print("FPS %f, Gain %f dB, Exposure %d us" % \
|
||||||
# to the IDE. The FPS should increase once disconnected.
|
(clock.fps(), sensor.get_gain_db(), sensor.get_exposure_us()))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user