Skip to content

Commit 4cb5090

Browse files
committed
Merge branch 'i2cdevice-next'
2 parents be831ec + 1b2f89b commit 4cb5090

File tree

7 files changed

+152
-153
lines changed

7 files changed

+152
-153
lines changed

examples/bargraph.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import time
22
import os
33
import sys
4-
import as7262
4+
from as7262 import AS7262
5+
6+
as7262 = AS7262()
57

68
BAR_CHAR = u'\u2588'
79

@@ -14,7 +16,6 @@
1416
MAX_VALUE = 14000.0
1517
BAR_WIDTH = 25
1618

17-
as7262.soft_reset()
1819
as7262.set_gain(64)
1920
as7262.set_integration_time(17.857)
2021
as7262.set_measurement_mode(2)

examples/spectrum.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import as7262
1+
from as7262 import AS7262
2+
3+
as7262 = AS7262()
24

3-
as7262.soft_reset()
45
as7262.set_gain(64)
56
as7262.set_integration_time(17.857)
67
as7262.set_measurement_mode(2)

library/CHANGELOG.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
0.1.0
2+
-----
3+
4+
* Port to new i2cdevice API
5+
* Breaking change from singleton module to AS7262 class
6+
17
0.0.2
28
-----
39

library/as7262/__init__.py

Lines changed: 133 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
import time
33
import struct
44

5-
import smbus
65
from i2cdevice import Device, Register, BitField, _int_to_bytes
76
from i2cdevice.adapter import Adapter, LookupAdapter
87

9-
__version__ = '0.0.2'
8+
__version__ = '0.1.0'
109

1110

1211
class 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-
16592
class 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

library/setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
setup(
4141
name='as7262',
42-
version='0.0.2',
42+
version='0.1.0',
4343
author='Philip Howard',
4444
author_email='phil@pimoroni.com',
4545
description="""Python library for the spectral sensor""",
@@ -50,5 +50,5 @@
5050
project_urls={'GitHub': 'https://www.github.com/pimoroni/as7262-python'},
5151
classifiers=classifiers,
5252
packages=['as7262'],
53-
install_requires=['i2cdevice']
53+
install_requires=['i2cdevice>=0.0.6']
5454
)

library/tests/test_features.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ def _setup():
99
smbus = mock.Mock()
1010
smbus.SMBus = SMBusFakeAS7262
1111
sys.modules['smbus'] = smbus
12-
import as7262
12+
from as7262 import AS7262
13+
as7262 = AS7262()
1314

1415

1516
def test_set_integration_time():

0 commit comments

Comments
 (0)