Skip to content

Commit 97ba2ce

Browse files
committed
Add in SYND mode example. Update library.
Populate SYND mode example. Update library to work with SYND mode and calculate conversion correctly.
1 parent 4206edc commit 97ba2ce

File tree

2 files changed

+162
-16
lines changed

2 files changed

+162
-16
lines changed
Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,96 @@
1+
/*
2+
Using the AMS AS7331 Spectral UV Sensor in Synchronous Start and Stop (SYND) Mode.
3+
4+
This example shows how operate the AS7331 in SYND mode. This uses the active
5+
low SYN pin to both start and stop the conversion. The conversion time is
6+
calculated and stored in the `measures.outputConversionTime` field in units
7+
of number of clock cycles.
8+
9+
By: Alex Brudner
10+
SparkFun Electronics
11+
Date: 2023/11/28
12+
SparkFun code, firmware, and software is released under the MIT License.
13+
Please see LICENSE.md for further details.
14+
15+
Hardware Connections:
16+
IoT RedBoard --> AS7331
17+
QWIIC --> QWIIC
18+
27 --> SYN
19+
20+
Serial.print it out at 115200 baud to serial monitor.
21+
22+
Feel like supporting our work? Buy a board from SparkFun!
23+
https://www.sparkfun.com/products/23517 - Qwiic 1x1
24+
https://www.sparkfun.com/products/23518 - Qwiic Mini
25+
*/
26+
127
#include "SparkFun_AS7331.h"
228

329
SfeAS7331ArdI2C myUVSensor;
430

531
int8_t result = SFE_BUS_OK;
632

33+
const uint8_t synPin = 27;
34+
735
void setup() {
36+
Serial.begin(115200);
37+
while(!Serial){delay(100);};
38+
Serial.println("AS7331 UV A/B/C Synchronous Start and End (SYND) mode example.");
39+
40+
// Configure SYN pin.
41+
pinMode(synPin, OUTPUT);
42+
digitalWrite(synPin, HIGH); // Active low, so start high.
43+
44+
// Initialize sensor and run default setup.
45+
if(myUVSensor.begin() == false) {
46+
Serial.println("Sensor failed to begin. Please check your wiring!");
47+
Serial.println("Spinning...");
48+
while(1);
49+
}
50+
51+
Serial.println("Sensor began.");
52+
53+
// Set measurement mode and change device operating mode to measure.
54+
if(myUVSensor.startMeasurement(MEAS_MODE_SYND) == false) {
55+
Serial.println("Sensor did not get set properly.");
56+
Serial.println("Spinning...");
57+
while(1);
58+
}
59+
60+
Serial.println("Set mode to synchronous start/end (SYND). Starting measurement...");
61+
62+
// Set device to be ready to measure.
63+
if(SFE_BUS_OK != myUVSensor.setStartStateMode(START_STATE_ENABLED))
64+
Serial.println("Error starting reading!");
65+
66+
// Send start toggle.
67+
digitalWrite(synPin, LOW);
68+
delay(1);
69+
digitalWrite(synPin, HIGH);
870

971
}
1072

1173
void loop() {
74+
// Delay a random period of time from 64ms (minimum for full read) and 300ms.
75+
delay(random(64,300));
76+
77+
// End measurement.
78+
digitalWrite(synPin, LOW);
79+
delay(1);
80+
digitalWrite(synPin, HIGH);
81+
82+
if(SFE_BUS_OK != myUVSensor.readAllUV())
83+
Serial.println("Error reading UV.");
84+
85+
Serial.print("UVA:");
86+
Serial.print(myUVSensor.measures.uva);
87+
Serial.print(" UVB:");
88+
Serial.print(myUVSensor.measures.uvb);
89+
Serial.print(" UVC:");
90+
Serial.println(myUVSensor.measures.uvc);
1291

13-
};
92+
// Start next measurement.
93+
digitalWrite(synPin, LOW);
94+
delay(1);
95+
digitalWrite(synPin, HIGH);
96+
}

src/SparkFun_AS7331.h

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,19 @@ class SfeAS7331Base {
408408
if(SFE_BUS_OK != result)
409409
return result;
410410

411-
measures.uva = ((float)((uint16_t)((uint16_t)uvaRaw[1] << 8 | uvaRaw[0]))-1.0f)*_conversionA;
411+
if(_state.mmode == MEAS_MODE_SYND) {
412+
result = readOutConv();
413+
414+
if(SFE_BUS_OK != result)
415+
return result;
416+
417+
float divFactor = (bool)_config.dividerEnabled ? (float)(1 << (1+_config.dividerRange)) : 1.0f;
418+
float convFactor = ((float)measures.outputConversionTime)*((float)(1 << (11 - _config.sensorGain)));
419+
measures.uva = (float)((uint16_t)(((uint16_t)uvaRaw[1]) << 8 | uvaRaw[0])-1.0f)*fsrA*divFactor/convFactor;
420+
}
421+
else {
422+
measures.uva = (float)((uint16_t)(((uint16_t)uvaRaw[1]) << 8 | uvaRaw[0])-1.0f)*_conversionA;
423+
}
412424

413425
return SFE_BUS_OK;
414426
}
@@ -424,7 +436,19 @@ class SfeAS7331Base {
424436
if(SFE_BUS_OK != result)
425437
return result;
426438

427-
measures.uvb = ((float)((uint16_t)((uint16_t)uvbRaw[1] << 8 | uvbRaw[0]))-1.0f)*_conversionB;
439+
if(_state.mmode == MEAS_MODE_SYND) {
440+
result = readOutConv();
441+
442+
if(SFE_BUS_OK != result)
443+
return result;
444+
445+
float divFactor = (bool)_config.dividerEnabled ? (float)(1 << (1+_config.dividerRange)) : 1.0f;
446+
float convFactor = ((float)measures.outputConversionTime)*((float)(1 << (11 - _config.sensorGain)));
447+
measures.uvb = (float)((uint16_t)(((uint16_t)uvbRaw[1]) << 8 | uvbRaw[0])-1.0f)*fsrB*divFactor/convFactor;
448+
}
449+
else {
450+
measures.uvb = (float)((uint16_t)(((uint16_t)uvbRaw[1]) << 8 | uvbRaw[0])-1.0f)*_conversionB;
451+
}
428452

429453
return SFE_BUS_OK;
430454
}
@@ -440,7 +464,19 @@ class SfeAS7331Base {
440464
if(SFE_BUS_OK != result)
441465
return result;
442466

443-
measures.uvc = ((float)((uint16_t)((uint16_t)uvcRaw[1] << 8 | uvcRaw[0]))-1.0f)*_conversionC;
467+
if(_state.mmode == MEAS_MODE_SYND) {
468+
result = readOutConv();
469+
470+
if(SFE_BUS_OK != result)
471+
return result;
472+
473+
float divFactor = (bool)_config.dividerEnabled ? (float)(1 << (1+_config.dividerRange)) : 1.0f;
474+
float convFactor = ((float)measures.outputConversionTime)*((float)(1 << (11 - _config.sensorGain)));
475+
measures.uvc = (float)((uint16_t)(((uint16_t)uvcRaw[1]) << 8 | uvcRaw[0])-1.0f)*fsrC*divFactor/convFactor;
476+
}
477+
else {
478+
measures.uvc = (float)((uint16_t)(((uint16_t)uvcRaw[1]) << 8 | uvcRaw[0])-1.0f)*_conversionC;
479+
}
444480

445481
return SFE_BUS_OK;
446482
}
@@ -456,9 +492,23 @@ class SfeAS7331Base {
456492
if(SFE_BUS_OK != result)
457493
return result;
458494

459-
measures.uva = (float)((uint16_t)(((uint16_t)dataRaw[1]) << 8 | dataRaw[0])-1.0f)*_conversionA;
460-
measures.uvb = (float)((uint16_t)(((uint16_t)dataRaw[3]) << 8 | dataRaw[2])-1.0f)*_conversionB;
461-
measures.uvc = (float)((uint16_t)(((uint16_t)dataRaw[5]) << 8 | dataRaw[4])-1.0f)*_conversionC;
495+
if(_state.mmode == MEAS_MODE_SYND) {
496+
result = readOutConv();
497+
498+
if(SFE_BUS_OK != result)
499+
return result;
500+
501+
float divFactor = (bool)_config.dividerEnabled ? (float)(1 << (1+_config.dividerRange)) : 1.0f;
502+
float convFactor = ((float)measures.outputConversionTime)*((float)(1 << (11 - _config.sensorGain)));
503+
measures.uva = (float)((uint16_t)(((uint16_t)dataRaw[1]) << 8 | dataRaw[0])-1.0f)*fsrA*divFactor/convFactor;
504+
measures.uvb = (float)((uint16_t)(((uint16_t)dataRaw[3]) << 8 | dataRaw[2])-1.0f)*fsrB*divFactor/convFactor;
505+
measures.uvc = (float)((uint16_t)(((uint16_t)dataRaw[5]) << 8 | dataRaw[4])-1.0f)*fsrC*divFactor/convFactor;
506+
}
507+
else {
508+
measures.uva = (float)((uint16_t)(((uint16_t)dataRaw[1]) << 8 | dataRaw[0])-1.0f)*_conversionA;
509+
measures.uvb = (float)((uint16_t)(((uint16_t)dataRaw[3]) << 8 | dataRaw[2])-1.0f)*_conversionB;
510+
measures.uvc = (float)((uint16_t)(((uint16_t)dataRaw[5]) << 8 | dataRaw[4])-1.0f)*_conversionC;
511+
}
462512

463513
return SFE_BUS_OK;
464514
}
@@ -467,18 +517,31 @@ class SfeAS7331Base {
467517
/// @return 0 if successful, negative if error, positive for warning.
468518
int8_t readAll(void)
469519
{
470-
uint8_t dataRaw[12];
520+
uint8_t dataRaw[8];
471521

472-
int8_t result = readRegister(SFE_AS7331_REGISTER_MEAS_TEMP, dataRaw, 12U);
522+
int8_t result = readRegister(SFE_AS7331_REGISTER_MEAS_TEMP, dataRaw, 8U);
473523

474524
if(SFE_BUS_OK != result)
475525
return result;
476526

477-
measures.uva = (float)((uint16_t)(((uint16_t)dataRaw[1]) << 8 | dataRaw[0]))*_conversionA;
478-
measures.uvb = (float)((uint16_t)(((uint16_t)dataRaw[3]) << 8 | dataRaw[2]))*_conversionB;
479-
measures.uvc = (float)((uint16_t)(((uint16_t)dataRaw[5]) << 8 | dataRaw[4]))*_conversionC;
480-
measures.temperature = convertRawTempToTempC((uint16_t)(((uint16_t)dataRaw[7] << 8 | dataRaw[6])));
481-
measures.outputConversionTime = (uint32_t)(((uint32_t)dataRaw[11] << 24) | ((uint32_t)dataRaw[10] << 16) | ((uint32_t)dataRaw[9] << 8) | dataRaw[8]);
527+
result = readOutConv();
528+
if(SFE_BUS_OK != result)
529+
return result;
530+
531+
if(_state.mmode == MEAS_MODE_SYND) {
532+
float divFactor = (bool)_config.dividerEnabled ? (float)(1 << (1+_config.dividerRange)) : 1.0f;
533+
float convFactor = ((float)measures.outputConversionTime)*((float)(1 << (11 - _config.sensorGain)));
534+
measures.uva = (float)((uint16_t)(((uint16_t)dataRaw[3]) << 8 | dataRaw[2])-1.0f)*fsrA*divFactor/convFactor;
535+
measures.uvb = (float)((uint16_t)(((uint16_t)dataRaw[5]) << 8 | dataRaw[4])-1.0f)*fsrB*divFactor/convFactor;
536+
measures.uvc = (float)((uint16_t)(((uint16_t)dataRaw[7]) << 8 | dataRaw[6])-1.0f)*fsrC*divFactor/convFactor;
537+
}
538+
else {
539+
measures.uva = (float)((uint16_t)(((uint16_t)dataRaw[3]) << 8 | dataRaw[2])-1.0f)*_conversionA;
540+
measures.uvb = (float)((uint16_t)(((uint16_t)dataRaw[5]) << 8 | dataRaw[4])-1.0f)*_conversionB;
541+
measures.uvc = (float)((uint16_t)(((uint16_t)dataRaw[7]) << 8 | dataRaw[6])-1.0f)*_conversionC;
542+
}
543+
544+
measures.temperature = convertRawTempToTempC((uint16_t)(((uint16_t)dataRaw[1] << 8 | dataRaw[0])));
482545

483546
return SFE_BUS_OK;
484547
}
@@ -1222,11 +1285,11 @@ class SfeAS7331Base {
12221285
/// @brief Converts the raw temperature value to a human readable form.
12231286
/// @param inputVal Raw temperature value to convert.
12241287
/// @return The converted device temperature in degree C.
1225-
float convertRawTempToTempC(const uint16_t *inputVal)
1288+
float convertRawTempToTempC(const uint16_t inputVal)
12261289
{
12271290
// T_chip = TEMP*0.05 - 66.9
12281291
// EX: TEMP=0x922 aka TEMP=0d2338, returns 50.0
1229-
return ((float)(*inputVal) * 0.05f) - 66.9f;
1292+
return ((float)(inputVal) * 0.05f) - 66.9f;
12301293
}
12311294

12321295
/// @brief Called when changing values that affect the conversion, calculates a new conversion factor to reduce the conversion overhead.

0 commit comments

Comments
 (0)