92
92
93
93
_AS726X_NUM_CHANNELS = const (6 )
94
94
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
+
95
112
# pylint: disable=too-many-instance-attributes
96
113
# 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.
99
121
100
- :param ~busio.I2C i2c_bus: The I2C bus connected to the sensor
101
122
"""
102
123
103
124
MODE_0 = 0b00
@@ -120,18 +141,16 @@ class Adafruit_AS726x:
120
141
121
142
DRIVER_CURRENT_LIMITS = (12.5 , 25 , 50 , 100 )
122
143
123
- def __init__ (self , i2c_bus ):
144
+ def __init__ (self ):
124
145
self ._driver_led = False
125
146
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
129
150
self ._integration_time = 0
130
- self ._gain = Adafruit_AS726x .GAIN .index (1 )
151
+ self ._gain = AS726x .GAIN .index (1 )
131
152
self .buf2 = bytearray (2 )
132
153
133
- self .i2c_device = I2CDevice (i2c_bus , _AS726X_ADDRESS )
134
-
135
154
# reset device
136
155
self ._virtual_write (_AS726X_CONTROL_SETUP , 0x80 )
137
156
@@ -148,7 +167,7 @@ def __init__(self, i2c_bus):
148
167
)
149
168
150
169
self .integration_time = 140
151
- self .conversion_mode = Adafruit_AS726x .MODE_2
170
+ self .conversion_mode = AS726x .MODE_2
152
171
self .gain = 64
153
172
154
173
@property
@@ -193,14 +212,14 @@ def driver_led_current(self):
193
212
194
213
@driver_led_current .setter
195
214
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 :
197
216
raise ValueError ("Must be 12.5, 25, 50 or 100" )
198
217
if self ._driver_led_current == val :
199
218
return
200
219
self ._driver_led_current = val
201
220
state = self ._virtual_read (_AS726X_LED_CONTROL )
202
221
state &= ~ (0x3 << 4 )
203
- state = state | (Adafruit_AS726x .DRIVER_CURRENT_LIMITS .index (val ) << 4 )
222
+ state = state | (AS726x .DRIVER_CURRENT_LIMITS .index (val ) << 4 )
204
223
self ._virtual_write (_AS726X_LED_CONTROL , state )
205
224
206
225
@property
@@ -215,14 +234,14 @@ def indicator_led_current(self):
215
234
216
235
@indicator_led_current .setter
217
236
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 :
219
238
raise ValueError ("Must be 1, 2, 4 or 8" )
220
239
if self ._indicator_led_current == val :
221
240
return
222
241
self ._indicator_led_current = val
223
242
state = self ._virtual_read (_AS726X_LED_CONTROL )
224
243
state &= ~ (0x3 << 1 )
225
- state = state | (Adafruit_AS726x .INDICATOR_CURRENT_LIMITS .index (val ) << 4 )
244
+ state = state | (AS726x .INDICATOR_CURRENT_LIMITS .index (val ) << 4 )
226
245
self ._virtual_write (_AS726X_LED_CONTROL , state )
227
246
228
247
@property
@@ -253,14 +272,14 @@ def gain(self):
253
272
254
273
@gain .setter
255
274
def gain (self , val ):
256
- if val not in Adafruit_AS726x .GAIN :
275
+ if val not in AS726x .GAIN :
257
276
raise ValueError ("Must be 1, 3.7, 16 or 64" )
258
277
if self ._gain == val :
259
278
return
260
279
self ._gain = val
261
280
state = self ._virtual_read (_AS726X_CONTROL_SETUP )
262
281
state &= ~ (0x3 << 4 )
263
- state |= Adafruit_AS726x .GAIN .index (val ) << 4
282
+ state |= AS726x .GAIN .index (val ) << 4
264
283
self ._virtual_write (_AS726X_CONTROL_SETUP , state )
265
284
266
285
@property
@@ -372,6 +391,23 @@ def raw_red(self):
372
391
"""Raw red (650nm) 16-bit value"""
373
392
return self .read_channel (_AS7262_RED )
374
393
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
+
375
411
def _read_u8 (self , command ):
376
412
"""read a single byte from a specified register"""
377
413
buf = self .buf2
@@ -428,5 +464,84 @@ def _virtual_write(self, addr, value):
428
464
self .__write_u8 (_AS726X_SLAVE_WRITE_REG , value )
429
465
430
466
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
+
431
543
# pylint: enable=too-many-instance-attributes
432
544
# pylint: enable=too-many-public-methods
545
+ # pylint: enable=invalid-name
546
+ # pylint: enable=no-else-return
547
+ # pylint: enable=inconsistent-return-statements
0 commit comments