Skip to content

Commit 39f667d

Browse files
author
clawpi
committed
Add INT pin hardware verification to spectral interrupt test
- Verify physical INT pin goes LOW when interrupt fires - Verify INT pin returns HIGH after clearStatus() - Tests both high and low threshold crossing - INT pin connected to Arduino D2 (active low)
1 parent 750e324 commit 39f667d

2 files changed

Lines changed: 174 additions & 117 deletions

File tree

hw_tests/10_spectral_interrupt_test/10_spectral_interrupt_test.ino

Lines changed: 153 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,41 @@
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

2024
Adafruit_AS7343 as7343;
2125
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
2226

2327
uint16_t allChannels[18];
28+
bool statusTestPass = true;
29+
bool intPinTestPass = true;
2430

2531
// Helper to wait for data ready with timeout
2632
bool 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

5358
void 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

Comments
 (0)