Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for gain and range settings #21

Merged
merged 12 commits into from
Sep 21, 2024
96 changes: 96 additions & 0 deletions adafruit_si1145.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2022 Carter Nelson for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2024 Aaron W Morris (aaronwmorris)
#
# SPDX-License-Identifier: MIT
"""
Expand Down Expand Up @@ -66,9 +67,29 @@
_RAM_CHLIST = const(0x01)


# Gain Parameters
_ALS_VIS_ADC_GAIN = const(0x11)
_ALS_VIS_ADC_MISC = const(0x12)
_ALS_IR_ADC_GAIN = const(0x1E)
_ALS_IR_ADC_MISC = const(0x1F)


# Gain technically increases integration time
GAIN_ADC_CLOCK_DIV_1 = const(0x00)
GAIN_ADC_CLOCK_DIV_2 = const(0x01)
GAIN_ADC_CLOCK_DIV_4 = const(0x02)
GAIN_ADC_CLOCK_DIV_8 = const(0x03)
GAIN_ADC_CLOCK_DIV_16 = const(0x04)
GAIN_ADC_CLOCK_DIV_32 = const(0x05)
GAIN_ADC_CLOCK_DIV_64 = const(0x06)
GAIN_ADC_CLOCK_DIV_128 = const(0x07)


class SI1145:
"""Driver for the SI1145 UV, IR, Visible Light Sensor."""

# pylint: disable=too-many-instance-attributes, maybe-no-member

_device_info = Struct(_PART_ID, "<BBB")
_ucoeff_0 = Struct(_COEFF_0, "<B")
_ucoeff_1 = Struct(_COEFF_1, "<B")
Expand All @@ -86,6 +107,7 @@ def __init__(self, i2c: I2C, address: int = _DEFAULT_ADDRESS) -> None:
self._write_register(_HW_KEY, 0x17)
self._als_enabled = True
self._uv_index_enabled = True

self.als_enabled = self._als_enabled
self.uv_index_enabled = self._uv_index_enabled

Expand Down Expand Up @@ -143,6 +165,80 @@ def uv_index(self) -> float:
self._send_command(_CMD_ALS_FORCE)
return self._aux_data[0] / 100

@property
def vis_gain(self) -> int:
"""Visible gain value"""
div = self._param_query(_ALS_VIS_ADC_GAIN)
return div & ~0b11111000

@vis_gain.setter
def vis_gain(self, value: int) -> None:
self._param_set(_ALS_VIS_ADC_GAIN, value)

@property
def ir_gain(self) -> int:
"""IR gain value"""
div = self._param_query(_ALS_IR_ADC_GAIN)
return div & ~0b11111000

@ir_gain.setter
def ir_gain(self, value: int) -> None:
self._param_set(_ALS_IR_ADC_GAIN, value)

@property
def gain(self) -> Tuple[int, int]:
"""Visble and IR gain values"""
# return both vis and ir gains
return self.vis_gain, self.ir_gain

@gain.setter
def gain(self, value: int) -> None:
# set both vis and ir gains
self.vis_gain = value
self.ir_gain = value

@property
def als_vis_range_high(self) -> bool:
"""Visible high range value"""
vis_adc_misc = self._param_query(_ALS_VIS_ADC_MISC)
return bool((vis_adc_misc & ~0b11011111) >> 5)

@als_vis_range_high.setter
def als_vis_range_high(self, enable: bool) -> None:
vis_adc_misc = self._param_query(_ALS_VIS_ADC_MISC)
if enable:
vis_adc_misc |= 0b00100000
else:
vis_adc_misc &= ~0b00100000
self._param_set(_ALS_VIS_ADC_MISC, vis_adc_misc)

@property
def als_ir_range_high(self) -> bool:
"""IR high range value"""
ir_adc_misc = self._param_query(_ALS_IR_ADC_MISC)
return bool((ir_adc_misc & ~0b11011111) >> 5)

@als_ir_range_high.setter
def als_ir_range_high(self, enable: bool) -> None:
ir_adc_misc = self._param_query(_ALS_IR_ADC_MISC)
if enable:
ir_adc_misc |= 0b00100000
else:
ir_adc_misc &= ~0b00100000
self._param_set(_ALS_IR_ADC_MISC, ir_adc_misc)

@property
def als_range_high(self) -> Tuple[bool, bool]:
"""Visbile and IR high range values"""
# return both vis and ir range
return self._als_vis_range_high, self._als_ir_range_high

@als_range_high.setter
def als_range_high(self, enable: bool) -> None:
# set both vis and ir ranges
self.als_vis_range_high = enable
self.als_ir_range_high = enable

def reset(self) -> None:
"""Perform a software reset of the firmware."""
self._send_command(_CMD_RESET)
Expand Down
86 changes: 86 additions & 0 deletions examples/si1145_test_gains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 Aaron W Morris (aaronwmorris)
#
# SPDX-License-Identifier: Unlicense

import time
import board
import adafruit_si1145

# setup I2C bus using board default
# change as needed for specific boards
i2c = board.I2C() # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller

# setup sensor
si1145 = adafruit_si1145.SI1145(i2c)


print("Default Vis Gain: {}".format(si1145.vis_gain))
print("Default IR Gain: {}".format(si1145.ir_gain))
print("Default Vis High range: {}".format(str(si1145.als_vis_range_high)))
print("Default IR High range: {}".format(str(si1145.als_ir_range_high)))
print()


### Low range
si1145.als_range_high = False # both settings
# si1145.als_vis_range_high = False
# si1145.als_ir_range_high = False

# Change above to True for High Signal Range mode.
# High Signal Range mode divides gain by 14.5
# Useful for direct sunlight operation

time.sleep(0.5)

# test reading attributes
print("Vis High range: {}".format(str(si1145.als_vis_range_high)))
print("IR High range: {}".format(str(si1145.als_ir_range_high)))
print()


gain_list = (
adafruit_si1145.GAIN_ADC_CLOCK_DIV_1, # (1x gain, default)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_2, # (2x gain)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_4, # (4x gain)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_8, # (8x gain)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_16, # (16x gain)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_32, # (32x gain)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_64, # (64x gain)
adafruit_si1145.GAIN_ADC_CLOCK_DIV_128, # (128x gain)
)


for gain in gain_list:
si1145.gain = gain # both gains
# si1145.vis_gain = gain
# si1145.ir_gain = gain

# test reading attributes
print("Vis Gain: {}".format(si1145.vis_gain))
print("IR Gain: {}".format(si1145.ir_gain))

vis, ir = si1145.als
uv_index = si1145.uv_index
print("Visible = {}, Infrared = {}, UV Index = {}".format(vis, ir, uv_index))
print()
time.sleep(0.5)


### High range
# In high range mode, sensor gain should be ~14.5
si1145.als_range_high = True # both settings
# si1145.als_vis_range_high = True
# si1145.als_ir_range_high = True
time.sleep(0.5)


# test reading attributes
print("Vis High range: {}".format(str(si1145.als_vis_range_high)))
print("IR High range: {}".format(str(si1145.als_ir_range_high)))
print()


vis, ir = si1145.als
uv_index = si1145.uv_index
print("Visible = {}, Infrared = {}, UV Index = {}".format(vis, ir, uv_index))