Skip to content
95 changes: 95 additions & 0 deletions adafruit_si1145.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,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 +106,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 +164,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
23 changes: 23 additions & 0 deletions examples/si1145_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,29 @@
# setup sensor
si1145 = adafruit_si1145.SI1145(i2c)


# High Signal Range mode divides gain by 14.5
# Useful for direct sunlight operation
# si1145.als_vis_range_high = True
# si1145.als_ir_range_high = True


# Gain technically increases integration time
# 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)


si1145.gain = adafruit_si1145.GAIN_ADC_CLOCK_DIV_16 # changes vis and ir gains
# si1145.vis_gain = adafruit_si1145.GAIN_ADC_CLOCK_DIV_16
# si1145.ir_gain = adafruit_si1145.GAIN_ADC_CLOCK_DIV_16


# loop forever printing values
while True:
vis, ir = si1145.als
Expand Down
82 changes: 82 additions & 0 deletions examples/si1145_test_gains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2022 Carter Nelson for Adafruit Industries
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we only need 1 copyright notice here instead of two.

Since it's a new file that you created now you can also update the year to 2024 and use your name or username instead of these ones.

You can also omit the "for Adafruit Industries" which is intended to indicate development work that was paid for by Adafruit.

#
# 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
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,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_2,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_4,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_8,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_16,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_32,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_64,
adafruit_si1145.GAIN_ADC_CLOCK_DIV_128,
)


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))