Skip to content

Commit caf36a8

Browse files
committed
add the rest of the image controls
1 parent d547c73 commit caf36a8

File tree

1 file changed

+130
-4
lines changed

1 file changed

+130
-4
lines changed

adafruit_ov5640.py

Lines changed: 130 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,10 @@
286286
# Bit[5:0]: QS
287287
_COMPRESSION_ISI_CTRL = const(0x4408)
288288
_COMPRESSION_CTRL09 = const(0x4409)
289-
_COMPRESSION_CTRL0a = const(0x440A)
290-
_COMPRESSION_CTRL0b = const(0x440B)
291-
_COMPRESSION_CTRL0c = const(0x440C)
292-
_COMPRESSION_CTRL0d = const(0x440D)
289+
_COMPRESSION_CTRL0A = const(0x440A)
290+
_COMPRESSION_CTRL0B = const(0x440B)
291+
_COMPRESSION_CTRL0C = const(0x440C)
292+
_COMPRESSION_CTRL0D = const(0x440D)
293293
_COMPRESSION_CTRL0E = const(0x440E)
294294

295295
_TEST_COLOR_BAR = const(0xC0)
@@ -568,6 +568,16 @@
568568
OV5640_COLOR_JPEG: _sensor_format_jpeg,
569569
}
570570

571+
_contrast_settings = [
572+
[0x20, 0x00], # 0
573+
[0x24, 0x10], # +1
574+
[0x1a, 0x13], # +2
575+
[0x2c, 0x1c], # +3
576+
[0x14, 0x14], # -3
577+
[0x18, 0x18], # -2
578+
[0x1c, 0x1c], # -1
579+
]
580+
571581
_sensor_saturation_levels = [
572582
[0x1D, 0x60, 0x03, 0x0C, 0x78, 0x84, 0x7D, 0x6B, 0x12, 0x01, 0x98], # 0
573583
[0x1D, 0x60, 0x03, 0x0D, 0x84, 0x91, 0x8A, 0x76, 0x14, 0x01, 0x98], # +1
@@ -580,6 +590,32 @@
580590
[0x1D, 0x60, 0x03, 0x0B, 0x6C, 0x77, 0x70, 0x60, 0x10, 0x01, 0x98], # -1
581591
]
582592

593+
_sensor_ev_levels = [
594+
[0x38, 0x30, 0x61, 0x38, 0x30, 0x10], # 0
595+
[0x40, 0x38, 0x71, 0x40, 0x38, 0x10], # +1
596+
[0x50, 0x48, 0x90, 0x50, 0x48, 0x20], # +2
597+
[0x60, 0x58, 0xa0, 0x60, 0x58, 0x20], # +3
598+
[0x10, 0x08, 0x10, 0x08, 0x20, 0x10], # -3
599+
[0x20, 0x18, 0x41, 0x20, 0x18, 0x10], # -2
600+
[0x30, 0x28, 0x61, 0x30, 0x28, 0x10], # -1
601+
]
602+
603+
OV5640_WHITE_BALANCE_AUTO = 0
604+
OV5640_WHITE_BALANCE_SUNNY = 1
605+
OV5640_WHITE_BALANCE_FLUORESCENT = 2
606+
OV5640_WHITE_BALANCE_CLOUDY = 3
607+
OV5640_WHITE_BALANCE_INCANDESCENT = 4
608+
609+
_light_registers = [0x3406, 0x3400, 0x3401, 0x3402, 0x3403, 0x3404, 0x3405]
610+
_light_modes = [
611+
[0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00], # auto
612+
[0x01, 0x06, 0x1c, 0x04, 0x00, 0x04, 0xf3], # sunny
613+
[0x01, 0x05, 0x48, 0x04, 0x00, 0x07, 0xcf], # office / fluorescent
614+
[0x01, 0x06, 0x48, 0x04, 0x00, 0x04, 0xd3], # cloudy
615+
[0x01, 0x04, 0x10, 0x04, 0x00, 0x08, 0x40], # home / incandescent
616+
617+
]
618+
583619
OV5640_SPECIAL_EFFECT_NONE = 0
584620
OV5640_SPECIAL_EFFECT_NEGATIVE = 1
585621
OV5640_SPECIAL_EFFECT_GRAYSCALE = 2
@@ -849,6 +885,8 @@ def __init__(
849885
self._test_pattern = False
850886
self._binning = False
851887
self._scale = False
888+
self._ev = 0
889+
self._white_balance = 0
852890
self.size = size
853891

854892
chip_id = _RegBits16(_CHIP_ID_HIGH, 0, 0xFFFF)
@@ -1100,6 +1138,10 @@ def saturation(self):
11001138

11011139
@saturation.setter
11021140
def saturation(self, value):
1141+
if not -4 <= value <= 4:
1142+
raise ValueError(
1143+
"Invalid saturation {value}, use a value from -4..4 inclusive"
1144+
)
11031145
for offset, reg_value in enumerate(_sensor_saturation_levels[value]):
11041146
self._write_register(0x5381 + offset, reg_value)
11051147
self._saturation = value
@@ -1129,3 +1171,87 @@ def quality(self, value: int):
11291171
f"Invalid quality value {value}, use a value from 5..55 inclusive"
11301172
)
11311173
self._write_register(_COMPRESSION_CTRL07, value & 0x3F)
1174+
1175+
def _write_group_3_settings(self, settings):
1176+
self._write_register(0x3212, 0x3) # start group 3
1177+
self._write_list(settings)
1178+
self._write_register(0x3212, 0x13) # end group 3
1179+
self._write_register(0x3212, 0xA3) # launch group 3
1180+
1181+
@property
1182+
def brightness(self):
1183+
"""Sensor brightness adjustment, from -4 to 4 inclusive"""
1184+
brightness_abs = self._read_register(0x5587) >> 4
1185+
brightness_neg = self._read_register(0x5588) & 8
1186+
if brightness_neg:
1187+
return -brightness_abs
1188+
return brightness_abs
1189+
1190+
@brightness.setter
1191+
def brightness(self, value):
1192+
if not -4 <= value <= 4:
1193+
raise ValueError(
1194+
"Invalid brightness value {value}, use a value from -4..4 inclusive"
1195+
)
1196+
self._write_group_3_settings(
1197+
[0x5587, abs(value) << 4, 0x9 if value < 0 else 0x1]
1198+
)
1199+
1200+
@property
1201+
def contrast(self):
1202+
"""Sensor contrast adjustment, from -4 to 4 inclusive"""
1203+
contrast_abs = self._read_register(0x5587) >> 4
1204+
contrast_neg = self._read_register(0x5588) & 8
1205+
if contrast_neg:
1206+
return -contrast_abs
1207+
return contrast_abs
1208+
1209+
@contrast.setter
1210+
def contrast(self, value):
1211+
if not -3 <= value <= 3:
1212+
raise ValueError(
1213+
"Invalid contrast value {value}, use a value from -3..3 inclusive"
1214+
)
1215+
setting = _contrast_settings[value]
1216+
self._write_group_3_settings([0x5586, setting[0], 0x5585, setting[1]])
1217+
1218+
@property
1219+
def exposure_value(self):
1220+
"""Sensor exposure (EV) adjustment, from -4 to 4 inclusive"""
1221+
return self._ev
1222+
1223+
@exposure_value.setter
1224+
def exposure_value(self, value):
1225+
if not -3 <= value <= 3:
1226+
raise ValueError(
1227+
"Invalid exposure value (EV) {value}, use a value from -4..4 inclusive"
1228+
)
1229+
for offset, reg_value in enumerate(_sensor_ev_levels[value]):
1230+
self._write_register(0x5381 + offset, reg_value)
1231+
1232+
@property
1233+
def white_balance(self):
1234+
"""The white balance setting, one of the ``OV5640_WHITE_BALANCE_*`` constants"""
1235+
return self._white_balance
1236+
1237+
@white_balance.setter
1238+
def white_balance(self, value):
1239+
if not OV5640_WHITE_BALANCE_AUTO <= value <= OV5640_WHITE_BALANCE_INCANDESCENT:
1240+
raise ValueError(
1241+
"Invalid exposure value (EV) {value}, "
1242+
"use one of the OV5640_WHITE_BALANCE_* constants"
1243+
)
1244+
self._write_register(0x3212, 0x3) # start group 3
1245+
for reg_addr, reg_value in zip(_light_registers, _light_modes[value]):
1246+
self._write_register(reg_addr, reg_value)
1247+
self._write_register(0x3212, 0x13) # end group 3
1248+
self._write_register(0x3212, 0xA3) # launch group 3
1249+
1250+
@property
1251+
def night_mode(self):
1252+
"""Enable or disable the night mode setting of the sensor"""
1253+
return bool(self._read_register(0x3A00) & 0x04)
1254+
1255+
@night_mode.setter
1256+
def night_mode(self, value):
1257+
self._write_reg_bits(0x3A00, 0x04, value)

0 commit comments

Comments
 (0)