Skip to content

Commit 8df00d8

Browse files
authored
Merge pull request #14 from caternuson/uart
Add UART support
2 parents 7983c0f + c15610e commit 8df00d8

File tree

2 files changed

+143
-20
lines changed

2 files changed

+143
-20
lines changed

adafruit_as726x.py

Lines changed: 132 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,33 @@
9292

9393
_AS726X_NUM_CHANNELS = const(6)
9494

95+
_COLOR_REGS = (
96+
_AS7262_VIOLET,
97+
_AS7262_BLUE,
98+
_AS7262_GREEN,
99+
_AS7262_YELLOW,
100+
_AS7262_ORANGE,
101+
_AS7262_RED,
102+
)
103+
_COLOR_REGS_CALIBRATED = (
104+
_AS7262_VIOLET_CALIBRATED,
105+
_AS7262_BLUE_CALIBRATED,
106+
_AS7262_GREEN_CALIBRATED,
107+
_AS7262_YELLOW_CALIBRATED,
108+
_AS7262_ORANGE_CALIBRATED,
109+
_AS7262_RED_CALIBRATED,
110+
)
111+
95112
# pylint: disable=too-many-instance-attributes
96113
# pylint: disable=too-many-public-methods
97-
class Adafruit_AS726x:
98-
"""AS726x spectral sensor.
114+
# pylint: disable=invalid-name
115+
# pylint: disable=no-else-return
116+
# pylint: disable=inconsistent-return-statements
117+
118+
119+
class AS726x:
120+
"""AS726x spectral sensor base class.
99121
100-
:param ~busio.I2C i2c_bus: The I2C bus connected to the sensor
101122
"""
102123

103124
MODE_0 = 0b00
@@ -120,18 +141,16 @@ class Adafruit_AS726x:
120141

121142
DRIVER_CURRENT_LIMITS = (12.5, 25, 50, 100)
122143

123-
def __init__(self, i2c_bus):
144+
def __init__(self):
124145
self._driver_led = False
125146
self._indicator_led = False
126-
self._driver_led_current = Adafruit_AS726x.DRIVER_CURRENT_LIMITS.index(12.5)
127-
self._indicator_led_current = Adafruit_AS726x.INDICATOR_CURRENT_LIMITS.index(1)
128-
self._conversion_mode = Adafruit_AS726x.MODE_2
147+
self._driver_led_current = AS726x.DRIVER_CURRENT_LIMITS.index(12.5)
148+
self._indicator_led_current = AS726x.INDICATOR_CURRENT_LIMITS.index(1)
149+
self._conversion_mode = AS726x.MODE_2
129150
self._integration_time = 0
130-
self._gain = Adafruit_AS726x.GAIN.index(1)
151+
self._gain = AS726x.GAIN.index(1)
131152
self.buf2 = bytearray(2)
132153

133-
self.i2c_device = I2CDevice(i2c_bus, _AS726X_ADDRESS)
134-
135154
# reset device
136155
self._virtual_write(_AS726X_CONTROL_SETUP, 0x80)
137156

@@ -148,7 +167,7 @@ def __init__(self, i2c_bus):
148167
)
149168

150169
self.integration_time = 140
151-
self.conversion_mode = Adafruit_AS726x.MODE_2
170+
self.conversion_mode = AS726x.MODE_2
152171
self.gain = 64
153172

154173
@property
@@ -193,14 +212,14 @@ def driver_led_current(self):
193212

194213
@driver_led_current.setter
195214
def driver_led_current(self, val):
196-
if val not in Adafruit_AS726x.DRIVER_CURRENT_LIMITS:
215+
if val not in AS726x.DRIVER_CURRENT_LIMITS:
197216
raise ValueError("Must be 12.5, 25, 50 or 100")
198217
if self._driver_led_current == val:
199218
return
200219
self._driver_led_current = val
201220
state = self._virtual_read(_AS726X_LED_CONTROL)
202221
state &= ~(0x3 << 4)
203-
state = state | (Adafruit_AS726x.DRIVER_CURRENT_LIMITS.index(val) << 4)
222+
state = state | (AS726x.DRIVER_CURRENT_LIMITS.index(val) << 4)
204223
self._virtual_write(_AS726X_LED_CONTROL, state)
205224

206225
@property
@@ -215,14 +234,14 @@ def indicator_led_current(self):
215234

216235
@indicator_led_current.setter
217236
def indicator_led_current(self, val):
218-
if val not in Adafruit_AS726x.INDICATOR_CURRENT_LIMITS:
237+
if val not in AS726x.INDICATOR_CURRENT_LIMITS:
219238
raise ValueError("Must be 1, 2, 4 or 8")
220239
if self._indicator_led_current == val:
221240
return
222241
self._indicator_led_current = val
223242
state = self._virtual_read(_AS726X_LED_CONTROL)
224243
state &= ~(0x3 << 1)
225-
state = state | (Adafruit_AS726x.INDICATOR_CURRENT_LIMITS.index(val) << 4)
244+
state = state | (AS726x.INDICATOR_CURRENT_LIMITS.index(val) << 4)
226245
self._virtual_write(_AS726X_LED_CONTROL, state)
227246

228247
@property
@@ -253,14 +272,14 @@ def gain(self):
253272

254273
@gain.setter
255274
def gain(self, val):
256-
if val not in Adafruit_AS726x.GAIN:
275+
if val not in AS726x.GAIN:
257276
raise ValueError("Must be 1, 3.7, 16 or 64")
258277
if self._gain == val:
259278
return
260279
self._gain = val
261280
state = self._virtual_read(_AS726X_CONTROL_SETUP)
262281
state &= ~(0x3 << 4)
263-
state |= Adafruit_AS726x.GAIN.index(val) << 4
282+
state |= AS726x.GAIN.index(val) << 4
264283
self._virtual_write(_AS726X_CONTROL_SETUP, state)
265284

266285
@property
@@ -372,6 +391,23 @@ def raw_red(self):
372391
"""Raw red (650nm) 16-bit value"""
373392
return self.read_channel(_AS7262_RED)
374393

394+
def _virtual_read(self, addr):
395+
raise NotImplementedError("Must be implemented.")
396+
397+
def _virtual_write(self, addr, value):
398+
raise NotImplementedError("Must be implemented.")
399+
400+
401+
class AS726x_I2C(AS726x):
402+
"""AS726x spectral sensor via I2C.
403+
404+
:param ~busio.I2C i2c_bus: The I2C bus connected to the sensor
405+
"""
406+
407+
def __init__(self, i2c_bus, address=_AS726X_ADDRESS):
408+
self.i2c_device = I2CDevice(i2c_bus, address)
409+
super().__init__()
410+
375411
def _read_u8(self, command):
376412
"""read a single byte from a specified register"""
377413
buf = self.buf2
@@ -428,5 +464,84 @@ def _virtual_write(self, addr, value):
428464
self.__write_u8(_AS726X_SLAVE_WRITE_REG, value)
429465

430466

467+
class AS726x_UART(AS726x):
468+
"""AS726x spectral sensor via UART.
469+
470+
:param ~busio.UART uart: The UART connected to the sensor
471+
"""
472+
473+
def __init__(self, uart):
474+
self._uart = uart
475+
self._uart.baudrate = 115200
476+
super().__init__()
477+
478+
def read_channel(self, channel):
479+
"""Read an individual sensor channel"""
480+
return self._virtual_read(channel)
481+
482+
def read_calibrated_value(self, channel):
483+
"""Read a calibrated sensor channel"""
484+
return self._virtual_read(channel)
485+
486+
def _uart_xfer(self, cmd):
487+
self._uart.reset_input_buffer()
488+
cmd += "\n"
489+
self._uart.write(cmd.encode())
490+
time.sleep(0.1)
491+
if self._uart.in_waiting:
492+
resp = self._uart.read(self._uart.in_waiting)
493+
return resp.rstrip(b" OK\n")
494+
return None
495+
496+
def _virtual_read(self, addr):
497+
if addr == _AS726X_HW_VERSION:
498+
# just return what is expected
499+
return 0x40
500+
elif addr == _AS726X_DEVICE_TEMP:
501+
return int(self._uart_xfer("ATTEMP"))
502+
elif addr == _AS726X_LED_CONTROL:
503+
LED_IND = int(self._uart_xfer("ATLED0"))
504+
LED_DRV = int(self._uart_xfer("ATLED1"))
505+
return LED_IND << 3 | LED_DRV
506+
elif addr == _AS726X_CONTROL_SETUP:
507+
GAIN = int(self._uart_xfer("ATGAIN"))
508+
BANK = int(self._uart_xfer("ATTCSMD"))
509+
return GAIN << 4 | BANK << 2 | 1 << 1
510+
elif addr in _COLOR_REGS:
511+
resp = self._uart_xfer("ATDATA")
512+
resp = resp.decode().split(",")
513+
return int(resp[_COLOR_REGS.index(addr)])
514+
elif addr in _COLOR_REGS_CALIBRATED:
515+
resp = self._uart_xfer("ATCDATA")
516+
resp = resp.decode().split(",")
517+
return float(resp[_COLOR_REGS_CALIBRATED.index(addr)])
518+
519+
def _virtual_write(self, addr, value):
520+
if addr == _AS726X_CONTROL_SETUP:
521+
# check for reset
522+
if (value >> 7) & 0x01:
523+
self._uart.write(b"ATRST\n")
524+
return
525+
# otherwise proceed
526+
GAIN = (value >> 4) & 0x03
527+
BANK = (value >> 2) & 0x03
528+
self._uart_xfer("ATGAIN={}".format(GAIN))
529+
self._uart_xfer("ATTCSMD={}".format(BANK))
530+
elif addr == _AS726X_LED_CONTROL:
531+
ICL_DRV = (value >> 4) & 0x07
532+
LED_DRV = 100 if value & 0x08 else 0
533+
ICL_IND = (value >> 1) & 0x07
534+
LED_IND = 100 if value & 0x01 else 0
535+
self._uart_xfer("ATLED0={}".format(LED_IND))
536+
self._uart_xfer("ATLED1={}".format(LED_DRV))
537+
self._uart_xfer("ATLEDC={}".format(ICL_DRV << 4 | ICL_IND))
538+
elif addr == _AS726X_INT_T:
539+
value = int(value / 2.8)
540+
self._uart_xfer("ATINTTIME={}".format(value))
541+
542+
431543
# pylint: enable=too-many-instance-attributes
432544
# pylint: enable=too-many-public-methods
545+
# pylint: enable=invalid-name
546+
# pylint: enable=no-else-return
547+
# pylint: enable=inconsistent-return-statements

examples/as726x_simpletest.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import board
44
import busio
55

6-
from adafruit_as726x import Adafruit_AS726x
6+
# for I2C use:
7+
from adafruit_as726x import AS726x_I2C
8+
9+
# for UART use:
10+
# from adafruit_as726x import AS726x_UART
711

812
# maximum value for sensor reading
913
max_val = 16000
@@ -16,9 +20,13 @@ def graph_map(x):
1620
return min(int(x * max_graph / max_val), max_graph)
1721

1822

19-
# Initialize I2C bus and sensor.
23+
# for I2C use:
2024
i2c = busio.I2C(board.SCL, board.SDA)
21-
sensor = Adafruit_AS726x(i2c)
25+
sensor = AS726x_I2C(i2c)
26+
27+
# for UART use:
28+
# uart = busio.UART(board.TX, board.RX)
29+
# sensor = AS726x_UART(uart)
2230

2331
sensor.conversion_mode = sensor.MODE_2
2432

0 commit comments

Comments
 (0)