commit
8df00d8992
2 changed files with 143 additions and 20 deletions
|
|
@ -92,12 +92,33 @@ _AS7262_RED_CALIBRATED = const(0x28)
|
|||
|
||||
_AS726X_NUM_CHANNELS = const(6)
|
||||
|
||||
_COLOR_REGS = (
|
||||
_AS7262_VIOLET,
|
||||
_AS7262_BLUE,
|
||||
_AS7262_GREEN,
|
||||
_AS7262_YELLOW,
|
||||
_AS7262_ORANGE,
|
||||
_AS7262_RED,
|
||||
)
|
||||
_COLOR_REGS_CALIBRATED = (
|
||||
_AS7262_VIOLET_CALIBRATED,
|
||||
_AS7262_BLUE_CALIBRATED,
|
||||
_AS7262_GREEN_CALIBRATED,
|
||||
_AS7262_YELLOW_CALIBRATED,
|
||||
_AS7262_ORANGE_CALIBRATED,
|
||||
_AS7262_RED_CALIBRATED,
|
||||
)
|
||||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
# pylint: disable=too-many-public-methods
|
||||
class Adafruit_AS726x:
|
||||
"""AS726x spectral sensor.
|
||||
# pylint: disable=invalid-name
|
||||
# pylint: disable=no-else-return
|
||||
# pylint: disable=inconsistent-return-statements
|
||||
|
||||
|
||||
class AS726x:
|
||||
"""AS726x spectral sensor base class.
|
||||
|
||||
:param ~busio.I2C i2c_bus: The I2C bus connected to the sensor
|
||||
"""
|
||||
|
||||
MODE_0 = 0b00
|
||||
|
|
@ -120,18 +141,16 @@ class Adafruit_AS726x:
|
|||
|
||||
DRIVER_CURRENT_LIMITS = (12.5, 25, 50, 100)
|
||||
|
||||
def __init__(self, i2c_bus):
|
||||
def __init__(self):
|
||||
self._driver_led = False
|
||||
self._indicator_led = False
|
||||
self._driver_led_current = Adafruit_AS726x.DRIVER_CURRENT_LIMITS.index(12.5)
|
||||
self._indicator_led_current = Adafruit_AS726x.INDICATOR_CURRENT_LIMITS.index(1)
|
||||
self._conversion_mode = Adafruit_AS726x.MODE_2
|
||||
self._driver_led_current = AS726x.DRIVER_CURRENT_LIMITS.index(12.5)
|
||||
self._indicator_led_current = AS726x.INDICATOR_CURRENT_LIMITS.index(1)
|
||||
self._conversion_mode = AS726x.MODE_2
|
||||
self._integration_time = 0
|
||||
self._gain = Adafruit_AS726x.GAIN.index(1)
|
||||
self._gain = AS726x.GAIN.index(1)
|
||||
self.buf2 = bytearray(2)
|
||||
|
||||
self.i2c_device = I2CDevice(i2c_bus, _AS726X_ADDRESS)
|
||||
|
||||
# reset device
|
||||
self._virtual_write(_AS726X_CONTROL_SETUP, 0x80)
|
||||
|
||||
|
|
@ -148,7 +167,7 @@ class Adafruit_AS726x:
|
|||
)
|
||||
|
||||
self.integration_time = 140
|
||||
self.conversion_mode = Adafruit_AS726x.MODE_2
|
||||
self.conversion_mode = AS726x.MODE_2
|
||||
self.gain = 64
|
||||
|
||||
@property
|
||||
|
|
@ -193,14 +212,14 @@ class Adafruit_AS726x:
|
|||
|
||||
@driver_led_current.setter
|
||||
def driver_led_current(self, val):
|
||||
if val not in Adafruit_AS726x.DRIVER_CURRENT_LIMITS:
|
||||
if val not in AS726x.DRIVER_CURRENT_LIMITS:
|
||||
raise ValueError("Must be 12.5, 25, 50 or 100")
|
||||
if self._driver_led_current == val:
|
||||
return
|
||||
self._driver_led_current = val
|
||||
state = self._virtual_read(_AS726X_LED_CONTROL)
|
||||
state &= ~(0x3 << 4)
|
||||
state = state | (Adafruit_AS726x.DRIVER_CURRENT_LIMITS.index(val) << 4)
|
||||
state = state | (AS726x.DRIVER_CURRENT_LIMITS.index(val) << 4)
|
||||
self._virtual_write(_AS726X_LED_CONTROL, state)
|
||||
|
||||
@property
|
||||
|
|
@ -215,14 +234,14 @@ class Adafruit_AS726x:
|
|||
|
||||
@indicator_led_current.setter
|
||||
def indicator_led_current(self, val):
|
||||
if val not in Adafruit_AS726x.INDICATOR_CURRENT_LIMITS:
|
||||
if val not in AS726x.INDICATOR_CURRENT_LIMITS:
|
||||
raise ValueError("Must be 1, 2, 4 or 8")
|
||||
if self._indicator_led_current == val:
|
||||
return
|
||||
self._indicator_led_current = val
|
||||
state = self._virtual_read(_AS726X_LED_CONTROL)
|
||||
state &= ~(0x3 << 1)
|
||||
state = state | (Adafruit_AS726x.INDICATOR_CURRENT_LIMITS.index(val) << 4)
|
||||
state = state | (AS726x.INDICATOR_CURRENT_LIMITS.index(val) << 4)
|
||||
self._virtual_write(_AS726X_LED_CONTROL, state)
|
||||
|
||||
@property
|
||||
|
|
@ -253,14 +272,14 @@ class Adafruit_AS726x:
|
|||
|
||||
@gain.setter
|
||||
def gain(self, val):
|
||||
if val not in Adafruit_AS726x.GAIN:
|
||||
if val not in AS726x.GAIN:
|
||||
raise ValueError("Must be 1, 3.7, 16 or 64")
|
||||
if self._gain == val:
|
||||
return
|
||||
self._gain = val
|
||||
state = self._virtual_read(_AS726X_CONTROL_SETUP)
|
||||
state &= ~(0x3 << 4)
|
||||
state |= Adafruit_AS726x.GAIN.index(val) << 4
|
||||
state |= AS726x.GAIN.index(val) << 4
|
||||
self._virtual_write(_AS726X_CONTROL_SETUP, state)
|
||||
|
||||
@property
|
||||
|
|
@ -372,6 +391,23 @@ class Adafruit_AS726x:
|
|||
"""Raw red (650nm) 16-bit value"""
|
||||
return self.read_channel(_AS7262_RED)
|
||||
|
||||
def _virtual_read(self, addr):
|
||||
raise NotImplementedError("Must be implemented.")
|
||||
|
||||
def _virtual_write(self, addr, value):
|
||||
raise NotImplementedError("Must be implemented.")
|
||||
|
||||
|
||||
class AS726x_I2C(AS726x):
|
||||
"""AS726x spectral sensor via I2C.
|
||||
|
||||
:param ~busio.I2C i2c_bus: The I2C bus connected to the sensor
|
||||
"""
|
||||
|
||||
def __init__(self, i2c_bus, address=_AS726X_ADDRESS):
|
||||
self.i2c_device = I2CDevice(i2c_bus, address)
|
||||
super().__init__()
|
||||
|
||||
def _read_u8(self, command):
|
||||
"""read a single byte from a specified register"""
|
||||
buf = self.buf2
|
||||
|
|
@ -428,5 +464,84 @@ class Adafruit_AS726x:
|
|||
self.__write_u8(_AS726X_SLAVE_WRITE_REG, value)
|
||||
|
||||
|
||||
class AS726x_UART(AS726x):
|
||||
"""AS726x spectral sensor via UART.
|
||||
|
||||
:param ~busio.UART uart: The UART connected to the sensor
|
||||
"""
|
||||
|
||||
def __init__(self, uart):
|
||||
self._uart = uart
|
||||
self._uart.baudrate = 115200
|
||||
super().__init__()
|
||||
|
||||
def read_channel(self, channel):
|
||||
"""Read an individual sensor channel"""
|
||||
return self._virtual_read(channel)
|
||||
|
||||
def read_calibrated_value(self, channel):
|
||||
"""Read a calibrated sensor channel"""
|
||||
return self._virtual_read(channel)
|
||||
|
||||
def _uart_xfer(self, cmd):
|
||||
self._uart.reset_input_buffer()
|
||||
cmd += "\n"
|
||||
self._uart.write(cmd.encode())
|
||||
time.sleep(0.1)
|
||||
if self._uart.in_waiting:
|
||||
resp = self._uart.read(self._uart.in_waiting)
|
||||
return resp.rstrip(b" OK\n")
|
||||
return None
|
||||
|
||||
def _virtual_read(self, addr):
|
||||
if addr == _AS726X_HW_VERSION:
|
||||
# just return what is expected
|
||||
return 0x40
|
||||
elif addr == _AS726X_DEVICE_TEMP:
|
||||
return int(self._uart_xfer("ATTEMP"))
|
||||
elif addr == _AS726X_LED_CONTROL:
|
||||
LED_IND = int(self._uart_xfer("ATLED0"))
|
||||
LED_DRV = int(self._uart_xfer("ATLED1"))
|
||||
return LED_IND << 3 | LED_DRV
|
||||
elif addr == _AS726X_CONTROL_SETUP:
|
||||
GAIN = int(self._uart_xfer("ATGAIN"))
|
||||
BANK = int(self._uart_xfer("ATTCSMD"))
|
||||
return GAIN << 4 | BANK << 2 | 1 << 1
|
||||
elif addr in _COLOR_REGS:
|
||||
resp = self._uart_xfer("ATDATA")
|
||||
resp = resp.decode().split(",")
|
||||
return int(resp[_COLOR_REGS.index(addr)])
|
||||
elif addr in _COLOR_REGS_CALIBRATED:
|
||||
resp = self._uart_xfer("ATCDATA")
|
||||
resp = resp.decode().split(",")
|
||||
return float(resp[_COLOR_REGS_CALIBRATED.index(addr)])
|
||||
|
||||
def _virtual_write(self, addr, value):
|
||||
if addr == _AS726X_CONTROL_SETUP:
|
||||
# check for reset
|
||||
if (value >> 7) & 0x01:
|
||||
self._uart.write(b"ATRST\n")
|
||||
return
|
||||
# otherwise proceed
|
||||
GAIN = (value >> 4) & 0x03
|
||||
BANK = (value >> 2) & 0x03
|
||||
self._uart_xfer("ATGAIN={}".format(GAIN))
|
||||
self._uart_xfer("ATTCSMD={}".format(BANK))
|
||||
elif addr == _AS726X_LED_CONTROL:
|
||||
ICL_DRV = (value >> 4) & 0x07
|
||||
LED_DRV = 100 if value & 0x08 else 0
|
||||
ICL_IND = (value >> 1) & 0x07
|
||||
LED_IND = 100 if value & 0x01 else 0
|
||||
self._uart_xfer("ATLED0={}".format(LED_IND))
|
||||
self._uart_xfer("ATLED1={}".format(LED_DRV))
|
||||
self._uart_xfer("ATLEDC={}".format(ICL_DRV << 4 | ICL_IND))
|
||||
elif addr == _AS726X_INT_T:
|
||||
value = int(value / 2.8)
|
||||
self._uart_xfer("ATINTTIME={}".format(value))
|
||||
|
||||
|
||||
# pylint: enable=too-many-instance-attributes
|
||||
# pylint: enable=too-many-public-methods
|
||||
# pylint: enable=invalid-name
|
||||
# pylint: enable=no-else-return
|
||||
# pylint: enable=inconsistent-return-statements
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ import time
|
|||
import board
|
||||
import busio
|
||||
|
||||
from adafruit_as726x import Adafruit_AS726x
|
||||
# for I2C use:
|
||||
from adafruit_as726x import AS726x_I2C
|
||||
|
||||
# for UART use:
|
||||
# from adafruit_as726x import AS726x_UART
|
||||
|
||||
# maximum value for sensor reading
|
||||
max_val = 16000
|
||||
|
|
@ -16,9 +20,13 @@ def graph_map(x):
|
|||
return min(int(x * max_graph / max_val), max_graph)
|
||||
|
||||
|
||||
# Initialize I2C bus and sensor.
|
||||
# for I2C use:
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
sensor = Adafruit_AS726x(i2c)
|
||||
sensor = AS726x_I2C(i2c)
|
||||
|
||||
# for UART use:
|
||||
# uart = busio.UART(board.TX, board.RX)
|
||||
# sensor = AS726x_UART(uart)
|
||||
|
||||
sensor.conversion_mode = sensor.MODE_2
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue