1- import 'dart:async' ;
21import 'package:pslab/communication/peripherals/i2c.dart' ;
32import 'package:pslab/communication/science_lab.dart' ;
43import 'package:pslab/others/logger_service.dart' ;
54
65class TSL2561 {
76 static const String tag = "TSL2561" ;
87
8+ static const List <int > addresses = [0x39 , 0x29 , 0x49 ];
9+
910 static const int commandBit = 0x80 ;
1011 static const int wordBit = 0x20 ;
1112
@@ -18,116 +19,118 @@ class TSL2561 {
1819 static const int registerChan0Low = 0x0C ;
1920 static const int registerChan1Low = 0x0E ;
2021
21- static const int integrationTime13ms = 0x00 ;
22- static const int integrationTime101ms = 0x01 ;
23- static const int integrationTime402ms = 0x02 ;
24-
25- static const int gain0x = 0x00 ;
26- static const int gain16x = 0x10 ;
22+ static const int integrationTime13Ms = 0x00 ;
23+ static const int integrationTime101Ms = 0x01 ;
24+ static const int integrationTime402Ms = 0x02 ;
2725
28- static const List <int > addresses = [0x39 , 0x29 , 0x49 ];
26+ static const int gain0X = 0x00 ;
27+ static const int gain16X = 0x10 ;
2928
3029 final I2C i2c;
31- int address = 0x39 ;
32- int timing = integrationTime13ms;
33- int gain = gain16x;
34-
35- TSL2561 (this .i2c, ScienceLab scienceLab) {
36- () async {
37- if (scienceLab.isConnected ()) {
38- for (final addr in addresses) {
39- address = addr;
40- await disable ();
41- logger.d ("$tag : Checking address 0x${address .toRadixString (16 )}" );
42- try {
43- int id = await i2c.readByte (address, registerId);
44- if (id != 0xffffffff && (id & 0x0A ) == 0x0A ) {
45- logger.d ("$tag : TSL2561 found!" );
46- break ;
47- } else {
48- logger.d ("$tag : TSL2561 not found." );
49- }
50- } catch (e) {
51- logger.e ("$tag : Error reading ID: $e " );
52- }
53- }
54- await enable ();
55- await _wait ();
56- await i2c
57- .writeBulk (address, [commandBit | registerTiming, timing | gain]);
58- }
59- }();
30+ int ? _address;
31+ int _timing = integrationTime13Ms;
32+ int _gain = gain16X;
33+
34+ double fullSpectrum = 0.0 ;
35+ double infrared = 0.0 ;
36+ double visible = 0.0 ;
37+
38+ TSL2561 ._(this .i2c);
39+
40+ static Future <TSL2561 > create (I2C i2c, ScienceLab scienceLab) async {
41+ final tsl2561 = TSL2561 ._(i2c);
42+ await tsl2561._initializeSensor (scienceLab);
43+ return tsl2561;
6044 }
6145
62- Future <int > getID () async {
63- try {
64- List <int > idList = await i2c.readBulk (address, registerId, 1 );
65- if (idList.isEmpty) return - 1 ;
66- int id = int .parse (idList[0 ].toRadixString (16 ), radix: 16 );
67- logger.d ("$tag : ID: $id " );
68- return id;
69- } catch (e) {
70- logger.e ("$tag : Error getting ID: $e " );
71- rethrow ;
46+ Future <void > _initializeSensor (ScienceLab scienceLab) async {
47+ if (! scienceLab.isConnected ()) {
48+ throw Exception ("ScienceLab not connected" );
7249 }
73- }
7450
75- Future <double ?> getRaw () async {
51+ bool sensorFound = false ;
52+
7653 try {
77- List <int > infraList = await i2c.readBulk (
78- address, commandBit | wordBit | registerChan1Low, 2 );
79- List <int > fullList = await i2c.readBulk (
80- address, commandBit | wordBit | registerChan0Low, 2 );
54+ for (int addr in addresses) {
55+ _address = addr;
56+ await disable ();
8157
82- if (infraList.isNotEmpty && fullList.isNotEmpty) {
83- int full = ((fullList[1 ] & 0xff ) << 8 ) | (fullList[0 ] & 0xff );
84- int infra = ((infraList[1 ] & 0xff ) << 8 ) | (infraList[0 ] & 0xff );
85- return (full - infra).toDouble ();
86- } else {
87- return 0.0 ;
58+ logger.d ("$tag : Checking address 0x${addr .toRadixString (16 )}" );
59+
60+ List <int > idData = await i2c.readBulk (addr, registerId | commandBit, 1 );
61+
62+ if (idData.isNotEmpty) {
63+ int id = idData[0 ];
64+ logger.d (
65+ "$tag : RAW ID READ at 0x${addr .toRadixString (16 )} is: 0x${id .toRadixString (16 )} (Decimal: $id )" );
66+
67+ if (id != 255 ) {
68+ logger.d ("$tag : Sensor accepted at 0x${addr .toRadixString (16 )}!" );
69+ sensorFound = true ;
70+ break ;
71+ }
72+ }
73+ }
74+
75+ if (! sensorFound) {
76+ throw Exception (
77+ 'TSL2561 sensor not found on I2C bus. Check SDA/SCL wiring.' );
8878 }
89- } catch (e) {
90- logger.e ("$tag : Error reading raw values: $e " );
91- return 0.0 ;
92- }
93- }
9479
95- Future <void > setGain (int gainValue) async {
96- switch (gainValue) {
97- case 1 :
98- gain = gain0x;
99- break ;
100- case 16 :
101- gain = gain16x;
102- break ;
103- default :
104- gain = gain16x;
80+ await enable ();
81+ await Future .delayed (const Duration (milliseconds: 15 ));
82+ await setGainAndTiming (_gain, _timing);
83+ } catch (e) {
84+ logger.e ("Error initializing TSL2561: $e " );
85+ rethrow ;
10586 }
106- await i2c.writeBulk (address, [commandBit | registerTiming, gain | timing]);
10787 }
10888
10989 Future <void > enable () async {
110- await i2c
111- . writeBulk (address , [commandBit | registerControl, controlPowerOn] );
90+ if (_address == null ) return ;
91+ await i2c. write (_address ! , [controlPowerOn], commandBit | registerControl);
11292 }
11393
11494 Future <void > disable () async {
115- await i2c
116- . writeBulk (address , [commandBit | registerControl, controlPowerOff] );
95+ if (_address == null ) return ;
96+ await i2c. write (_address ! , [controlPowerOff], commandBit | registerControl);
11797 }
11898
119- Future <void > _wait () async {
120- switch (timing) {
121- case integrationTime13ms:
122- await Future .delayed (const Duration (milliseconds: 14 ));
123- break ;
124- case integrationTime101ms:
125- await Future .delayed (const Duration (milliseconds: 102 ));
126- break ;
127- case integrationTime402ms:
128- default :
129- await Future .delayed (const Duration (milliseconds: 403 ));
130- break ;
99+ Future <void > setGainAndTiming (int gain, int timing) async {
100+ if (_address == null ) return ;
101+ _gain = gain;
102+ _timing = timing;
103+ await i2c.write (_address! , [_gain | _timing], commandBit | registerTiming);
104+ }
105+
106+ Future <Map <String , double >> getRawData () async {
107+ if (_address == null ) throw Exception ("Sensor not initialized" );
108+
109+ try {
110+ List <int > infraList = await i2c.readBulk (
111+ _address! , commandBit | wordBit | registerChan1Low, 2 );
112+ List <int > fullList = await i2c.readBulk (
113+ _address! , commandBit | wordBit | registerChan0Low, 2 );
114+
115+ if (infraList.length >= 2 && fullList.length >= 2 ) {
116+ int fullInt = ((fullList[1 ] & 0xFF ) << 8 ) | (fullList[0 ] & 0xFF );
117+ int infraInt = ((infraList[1 ] & 0xFF ) << 8 ) | (infraList[0 ] & 0xFF );
118+
119+ fullSpectrum = fullInt.toDouble ();
120+ infrared = infraInt.toDouble ();
121+ visible = (fullInt - infraInt).toDouble ();
122+
123+ return {
124+ 'full' : fullSpectrum,
125+ 'infrared' : infrared,
126+ 'visible' : visible,
127+ };
128+ } else {
129+ throw Exception ("Incomplete data received from TSL2561" );
130+ }
131+ } catch (e) {
132+ logger.e ("Error getting raw data: $e " );
133+ rethrow ;
131134 }
132135 }
133136}
0 commit comments