| """ |
| This file licensed under the MIT License and incorporates work covered by |
| the following copyright and permission notice: |
| |
| The MIT License (MIT) |
| |
| Copyright (c) 2022-2022 Rob Hamerling |
| |
| Permission is hereby granted, free of charge, to any person obtaining a copy |
| of this software and associated documentation files (the "Software"), to deal |
| in the Software without restriction, including without limitation the rights |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| copies of the Software, and to permit persons to whom the Software is |
| furnished to do so, subject to the following conditions: |
| |
| The above copyright notice and this permission notice shall be included in |
| all copies or substantial portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| THE SOFTWARE. |
| |
| Rob Hamerling, Version 0.0, August 2022 |
| |
| Original by WaveShare for Raspberry Pi, part of: |
| https://www.waveshare.com/w/upload/b/b3/AS7341_Spectral_Color_Sensor_code.7z |
| |
| Converted to Micropython for use with MicroPython devices such as ESP32 |
| - pythonized (in stead of 'literal' translation of C code) |
| - instance of AS7341 requires specification of I2C interface |
| - added I2C read/write error detection |
| - added check for connected AS7341 incl. device ID |
| - some code optimization (esp. adding I2C word/block reads/writes) |
| - Replaced bit addressing like (1<<5) by symbolic name with bit mask |
| - moved SMUX settings for predefined channel mappings to a dictionary |
| and as a separate file to allow changes or additional configurations |
| by the user without changing the driver |
| - several changes of names of functions and constants |
| (incl. camel case -> word separators with underscores) |
| - added comments, doc-strings with explanation and/or argumentation |
| - several other improvements and some corrections |
| |
| Remarks: |
| - Automatic Gain Control (AGC) is not supported |
| - No provisions for SYND mode |
| |
| """ |
|
|
| from time import sleep_ms |
|
|
| from as7341_smux_select import * |
|
|
| AS7341_I2C_ADDRESS = const(0x39) |
| AS7341_ID_VALUE = const(0x24) |
| |
|
|
| |
| |
| AS7341_CONFIG = const(0x70) |
| AS7341_CONFIG_INT_MODE_SPM = const(0x00) |
| AS7341_MODE_SPM = AS7341_CONFIG_INT_MODE_SPM |
| AS7341_CONFIG_INT_MODE_SYNS = const(0x01) |
| AS7341_MODE_SYNS = AS7341_CONFIG_INT_MODE_SYNS |
| AS7341_CONFIG_INT_MODE_SYND = const(0x03) |
| AS7341_MODE_SYND = AS7341_CONFIG_INT_MODE_SYND |
| AS7341_CONFIG_INT_SEL = const(0x04) |
| AS7341_CONFIG_LED_SEL = const(0x08) |
| AS7341_STAT = const(0x71) |
| AS7341_STAT_READY = const(0x01) |
| AS7341_STAT_WAIT_SYNC = const(0x02) |
| AS7341_EDGE = const(0x72) |
| AS7341_GPIO = const(0x73) |
| AS7341_GPIO_PD_INT = const(0x01) |
| AS7341_GPIO_PD_GPIO = const(0x02) |
| AS7341_LED = const(0x74) |
| AS7341_LED_LED_ACT = const(0x80) |
| AS7341_ENABLE = const(0x80) |
| AS7341_ENABLE_PON = const(0x01) |
| AS7341_ENABLE_SP_EN = const(0x02) |
| AS7341_ENABLE_WEN = const(0x08) |
| AS7341_ENABLE_SMUXEN = const(0x10) |
| AS7341_ENABLE_FDEN = const(0x40) |
| AS7341_ATIME = const(0x81) |
| AS7341_WTIME = const(0x83) |
| AS7341_SP_TH_LOW = const(0x84) |
| AS7341_SP_TH_L_LSB = const(0x84) |
| AS7341_SP_TH_L_MSB = const(0x85) |
| AS7341_SP_TH_HIGH = const(0x86) |
| AS7341_SP_TH_H_LSB = const(0x86) |
| AS7341_SP_TH_H_MSB = const(0x87) |
| AS7341_AUXID = const(0x90) |
| AS7341_REVID = const(0x91) |
| AS7341_ID = const(0x92) |
| AS7341_STATUS = const(0x93) |
| AS7341_STATUS_ASAT = const(0x80) |
| AS7341_STATUS_AINT = const(0x08) |
| AS7341_STATUS_FINT = const(0x04) |
| AS7341_STATUS_C_INT = const(0x02) |
| AS7341_STATUS_SINT = const(0x01) |
| AS7341_ASTATUS = const(0x94) |
| AS7341_ASTATUS_ASAT_STATUS = const(0x80) |
| AS7341_ASTATUS_AGAIN_STATUS = const(0x0F) |
| AS7341_CH_DATA = const(0x95) |
| AS7341_CH0_DATA_L = const(0x95) |
| AS7341_CH0_DATA_H = const(0x96) |
| AS7341_CH1_DATA_L = const(0x97) |
| AS7341_CH1_DATA_H = const(0x98) |
| AS7341_CH2_DATA_L = const(0x99) |
| AS7341_CH2_DATA_H = const(0x9A) |
| AS7341_CH3_DATA_L = const(0x9B) |
| AS7341_CH3_DATA_H = const(0x9C) |
| AS7341_CH4_DATA_L = const(0x9D) |
| AS7341_CH4_DATA_H = const(0x9E) |
| AS7341_CH5_DATA_L = const(0x9F) |
| AS7341_CH5_DATA_H = const(0xA0) |
| AS7341_STATUS_2 = const(0xA3) |
| AS7341_STATUS_2_AVALID = const(0x40) |
| AS7341_STATUS_3 = const(0xA4) |
| AS7341_STATUS_5 = const(0xA6) |
| AS7341_STATUS_6 = const(0xA7) |
| AS7341_CFG_0 = const(0xA9) |
| AS7341_CFG_0_WLONG = const(0x04) |
| AS7341_CFG_0_REG_BANK = const(0x10) |
| AS7341_CFG_0_LOW_POWER = const(0x20) |
| AS7341_CFG_1 = const(0xAA) |
| AS7341_CFG_3 = const(0xAC) |
| AS7341_CFG_6 = const(0xAF) |
| AS7341_CFG_6_SMUX_CMD_ROM = const(0x00) |
| AS7341_CFG_6_SMUX_CMD_READ = const(0x08) |
| AS7341_CFG_6_SMUX_CMD_WRITE = const(0x10) |
| AS7341_CFG_8 = const(0xB1) |
| AS7341_CFG_9 = const(0xB2) |
| AS7341_CFG_10 = const(0xB3) |
| AS7341_CFG_12 = const(0xB5) |
| AS7341_PERS = const(0xBD) |
| AS7341_GPIO_2 = const(0xBE) |
| AS7341_GPIO_2_GPIO_IN = const(0x01) |
| AS7341_GPIO_2_GPIO_OUT = const(0x02) |
| AS7341_GPIO_2_GPIO_IN_EN = const(0x04) |
| AS7341_GPIO_2_GPIO_INV = const(0x08) |
| AS7341_ASTEP = const(0xCA) |
| AS7341_ASTEP_L = const(0xCA) |
| AS7341_ASTEP_H = const(0xCB) |
| AS7341_AGC_GAIN_MAX = const(0xCF) |
| AS7341_AZ_CONFIG = const(0xD6) |
| AS7341_FD_TIME_1 = const(0xD8) |
| AS7341_FD_TIME_2 = const(0xDA) |
| AS7341_FD_CFG0 = const(0xD7) |
| AS7341_FD_STATUS = const(0xDB) |
| AS7341_FD_STATUS_FD_100HZ = const(0x01) |
| AS7341_FD_STATUS_FD_120HZ = const(0x02) |
| AS7341_FD_STATUS_FD_100_VALID = const(0x04) |
| AS7341_FD_STATUS_FD_120_VALID = const(0x08) |
| AS7341_FD_STATUS_FD_SAT_DETECT = const(0x10) |
| AS7341_FD_STATUS_FD_MEAS_VALID = const(0x20) |
| AS7341_INTENAB = const(0xF9) |
| AS7341_INTENAB_SP_IEN = const(0x08) |
| AS7341_CONTROL = const(0xFA) |
| AS7341_FIFO_MAP = const(0xFC) |
| AS7341_FIFO_LVL = const(0xFD) |
| AS7341_FDATA = const(0xFE) |
| AS7341_FDATA_L = const(0xFE) |
| AS7341_FDATA_H = const(0xFF) |
|
|
|
|
| class AS7341: |
| """Class for AS7341: 11 Channel Multi-Spectral Digital Sensor""" |
|
|
| def __init__(self, i2c, addr=AS7341_I2C_ADDRESS): |
| """specification of active I2C object is mandatory |
| specification of I2C address of AS7341 is optional |
| """ |
| self.__bus = i2c |
| self.__address = addr |
| self.__buffer1 = bytearray(1) |
| self.__buffer2 = bytearray(2) |
| self.__buffer13 = bytearray(13) |
| self.__measuremode = AS7341_MODE_SPM |
| self.__connected = self.reset() |
|
|
| """ --------- 'private' functions ----------- """ |
|
|
| def __read_byte(self, reg): |
| """read byte, return byte (integer) value""" |
| try: |
| self.__bus.readfrom_mem_into(self.__address, reg, self.__buffer1) |
| return self.__buffer1[0] |
| except Exception as err: |
| print("I2C read_byte at 0x{:02X}, error".format(reg), err) |
| return -1 |
|
|
| def __read_word(self, reg): |
| """read 2 consecutive bytes, return integer value (little Endian)""" |
| try: |
| self.__bus.readfrom_mem_into(self.__address, reg, self.__buffer2) |
| return int.from_bytes(self.__buffer2, "little") |
| except Exception as err: |
| print("I2C read_word at 0x{:02X}, error".format(reg), err) |
| return -1 |
|
|
| def __read_all_channels(self): |
| """read ASTATUS register and all channels, return list of 6 integer values""" |
| try: |
| self.__bus.readfrom_mem_into( |
| self.__address, AS7341_ASTATUS, self.__buffer13 |
| ) |
| return [ |
| int.from_bytes(self.__buffer13[1 + 2 * i : 3 + 2 * i], "little") |
| for i in range(6) |
| ] |
| except Exception as err: |
| print( |
| "I2C read_all_channels at 0x{:02X}, error".format(AS7341_ASTATUS), err |
| ) |
| return [] |
|
|
| def __write_byte(self, reg, value): |
| """write a single byte to the specified register""" |
| self.__buffer1[0] = value & 0xFF |
| try: |
| self.__bus.writeto_mem(self.__address, reg, self.__buffer1) |
| sleep_ms(10) |
| except Exception as err: |
| print("I2C write_byte at 0x{:02X}, error".format(reg), err) |
| return False |
| return True |
|
|
| def __write_word(self, reg, value): |
| """write a word as 2 bytes (little endian encoding) |
| to adresses <reg> + 0 and <reg> + 1 |
| """ |
| self.__buffer2[0] = value & 0xFF |
| self.__buffer2[1] = (value >> 8) & 0xFF |
| try: |
| self.__bus.writeto_mem(self.__address, reg, self.__buffer2) |
| sleep_ms(20) |
| except Exception as err: |
| print("I2C write_word at 0x{:02X}, error".format(reg), err) |
| return False |
| return True |
|
|
| def __write_burst(self, reg, value): |
| """write an array of bytes to consucutive addresses starting <reg>""" |
| try: |
| self.__bus.writeto_mem(self.__address, reg, value) |
| sleep_ms(100) |
| except Exception as err: |
| print("I2C write_burst at 0x{:02X}, error".format(reg), err) |
| return False |
| return True |
|
|
| def __modify_reg(self, reg, mask, flag=True): |
| """modify register <reg> with <mask> |
| <flag> True means 'or' with <mask> : set the bit(s) |
| <flag> False means 'and' with inverted <mask> : reset the bit(s) |
| Notes: 1. Works only with '1' bits in <mask> |
| (in most cases <mask> contains a single 1-bit!) |
| 2. When <reg> is in region 0x60-0x74 |
| bank 1 is supposed be set by caller |
| """ |
| data = self.__read_byte(reg) |
| if flag: |
| data |= mask |
| else: |
| data &= ~mask |
| self.__write_byte(reg, data) |
|
|
| def __set_bank(self, bank=1): |
| """select registerbank |
| <bank> 1 for access to regs 0x60-0x74 |
| <bank> 0 for access to regs 0x80-0xFF |
| Note: It seems that reg CFG_0 (0x93) is accessible |
| even when REG_BANK bit is set for 0x60-0x74, |
| otherwise it wouldn't be possible to reset REG_BANK |
| Datasheet isn't clear about this. |
| """ |
| if bank in (0, 1): |
| self.__modify_reg(AS7341_CFG_0, AS7341_CFG_0_REG_BANK, bank == 1) |
|
|
| """ ----------- 'public' functions ----------- """ |
|
|
| def enable(self): |
| """enable device (only power on)""" |
| self.__write_byte(AS7341_ENABLE, AS7341_ENABLE_PON) |
|
|
| def disable(self): |
| """disable all functions and power off""" |
| self.__set_bank(1) |
| self.__write_byte(AS7341_CONFIG, 0x00) |
| self.__set_bank(0) |
| self.__write_byte(AS7341_ENABLE, 0x00) |
|
|
| def isconnected(self): |
| """determine if AS7341 is successfully initialized (True/False)""" |
| return self.__connected |
|
|
| def reset(self): |
| """Cycle power and check if AS7341 is (re-)connected |
| When connected set (restore) measurement mode |
| """ |
| self.disable() |
| sleep_ms(50) |
| self.enable() |
| sleep_ms(50) |
| id = self.__read_byte(AS7341_ID) |
| if id < 0: |
| print( |
| "Failed to contact AS7341 at I2C address 0x{:02X}".format( |
| self.__address |
| ) |
| ) |
| return False |
| else: |
| if not (id & (~0x03)) == AS7341_ID_VALUE: |
| print( |
| "No AS7341: ID = 0x{:02X}, expected 0x{:02X}".format( |
| id, AS7341_ID_VALUE |
| ) |
| ) |
| return False |
| self.set_measure_mode(self.__measuremode) |
| return True |
|
|
| def measurement_completed(self): |
| """check if measurement completed (return True) or otherwise return False""" |
| return bool(self.__read_byte(AS7341_STATUS_2) & AS7341_STATUS_2_AVALID) |
|
|
| def set_spectral_measurement(self, flag=True): |
| """enable (flag == True) spectral measurement or otherwise disable it""" |
| self.__modify_reg(AS7341_ENABLE, AS7341_ENABLE_SP_EN, flag) |
|
|
| def set_smux(self, flag=True): |
| """enable (flag == True) SMUX or otherwise disable it""" |
| self.__modify_reg(AS7341_ENABLE, AS7341_ENABLE_SMUXEN, flag) |
|
|
| def set_measure_mode(self, mode=AS7341_CONFIG_INT_MODE_SPM): |
| """configure the AS7341 for a specific measurement mode |
| when interrupt needed it must be configured separately |
| """ |
| if mode in ( |
| AS7341_CONFIG_INT_MODE_SPM, |
| AS7341_CONFIG_INT_MODE_SYNS, |
| AS7341_CONFIG_INT_MODE_SYND, |
| ): |
| self.__measuremode = mode |
| self.__set_bank(1) |
| data = self.__read_byte(AS7341_CONFIG) & (~3) |
| data |= mode |
| self.__write_byte(AS7341_CONFIG, data) |
| self.__set_bank(0) |
|
|
| def channel_select(self, selection): |
| """select one from a series of predefined SMUX configurations |
| <selection> should be a key in dictionary AS7341_SMUX_SELECT |
| 20 bytes of memory starting from address 0 will be overwritten. |
| """ |
| if selection in AS7341_SMUX_SELECT: |
| self.__write_burst(0x00, AS7341_SMUX_SELECT[selection]) |
| else: |
| print(selection, "is unknown in AS7341_SMUX_SELECT") |
|
|
| def start_measure(self, selection): |
| """select SMUX configuration, prepare and start measurement""" |
| self.__modify_reg(AS7341_CFG_0, AS7341_CFG_0_LOW_POWER, False) |
| self.set_spectral_measurement(False) |
| self.__write_byte(AS7341_CFG_6, AS7341_CFG_6_SMUX_CMD_WRITE) |
| if self.__measuremode == AS7341_CONFIG_INT_MODE_SPM: |
| self.channel_select(selection) |
| self.set_smux(True) |
| elif self.__measuremode == AS7341_CONFIG_INT_MODE_SYNS: |
| self.channel_select(selection) |
| self.set_smux(True) |
| self.set_gpio_mode(AS7341_GPIO_2_GPIO_IN_EN) |
| self.set_spectral_measurement(True) |
| if self.__measuremode == AS7341_CONFIG_INT_MODE_SPM: |
| while not self.measurement_completed(): |
| sleep_ms(50) |
|
|
| def get_channel_data(self, channel): |
| """read count of a single channel (channel in range 0..5) |
| with or without measurement, just read count of one channel |
| contents depend on previous selection with 'start_measure' |
| auto-zero feature may result in value 0! |
| """ |
| data = 0 |
| if 0 <= channel <= 5: |
| data = self.__read_word(AS7341_CH_DATA + channel * 2) |
| return data |
|
|
| def get_spectral_data(self): |
| """obtain counts of all channels |
| return a tuple of 6 counts (integers) of the channels |
| contents depend on previous selection with 'start_measure' |
| """ |
| return self.__read_all_channels() |
|
|
| def set_flicker_detection(self, flag=True): |
| """enable (flag == True) flicker detection or otherwise disable it""" |
| self.__modify_reg(AS7341_ENABLE, AS7341_ENABLE_FDEN, flag) |
|
|
| def get_flicker_frequency(self): |
| """Determine flicker frequency in Hz. Returns 100, 120 or 0 |
| Integration time and gain for flicker detection is the same as for |
| other channels, the dedicated FD_TIME and FD_GAIN are not supported |
| """ |
| self.__modify_reg(AS7341_CFG_0, AS7341_CFG_0_LOW_POWER, False) |
| self.set_spectral_measurement(False) |
| self.__write_byte(AS7341_CFG_6, AS7341_CFG_6_SMUX_CMD_WRITE) |
| self.channel_select("FD") |
| self.set_smux(True) |
| self.set_spectral_measurement(True) |
| self.set_flicker_detection(True) |
| for _ in range(10): |
| fd_status = self.__read_byte(AS7341_FD_STATUS) |
| if fd_status & AS7341_FD_STATUS_FD_MEAS_VALID: |
| break |
| |
| sleep_ms(100) |
| else: |
| print("Flicker measurement timed out") |
| return 0 |
| for _ in range(10): |
| fd_status = self.__read_byte(AS7341_FD_STATUS) |
| if (fd_status & AS7341_FD_STATUS_FD_100_VALID) or ( |
| fd_status & AS7341_FD_STATUS_FD_120_VALID |
| ): |
| break |
| |
| sleep_ms(100) |
| else: |
| print("Flicker frequency calculation timed out") |
| return 0 |
| |
| self.set_flicker_detection(False) |
| self.__write_byte(AS7341_FD_STATUS, 0x3C) |
| if (fd_status & AS7341_FD_STATUS_FD_100_VALID) and ( |
| fd_status & AS7341_FD_STATUS_FD_100HZ |
| ): |
| return 100 |
| elif (fd_status & AS7341_FD_STATUS_FD_120_VALID) and ( |
| fd_status & AS7341_FD_STATUS_FD_120HZ |
| ): |
| return 120 |
| return 0 |
|
|
| def set_gpio_mode(self, mode): |
| """Configure mode of GPIO pin. |
| Allow only input-enable or output (with or without inverted) |
| specify 0x00 to reset the mode of the GPIO pin. |
| Notes: 1. It seems that GPIO_INV bit must be set |
| together with GPIO_IN_EN. |
| Proof: Use a pull-up resistor between GPIO and 3.3V: |
| - when program is ot started GPIO is high |
| - when program is started (GPIO_IN_EN=1) GPIO becomes low |
| - when also GPIO_INV=1 GPIO behaves normally |
| Maybe it is a quirk of the used test-board. |
| 2. GPIO output is not tested |
| (dataset lacks info how to set/reset GPIO) |
| """ |
| if mode in ( |
| 0x00, |
| AS7341_GPIO_2_GPIO_OUT, |
| AS7341_GPIO_2_GPIO_OUT | AS7341_GPIO_2_GPIO_INV, |
| AS7341_GPIO_2_GPIO_IN_EN, |
| AS7341_GPIO_2_GPIO_IN_EN | AS7341_GPIO_2_GPIO_INV, |
| ): |
| if mode == AS7341_GPIO_2_GPIO_IN_EN: |
| mode |= AS7341_GPIO_2_GPIO_INV |
| self.__write_byte(AS7341_GPIO_2, mode) |
|
|
| def get_gpio_value(self): |
| """Determine GPIO value (when GPIO enabled for IN_EN) |
| returns 0 (low voltage) or 1 (high voltage) |
| """ |
| |
| return self.__read_byte(AS7341_GPIO_2) & AS7341_GPIO_2_GPIO_IN |
|
|
| def set_astep(self, value): |
| """set ASTEP size (range 0..65534 -> 2.78 usec .. 182 msec)""" |
| if 0 <= value <= 65534: |
| self.__write_word(AS7341_ASTEP, value) |
|
|
| def set_atime(self, value): |
| """set number of integration steps (range 0..255 -> 1..256 ASTEPs)""" |
| self.__write_byte(AS7341_ATIME, value) |
|
|
| def get_integration_time(self): |
| """return actual total integration time (atime * astep) |
| in milliseconds (valid with SPM and SYNS measurement mode) |
| """ |
| return ( |
| (self.__read_word(AS7341_ASTEP) + 1) |
| * (self.__read_byte(AS7341_ATIME) + 1) |
| * 2.78 |
| / 1000 |
| ) |
|
|
| def set_again(self, code): |
| """set AGAIN (code in range 0..10 -> gain factor 0.5 .. 512) |
| value 0 1 2 3 4 5 6 7 8 9 10 |
| gain: *0.5 | *1 | *2 | *4 | *8 | *16 | *32 | *64 | *128 | *256 | *512 |
| """ |
| if 0 <= code <= 10: |
| self.__write_byte(AS7341_CFG_1, code) |
|
|
| def get_again(self): |
| """obtain actual gain code (in range 0 .. 10)""" |
| return self.__read_byte(AS7341_CFG_1) |
|
|
| def set_again_factor(self, factor): |
| """'inverse' of 'set_again': gain factor -> code 0 .. 10 |
| <factor> is rounded down to nearest power of 2 (in range 0.5 .. 512) |
| """ |
| code = 10 |
| gain = 512 |
| while gain > factor and code > 0: |
| gain /= 2 |
| code -= 1 |
| |
| self.__write_byte(AS7341_CFG_1, code) |
|
|
| def get_again_factor(self): |
| """obtain actual gain factor (in range 0.5 .. 512)""" |
| return 2 ** (self.__read_byte(AS7341_CFG_1) - 1) |
|
|
| def set_wen(self, flag=True): |
| """enable (flag=True) or otherwise disable use of WTIME (auto re-start)""" |
| self.__modify_reg(AS7341_ENABLE, AS7341_ENABLE_WEN, flag) |
|
|
| def set_wtime(self, wtime): |
| """set WTIME when auto-re-start is desired (in range 0 .. 0xFF) |
| 0 -> 2.78ms, 0xFF -> 711.7 ms |
| Note: The WEN bit in ENABLE should be set as well: set_wen() |
| """ |
| self.__write_byte(AS7341_WTIME, wtime) |
|
|
| def set_led_current(self, current): |
| """Control current of onboard LED in milliamperes |
| LED-current is (here) limited to the range 4..20 mA |
| use only even numbers (4,6,8,... etc) |
| Specification outside this range results in LED OFF |
| """ |
| self.__set_bank(1) |
| if 4 <= current <= 20: |
| self.__modify_reg(AS7341_CONFIG, AS7341_CONFIG_LED_SEL, True) |
| |
| data = AS7341_LED_LED_ACT + ((current - 4) // 2) |
| else: |
| self.__modify_reg(AS7341_CONFIG, AS7341_CONFIG_LED_SEL, False) |
| data = 0 |
| self.__write_byte(AS7341_LED, data) |
| |
| self.__set_bank(0) |
| sleep_ms(100) |
|
|
| def check_interrupt(self): |
| """Check for Spectral or Flicker Detect saturation interrupt""" |
| data = self.__read_byte(AS7341_STATUS) |
| if data & AS7341_STATUS_ASAT: |
| print("Spectral interrupt generation!") |
| return True |
| return False |
|
|
| def clear_interrupt(self): |
| """clear all interrupt signals""" |
| self.__write_byte(AS7341_STATUS, 0xFF) |
|
|
| def set_spectral_interrupt(self, flag=True): |
| """enable (flag == True) or otherwise disable spectral interrupts""" |
| self.__modify_reg(AS7341_INTENAB, AS7341_INTENAB_SP_IEN, flag) |
|
|
| def set_interrupt_persistence(self, value): |
| """configure interrupt persistance""" |
| if 0 <= value <= 15: |
| self.__write_byte(AS7341_PERS, value) |
|
|
| def set_spectral_threshold_channel(self, value): |
| """select channel (0..4) for interrupts, persistence and AGC""" |
| if 0 <= value <= 4: |
| self.__write_byte(AS7341_CFG_12, value) |
|
|
| def set_thresholds(self, lo, hi): |
| """Set thresholds (when lo < hi)""" |
| if lo < hi: |
| self.__write_word(AS7341_SP_TH_LOW, lo) |
| self.__write_word(AS7341_SP_TH_HIGH, hi) |
| sleep_ms(20) |
|
|
| def get_thresholds(self): |
| """obtain and return tuple with low and high threshold values""" |
| lo = self.__read_word(AS7341_SP_TH_LOW) |
| hi = self.__read_word(AS7341_SP_TH_HIGH) |
| return (lo, hi) |
|
|
| def set_syns_int(self): |
| """select SYNS mode and signal SYNS interrupt on Pin INT""" |
| self.__set_bank(1) |
| self.__write_byte( |
| AS7341_CONFIG, AS7341_CONFIG_INT_SEL | AS7341_CONFIG_INT_MODE_SYNS |
| ) |
| self.__set_bank(0) |
|
|
|
|
| |
|
|