66 * - Self-calibrating thresholds based on ambient conditions
77 * - High threshold crossing detection
88 * - Low threshold crossing detection
9- * - Status register polling (INT pin not required)
9+ * - Status register AINT bit verification
10+ * - Physical INT pin verification (active low)
1011 *
1112 * Hardware: AS7343 on I2C, NeoPixel ring (16 LEDs) on pin 6
13+ * AS7343 INT pin connected to Arduino pin 2
14+ * Board: Metro Mini (arduino:avr:uno)
1215 */
1316
1417#include < Adafruit_AS7343.h>
1518#include < Adafruit_NeoPixel.h>
1619
1720#define NEOPIXEL_PIN 6
1821#define NEOPIXEL_COUNT 16
22+ #define INT_PIN 2 // AS7343 INT pin connected here (active low)
1923
2024Adafruit_AS7343 as7343;
2125Adafruit_NeoPixel pixels (NEOPIXEL_COUNT , NEOPIXEL_PIN , NEO_GRB + NEO_KHZ800 );
2226
2327uint16_t allChannels[18 ];
28+ bool statusTestPass = true ;
29+ bool intPinTestPass = true ;
2430
2531// Helper to wait for data ready with timeout
2632bool waitForData (uint16_t timeoutMs = 2000 ) {
2733 uint32_t start = millis ();
2834 while (!as7343.dataReady ()) {
29- if (millis () - start > timeoutMs) {
35+ if (millis () - start > timeoutMs)
3036 return false ;
31- }
3237 delay (10 );
3338 }
3439 return true ;
3540}
3641
37- // Take a measurement and return FZ channel value
38- uint16_t measureFZ () {
42+ // Take a measurement and return CH0 value
43+ uint16_t measureCH0 () {
3944 as7343.stopMeasurement ();
4045 delay (10 );
4146 as7343.clearStatus ();
@@ -47,7 +52,7 @@ uint16_t measureFZ() {
4752 }
4853
4954 as7343.readAllChannels (allChannels);
50- return allChannels[AS7343_CHANNEL_FZ ];
55+ return allChannels[0 ]; // CH0 in 6-channel mode
5156}
5257
5358void setup () {
@@ -57,8 +62,12 @@ void setup() {
5762
5863 Serial.println (F (" AS7343 Spectral Interrupt Test" ));
5964 Serial.println (F (" ==============================" ));
65+ Serial.println (F (" INT pin: D2 (active low)" ));
6066 Serial.println ();
6167
68+ // Initialize INT pin as input with pull-up
69+ pinMode (INT_PIN , INPUT_PULLUP );
70+
6271 // Initialize NeoPixels
6372 pixels.begin ();
6473 pixels.clear ();
@@ -72,183 +81,225 @@ void setup() {
7281 delay (100 );
7382 }
7483
75- // Use low gain to avoid saturation
76- as7343.setGain (AS7343_GAIN_16X );
77- as7343.setATIME (29 ); // 30 cycles
78- as7343.setASTEP (599 ); // ~1.67ms step -> ~50ms total
79-
80- // Set threshold channel to 0 (FZ)
81- as7343.setThresholdChannel (0 );
84+ // Use 6-channel mode, low gain
85+ as7343.setSMUXMode (AS7343_SMUX_6CH );
86+ as7343.setGain (AS7343_GAIN_4X );
87+ as7343.setATIME (29 );
88+ as7343.setASTEP (599 );
8289
8390 // =====================
84- // CALIBRATION PHASE
91+ // CALIBRATION
8592 // =====================
86- Serial.println (F (" CALIBRATION :" ));
93+ Serial.println (F (" Calibration :" ));
8794
8895 // Baseline: NeoPixels OFF
8996 pixels.clear ();
9097 pixels.show ();
9198 delay (100 );
9299
93- uint16_t baseline = measureFZ ();
94- Serial.print (F (" NeoPixels OFF baseline (FZ ): " ));
100+ uint16_t baseline = measureCH0 ();
101+ Serial.print (F (" NeoPixels OFF (CH0 ): " ));
95102 Serial.println (baseline);
96103
97- // Peak: NeoPixels ON bright
104+ // Peak: NeoPixels ON
98105 for (int i = 0 ; i < NEOPIXEL_COUNT ; i++) {
99- pixels.setPixelColor (i, pixels. Color ( 255 , 255 , 255 ));
106+ pixels.setPixelColor (i, 0 , 0 , 255 ); // Blue
100107 }
101108 pixels.show ();
102109 delay (100 );
103110
104- uint16_t peak = measureFZ ();
105- Serial.print (F (" NeoPixels ON peak (FZ ): " ));
111+ uint16_t peak = measureCH0 ();
112+ Serial.print (F (" NeoPixels ON (CH0 ): " ));
106113 Serial.println (peak);
107114
108115 // Calculate thresholds
109116 uint16_t range = peak - baseline;
110- uint16_t lowThresh = baseline + (range / 4 ); // 25% of range
111- uint16_t highThresh = baseline + (3 * range / 4 ); // 75% of range
117+ uint16_t lowThresh = baseline + (range / 4 );
118+ uint16_t highThresh = baseline + (3 * range / 4 );
112119
113- Serial.print (F (" Calculated thresholds: low= " ));
114- Serial.print (lowThresh);
115- Serial.print (F (" high= " ));
120+ Serial.print (F (" Low threshold: " ));
121+ Serial.println (lowThresh);
122+ Serial.print (F (" High threshold: " ));
116123 Serial.println (highThresh);
117124 Serial.println ();
118125
119- // Turn off NeoPixels
120- pixels.clear ();
121- pixels.show ();
122-
123126 // =====================
124- // INTERRUPT SETUP
127+ // SETUP INTERRUPTS
125128 // =====================
126- Serial.println (F (" INTERRUPT TEST:" ));
127-
128- // Set thresholds
129129 as7343.setLowThreshold (lowThresh);
130130 as7343.setHighThreshold (highThresh);
131+ as7343.setPersistence (0 ); // Immediate
132+ as7343.setThresholdChannel (0 );
131133
132- // Verify readback
133- uint16_t readLow = as7343.getLowThreshold ();
134- uint16_t readHigh = as7343.getHighThreshold ();
135-
136- Serial.print (F (" Thresholds set: low=" ));
137- Serial.print (readLow);
138- Serial.print (F (" high=" ));
139- Serial.println (readHigh);
134+ // Clear any pending interrupts
135+ as7343.clearStatus ();
136+ delay (10 );
140137
141- // Set persistence to 1 (trigger after 1 consecutive reading)
142- as7343.setPersistence (1 );
143- Serial.print (F (" Persistence: " ));
144- Serial.println (as7343.getPersistence ());
138+ // Check INT pin is HIGH (no interrupt) after clear
139+ bool intPinIdle = digitalRead (INT_PIN );
140+ Serial.print (F (" INT pin after clear: " ));
141+ Serial.println (intPinIdle ? F (" HIGH (good)" ) : F (" LOW (unexpected)" ));
142+ if (!intPinIdle) {
143+ Serial.println (F (" Warning: INT pin stuck low" ));
144+ }
145145 Serial.println ();
146146
147147 // Enable spectral interrupt
148148 as7343.enableSpectralInterrupt (true );
149149
150- bool highTestPass = false ;
151- bool lowTestPass = false ;
152-
153150 // =====================
154151 // HIGH THRESHOLD TEST
155152 // =====================
156- Serial.println (F (" High threshold test:" ));
153+ Serial.println (F (" High threshold test (NeoPixels ON) :" ));
157154
158- // Turn NeoPixels ON bright
155+ // NeoPixels ON
159156 for (int i = 0 ; i < NEOPIXEL_COUNT ; i++) {
160- pixels.setPixelColor (i, pixels. Color ( 255 , 255 , 255 ) );
157+ pixels.setPixelColor (i, 0 , 0 , 255 );
161158 }
162159 pixels.show ();
163- delay (100 );
160+ delay (50 );
164161
165- // Clear status and start measurement
162+ // Start measurement, prime pipeline, then check
166163 as7343.clearStatus ();
167164 as7343.startMeasurement ();
168165
166+ // First cycle - prime
169167 if (!waitForData ()) {
170- Serial.println (F (" ERROR: Measurement timeout" ));
168+ Serial.println (F (" ERROR: Timeout" ));
169+ statusTestPass = false ;
170+ }
171+ as7343.readAllChannels (allChannels);
172+ as7343.clearStatus ();
173+
174+ // Second cycle - actual test
175+ if (!waitForData ()) {
176+ Serial.println (F (" ERROR: Timeout" ));
177+ statusTestPass = false ;
171178 } else {
172179 as7343.readAllChannels (allChannels);
173- uint16_t reading = allChannels[AS7343_CHANNEL_FZ ];
180+ uint16_t reading = allChannels[0 ];
174181
175- // Check status for AINT bit (bit 3 = 0x08)
176182 uint8_t status = as7343.getStatus ();
177183 bool aintSet = (status & 0x08 ) != 0 ;
178-
179- Serial.print (F (" NeoPixels ON, reading: " ));
180- Serial.println (reading);
181- Serial.print (F (" Status: 0x" ));
182- if (status < 0x10 ) Serial.print (F (" 0" ));
183- Serial.print (status, HEX );
184- Serial.print (F (" , AINT bit: " ));
185- Serial.println (aintSet ? F (" SET" ) : F (" CLEAR" ));
186-
187- // Should trigger because reading > highThresh
188- highTestPass = aintSet && (reading > highThresh);
189-
190- Serial.print (F (" Result: " ));
191- Serial.println (highTestPass ? F (" PASS" ) : F (" FAIL" ));
184+ bool intPinLow = !digitalRead (INT_PIN );
185+
186+ Serial.print (F (" CH0 reading: " ));
187+ Serial.print (reading);
188+ Serial.print (F (" (threshold: " ));
189+ Serial.print (highThresh);
190+ Serial.println (F (" )" ));
191+
192+ Serial.print (F (" Status AINT: " ));
193+ Serial.print (aintSet ? F (" SET" ) : F (" CLEAR" ));
194+ bool statusOK = aintSet && (reading > highThresh);
195+ Serial.println (statusOK ? F (" PASS" ) : F (" FAIL" ));
196+ if (!statusOK)
197+ statusTestPass = false ;
198+
199+ Serial.print (F (" INT pin: " ));
200+ Serial.print (intPinLow ? F (" LOW (active)" ) : F (" HIGH" ));
201+ Serial.println (intPinLow ? F (" PASS" ) : F (" FAIL" ));
202+ if (!intPinLow)
203+ intPinTestPass = false ;
204+
205+ // Verify clear works
206+ as7343.clearStatus ();
207+ delay (5 );
208+ bool intPinAfterClear = digitalRead (INT_PIN );
209+ Serial.print (F (" After clear: " ));
210+ Serial.print (intPinAfterClear ? F (" HIGH" ) : F (" LOW" ));
211+ Serial.println (intPinAfterClear ? F (" PASS" ) : F (" FAIL" ));
212+ if (!intPinAfterClear)
213+ intPinTestPass = false ;
192214 }
215+
216+ as7343.stopMeasurement ();
193217 Serial.println ();
194218
195219 // =====================
196220 // LOW THRESHOLD TEST
197221 // =====================
198- Serial.println (F (" Low threshold test:" ));
222+ Serial.println (F (" Low threshold test (NeoPixels OFF) :" ));
199223
200- // Turn NeoPixels OFF
224+ // NeoPixels OFF
201225 pixels.clear ();
202226 pixels.show ();
203- delay (100 );
227+ delay (50 );
204228
205- // Clear status and start measurement
229+ // Start measurement, prime pipeline, then check
206230 as7343.clearStatus ();
207231 as7343.startMeasurement ();
208232
233+ // First cycle - prime
209234 if (!waitForData ()) {
210- Serial.println (F (" ERROR: Measurement timeout" ));
235+ Serial.println (F (" ERROR: Timeout" ));
236+ statusTestPass = false ;
237+ }
238+ as7343.readAllChannels (allChannels);
239+ as7343.clearStatus ();
240+
241+ // Second cycle - actual test
242+ if (!waitForData ()) {
243+ Serial.println (F (" ERROR: Timeout" ));
244+ statusTestPass = false ;
211245 } else {
212246 as7343.readAllChannels (allChannels);
213- uint16_t reading = allChannels[AS7343_CHANNEL_FZ ];
247+ uint16_t reading = allChannels[0 ];
214248
215- // Check status for AINT bit (bit 3 = 0x08)
216249 uint8_t status = as7343.getStatus ();
217250 bool aintSet = (status & 0x08 ) != 0 ;
218-
219- Serial.print (F (" NeoPixels OFF, reading: " ));
220- Serial.println (reading);
221- Serial.print (F (" Status: 0x" ));
222- if (status < 0x10 ) Serial.print (F (" 0" ));
223- Serial.print (status, HEX );
224- Serial.print (F (" , AINT bit: " ));
225- Serial.println (aintSet ? F (" SET" ) : F (" CLEAR" ));
226-
227- // Should trigger because reading < lowThresh
228- lowTestPass = aintSet && (reading < lowThresh);
229-
230- Serial.print (F (" Result: " ));
231- Serial.println (lowTestPass ? F (" PASS" ) : F (" FAIL" ));
251+ bool intPinLow = !digitalRead (INT_PIN );
252+
253+ Serial.print (F (" CH0 reading: " ));
254+ Serial.print (reading);
255+ Serial.print (F (" (threshold: " ));
256+ Serial.print (lowThresh);
257+ Serial.println (F (" )" ));
258+
259+ Serial.print (F (" Status AINT: " ));
260+ Serial.print (aintSet ? F (" SET" ) : F (" CLEAR" ));
261+ bool statusOK = aintSet && (reading < lowThresh);
262+ Serial.println (statusOK ? F (" PASS" ) : F (" FAIL" ));
263+ if (!statusOK)
264+ statusTestPass = false ;
265+
266+ Serial.print (F (" INT pin: " ));
267+ Serial.print (intPinLow ? F (" LOW (active)" ) : F (" HIGH" ));
268+ Serial.println (intPinLow ? F (" PASS" ) : F (" FAIL" ));
269+ if (!intPinLow)
270+ intPinTestPass = false ;
271+
272+ // Verify clear works
273+ as7343.clearStatus ();
274+ delay (5 );
275+ bool intPinAfterClear = digitalRead (INT_PIN );
276+ Serial.print (F (" After clear: " ));
277+ Serial.print (intPinAfterClear ? F (" HIGH" ) : F (" LOW" ));
278+ Serial.println (intPinAfterClear ? F (" PASS" ) : F (" FAIL" ));
279+ if (!intPinAfterClear)
280+ intPinTestPass = false ;
232281 }
282+
283+ as7343.stopMeasurement ();
233284 Serial.println ();
234285
235286 // =====================
236- // FINAL RESULT
287+ // SUMMARY
237288 // =====================
238-
239- // Cleanup
240289 as7343.enableSpectralInterrupt (false );
241- as7343.stopMeasurement ();
242290 pixels.clear ();
243291 pixels.show ();
244292
245- // At least one interrupt must fire for pass
246- bool pass = (highTestPass || lowTestPass);
293+ Serial.println (F (" Summary:" ));
294+ Serial.print (F (" Status register: " ));
295+ Serial.println (statusTestPass ? F (" PASS" ) : F (" FAIL" ));
296+ Serial.print (F (" INT pin: " ));
297+ Serial.println (intPinTestPass ? F (" PASS" ) : F (" FAIL" ));
247298
299+ bool allPass = statusTestPass && intPinTestPass;
300+ Serial.println ();
248301 Serial.print (F (" RESULT: " ));
249- Serial.println (pass ? F (" PASS" ) : F (" FAIL" ));
302+ Serial.println (allPass ? F (" PASS" ) : F (" FAIL" ));
250303}
251304
252- void loop () {
253- // Nothing to do
254- }
305+ void loop () { delay (1000 ); }
0 commit comments