Merge pull request #296 from kwagyeman/sensor_fixes

Fix bugs with sensor auto gain control.
This commit is contained in:
Ibrahim Abd Elkader 2018-01-01 01:55:18 +02:00 committed by GitHub
commit 92c7900039
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 46 deletions

View File

@ -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));
} 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, &reg);
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_readb(sensor->slv_addr, COM8, &reg);
if (reg & COM8_AGC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, reg & (~COM8_AGC_EN));
}
// DISABLED
// 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);
if (reg & COM8_AGC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AGC_EN);
}
// DISABLED
// 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));
@ -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_readb(sensor->slv_addr, COM8, &reg);
if (reg & COM8_AEC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, reg & (~COM8_AEC_EN));
}
// DISABLED
// 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, AEC, &aec_92);
ret |= cambus_readb(sensor->slv_addr, REG45, &aec_1510);
if (reg & COM8_AEC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AEC_EN);
}
// DISABLED
// if (reg & COM8_AEC_EN) {
// ret |= cambus_writeb(sensor->slv_addr, COM8, reg | COM8_AEC_EN);
// }
// DISABLED
ret |= cambus_readb(sensor->slv_addr, COM7, &reg);
int t_line = 0;

View File

@ -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));
} 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, &reg);
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;
int ret = cambus_readb(sensor->slv_addr, COM8, &reg);
if (reg & COM8_AGC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, 0));
}
// DISABLED
// 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);
if (reg & COM8_AGC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, 1));
}
// DISABLED
// 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));
@ -445,16 +449,20 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
uint8_t reg, aec_l, aec_h;
int ret = cambus_readb(sensor->slv_addr, COM8, &reg);
if (reg & COM8_AEC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AEC(reg, 0));
}
// DISABLED
// 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, AECH, &aec_h);
if (reg & COM8_AEC_EN) {
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AEC(reg, 1));
}
// DISABLED
// 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, &reg);

View File

@ -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, &reg);
ret |= cambus_writeb(sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F));
} 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, &reg);
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;
int ret = cambus_readb(sensor->slv_addr, REG_COM8, &reg);
if (reg & REG_COM8_AGC) {
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AGC));
}
// DISABLED
// 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_VREF, &gain_hi);
if (reg & REG_COM8_AGC) {
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AGC);
}
// DISABLED
// 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));
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;
int ret = cambus_readb(sensor->slv_addr, REG_COM8, &reg);
if (reg & REG_COM8_AEC) {
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AEC));
}
// DISABLED
// 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_AECH, &aec_92);
ret |= cambus_readb(sensor->slv_addr, REG_AECHM, &aec_1510);
if (reg & REG_COM8_AEC) {
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AEC);
}
// DISABLED
// 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, &reg);
int t_line = 0, t_pclk = (reg & REG_COM7_RGB) ? 2 : 1;

View File

@ -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.
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):
clock.tick() # Update the FPS clock.
img = sensor.snapshot() # Take a picture and return the image.
print(clock.fps()) # Note: OpenMV Cam runs about half as fast when connected
# to the IDE. The FPS should increase once disconnected.
print("FPS %f, Gain %f dB, Exposure %d us" % \
(clock.fps(), sensor.get_gain_db(), sensor.get_exposure_us()))