22import time
33import struct
44
5- import smbus
65from i2cdevice import Device , Register , BitField , _int_to_bytes
76from i2cdevice .adapter import Adapter , LookupAdapter
87
9- __version__ = '0.0.2 '
8+ __version__ = '0.1.0 '
109
1110
1211class as7262VirtualRegisterBus ():
@@ -19,13 +18,17 @@ class as7262VirtualRegisterBus():
1918
2019 """
2120
22- def __init__ (self , bus = 1 ):
21+ def __init__ (self , i2c_dev = None ):
2322 """Initialise virtual register class.
2423
2524 :param bus: SMBus bus ID
2625
2726 """
28- self ._i2c_bus = smbus .SMBus (bus )
27+ if i2c_dev is None :
28+ import smbus
29+ self ._i2c_bus = smbus .SMBus (1 )
30+ else :
31+ self ._i2c_bus = i2c_dev
2932
3033 def get_status (self , address ):
3134 """Return the AS7262 status register."""
@@ -86,82 +89,6 @@ def _encode(self, value):
8689 return int (value * 2.8 ) & 0xff
8790
8891
89- _as7262 = Device (0x49 , i2c_dev = as7262VirtualRegisterBus (1 ), bit_width = 8 , registers = (
90- Register ('VERSION' , 0x00 , fields = (
91- BitField ('hw_type' , 0xFF000000 ),
92- BitField ('hw_version' , 0x00FF0000 ),
93- BitField ('fw_version' , 0x0000FFFF , adapter = FWVersionAdapter ()),
94- ), bit_width = 32 , read_only = True ),
95- Register ('CONTROL' , 0x04 , fields = (
96- BitField ('reset' , 0b10000000 ),
97- BitField ('interrupt' , 0b01000000 ),
98- BitField ('gain_x' , 0b00110000 , adapter = LookupAdapter ({
99- 1 : 0b00 , 3.7 : 0b01 , 16 : 0b10 , 64 : 0b11
100- })),
101- BitField ('measurement_mode' , 0b00001100 ),
102- BitField ('data_ready' , 0b00000010 ),
103- )),
104- Register ('INTEGRATION_TIME' , 0x05 , fields = (
105- BitField ('ms' , 0xFF , adapter = IntegrationTimeAdapter ()),
106- )),
107- Register ('TEMPERATURE' , 0x06 , fields = (
108- BitField ('degrees_c' , 0xFF ),
109- )),
110- Register ('LED_CONTROL' , 0x07 , fields = (
111- BitField ('illumination_current_limit_ma' , 0b00110000 , adapter = LookupAdapter ({
112- 12.5 : 0b00 , 25 : 0b01 , 50 : 0b10 , 100 : 0b11
113- })),
114- BitField ('illumination_enable' , 0b00001000 ),
115- BitField ('indicator_current_limit_ma' , 0b00000110 , adapter = LookupAdapter ({
116- 1 : 0b00 , 2 : 0b01 , 4 : 0b10 , 8 : 0b11
117- })),
118- BitField ('indicator_enable' , 0b00000001 ),
119- )),
120- Register ('DATA' , 0x08 , fields = (
121- BitField ('v' , 0xFFFF00000000000000000000 ),
122- BitField ('b' , 0x0000FFFF0000000000000000 ),
123- BitField ('g' , 0x00000000FFFF000000000000 ),
124- BitField ('y' , 0x000000000000FFFF00000000 ),
125- BitField ('o' , 0x0000000000000000FFFF0000 ),
126- BitField ('r' , 0x00000000000000000000FFFF ),
127- ), bit_width = 96 ),
128- Register ('CALIBRATED_DATA' , 0x14 , fields = (
129- BitField ('v' , 0xFFFFFFFF << (32 * 5 ), adapter = FloatAdapter ()),
130- BitField ('b' , 0xFFFFFFFF << (32 * 4 ), adapter = FloatAdapter ()),
131- BitField ('g' , 0xFFFFFFFF << (32 * 3 ), adapter = FloatAdapter ()),
132- BitField ('y' , 0xFFFFFFFF << (32 * 2 ), adapter = FloatAdapter ()),
133- BitField ('o' , 0xFFFFFFFF << (32 * 1 ), adapter = FloatAdapter ()),
134- BitField ('r' , 0xFFFFFFFF << (32 * 0 ), adapter = FloatAdapter ()),
135- ), bit_width = 192 ),
136- ))
137-
138- # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
139- # Iterate through all register fields and export their lookup tables to constants
140- for register in _as7262 .registers :
141- register = _as7262 .registers [register ]
142- for field in register .fields :
143- field = register .fields [field ]
144- if isinstance (field .adapter , LookupAdapter ):
145- for key in field .adapter .lookup_table :
146- value = field .adapter .lookup_table [key ]
147- name = 'AS7262_{register}_{field}_{key}' .format (
148- register = register .name ,
149- field = field .name ,
150- key = key
151- ).upper ()
152- locals ()[name ] = key
153-
154-
155- def soft_reset ():
156- """Set the soft reset register bit of the AS7262."""
157- _as7262 .CONTROL .set_reset (1 )
158- # Polling for the state of the reset flag does not work here
159- # since the fragile virtual register state machine cannot
160- # respond while in a soft reset condition
161- # So, just wait long enough for it to reset fully...
162- time .sleep (2.0 )
163-
164-
16592class CalibratedValues :
16693 """Store the 6 band spectral values."""
16794
@@ -178,88 +105,149 @@ def __iter__(self): # noqa D107
178105 yield getattr (self , colour )
179106
180107
181- def get_calibrated_values (timeout = 10 ):
182- """Return an instance of CalibratedValues containing the 6 spectral bands."""
183- t_start = time .time ()
184- while _as7262 .CONTROL .get_data_ready () == 0 and (time .time () - t_start ) <= timeout :
185- pass
186- with _as7262 .CALIBRATED_DATA as DATA :
187- return CalibratedValues (DATA .get_r (),
188- DATA .get_o (),
189- DATA .get_y (),
190- DATA .get_g (),
191- DATA .get_b (),
192- DATA .get_v ())
193-
194-
195- def set_gain (gain ):
196- """Set the gain amount of the AS7262.
197-
198- :param gain: gain multiplier, one of 1, 3.7, 16 or 64
199-
200- """
201- _as7262 .CONTROL .set_gain_x (gain )
202-
203-
204- def set_measurement_mode (mode ):
205- """Set the AS7262 measurement mode.
206-
207- :param mode: 0-3
208-
209- """
210- _as7262 .CONTROL .set_measurement_mode (mode )
211-
212-
213- def set_integration_time (time_ms ):
214- """Set the AS7262 sensor integration time in milliseconds.
108+ class AS7262 :
109+ def __init__ (self , i2c_dev = None ):
110+ self ._as7262 = Device (0x49 , i2c_dev = as7262VirtualRegisterBus (i2c_dev = i2c_dev ), bit_width = 8 , registers = (
111+ Register ('VERSION' , 0x00 , fields = (
112+ BitField ('hw_type' , 0xFF000000 ),
113+ BitField ('hw_version' , 0x00FF0000 ),
114+ BitField ('fw_version' , 0x0000FFFF , adapter = FWVersionAdapter ()),
115+ ), bit_width = 32 , read_only = True ),
116+ Register ('CONTROL' , 0x04 , fields = (
117+ BitField ('reset' , 0b10000000 ),
118+ BitField ('interrupt' , 0b01000000 ),
119+ BitField ('gain_x' , 0b00110000 , adapter = LookupAdapter ({
120+ 1 : 0b00 , 3.7 : 0b01 , 16 : 0b10 , 64 : 0b11
121+ })),
122+ BitField ('measurement_mode' , 0b00001100 ),
123+ BitField ('data_ready' , 0b00000010 ),
124+ )),
125+ Register ('INTEGRATION_TIME' , 0x05 , fields = (
126+ BitField ('ms' , 0xFF , adapter = IntegrationTimeAdapter ()),
127+ )),
128+ Register ('TEMPERATURE' , 0x06 , fields = (
129+ BitField ('degrees_c' , 0xFF ),
130+ )),
131+ Register ('LED_CONTROL' , 0x07 , fields = (
132+ BitField ('illumination_current_limit_ma' , 0b00110000 , adapter = LookupAdapter ({
133+ 12.5 : 0b00 , 25 : 0b01 , 50 : 0b10 , 100 : 0b11
134+ })),
135+ BitField ('illumination_enable' , 0b00001000 ),
136+ BitField ('indicator_current_limit_ma' , 0b00000110 , adapter = LookupAdapter ({
137+ 1 : 0b00 , 2 : 0b01 , 4 : 0b10 , 8 : 0b11
138+ })),
139+ BitField ('indicator_enable' , 0b00000001 ),
140+ )),
141+ Register ('DATA' , 0x08 , fields = (
142+ BitField ('v' , 0xFFFF00000000000000000000 ),
143+ BitField ('b' , 0x0000FFFF0000000000000000 ),
144+ BitField ('g' , 0x00000000FFFF000000000000 ),
145+ BitField ('y' , 0x000000000000FFFF00000000 ),
146+ BitField ('o' , 0x0000000000000000FFFF0000 ),
147+ BitField ('r' , 0x00000000000000000000FFFF ),
148+ ), bit_width = 96 ),
149+ Register ('CALIBRATED_DATA' , 0x14 , fields = (
150+ BitField ('v' , 0xFFFFFFFF << (32 * 5 ), adapter = FloatAdapter ()),
151+ BitField ('b' , 0xFFFFFFFF << (32 * 4 ), adapter = FloatAdapter ()),
152+ BitField ('g' , 0xFFFFFFFF << (32 * 3 ), adapter = FloatAdapter ()),
153+ BitField ('y' , 0xFFFFFFFF << (32 * 2 ), adapter = FloatAdapter ()),
154+ BitField ('o' , 0xFFFFFFFF << (32 * 1 ), adapter = FloatAdapter ()),
155+ BitField ('r' , 0xFFFFFFFF << (32 * 0 ), adapter = FloatAdapter ()),
156+ ), bit_width = 192 ),
157+ ))
158+
159+ # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
160+ # Iterate through all register fields and export their lookup tables to constants
161+ for register in self ._as7262 .registers :
162+ register = self ._as7262 .registers [register ]
163+ for field in register .fields :
164+ field = register .fields [field ]
165+ if isinstance (field .adapter , LookupAdapter ):
166+ for key in field .adapter .lookup_table :
167+ value = field .adapter .lookup_table [key ]
168+ name = 'AS7262_{register}_{field}_{key}' .format (
169+ register = register .name ,
170+ field = field .name ,
171+ key = key
172+ ).upper ()
173+ locals ()[name ] = key
174+
175+ self .soft_reset ()
176+
177+ def soft_reset (self ):
178+ """Set the soft reset register bit of the AS7262."""
179+ self ._as7262 .set ('CONTROL' , reset = 1 )
180+ # Polling for the state of the reset flag does not work here
181+ # since the fragile virtual register state machine cannot
182+ # respond while in a soft reset condition
183+ # So, just wait long enough for it to reset fully...
184+ time .sleep (2.0 )
185+
186+ def get_calibrated_values (self , timeout = 10 ):
187+ """Return an instance of CalibratedValues containing the 6 spectral bands."""
188+ t_start = time .time ()
189+ while self ._as7262 .get ('CONTROL' ).data_ready == 0 and (time .time () - t_start ) <= timeout :
190+ pass
191+ data = self ._as7262 .get ('CALIBRATED_DATA' )
192+ return CalibratedValues (data .r , data .o , data .y , data .g , data .b , data .v )
193+
194+ def set_gain (self , gain ):
195+ """Set the gain amount of the AS7262.
196+
197+ :param gain: gain multiplier, one of 1, 3.7, 16 or 64
215198
216- :param time_ms: Time in milliseconds from 0 to ~91
199+ """
200+ self ._as7262 .set ('CONTROL' , gain_x = gain )
217201
218- """
219- _as7262 . INTEGRATION_TIME . set_ms ( time_ms )
202+ def set_measurement_mode ( self , mode ):
203+ """Set the AS7262 measurement mode.
220204
205+ :param mode: 0-3
221206
222- def set_illumination_led_current ( current ):
223- """Set the AS7262 illumination LED current in milliamps.
207+ """
208+ self . _as7262 . set ( 'CONTROL' , measurement_mode = mode )
224209
225- :param current: Value in milliamps, one of 12.5, 25, 50 or 100
210+ def set_integration_time (self , time_ms ):
211+ """Set the AS7262 sensor integration time in milliseconds.
226212
227- """
228- _as7262 .LED_CONTROL .set_illumination_current_limit_ma (current )
213+ :param time_ms: Time in milliseconds from 0 to ~91
229214
215+ """
216+ self ._as7262 .set ('INTEGRATION_TIME' , ms = time_ms )
230217
231- def set_indicator_led_current (current ):
232- """Set the AS7262 indicator LED current in milliamps.
233-
234- :param current: Value in milliamps, one of 1, 2, 4 or 8
218+ def set_illumination_led_current (self , current ):
219+ """Set the AS7262 illumination LED current in milliamps.
235220
236- """
237- _as7262 .LED_CONTROL .set_indicator_current_limit_ma (current )
221+ :param current: Value in milliamps, one of 12.5, 25, 50 or 100
238222
223+ """
224+ self ._as7262 .set ('LED_CONTROL' , illumination_current_limit_ma = current )
239225
240- def set_illumination_led ( state ):
241- """Set the AS7262 illumination LED state .
226+ def set_indicator_led_current ( self , current ):
227+ """Set the AS7262 indicator LED current in milliamps .
242228
243- :param state: True = On, False = Off
229+ :param current: Value in milliamps, one of 1, 2, 4 or 8
244230
245- """
246- _as7262 .LED_CONTROL . set_illumination_enable ( state )
231+ """
232+ self . _as7262 .set ( 'LED_CONTROL' , indicator_current_limit_ma = current )
247233
234+ def set_illumination_led (self , state ):
235+ """Set the AS7262 illumination LED state.
248236
249- def set_indicator_led (state ):
250- """Set the AS7262 indicator LED state.
237+ :param state: True = On, False = Off
251238
252- :param state: True = On, False = Off
239+ """
240+ self ._as7262 .set ('LED_CONTROL' , illumination_enable = state )
253241
254- """
255- _as7262 . LED_CONTROL . set_indicator_enable ( state )
242+ def set_indicator_led ( self , state ):
243+ """Set the AS7262 indicator LED state.
256244
245+ :param state: True = On, False = Off
257246
258- def get_version ():
259- """Get the hardware type, version and firmware version from the AS7262."""
260- with _as7262 .VERSION as VERSION :
261- fw_version = VERSION .get_fw_version ()
262- hw_version = VERSION .get_hw_version ()
263- hw_type = VERSION .get_hw_type ()
247+ """
248+ self ._as7262 .set ('LED_CONTROL' , indicator_enable = state )
264249
265- return hw_type , hw_version , fw_version
250+ def get_version (self ):
251+ """Get the hardware type, version and firmware version from the AS7262."""
252+ version = self ._as7262 .get ('VERSION' )
253+ return version .hw_type , version .hw_version , version .fw_version
0 commit comments