Skip to content

Commit 95bdcc3

Browse files
committed
add sps30 library
1 parent 3c233ca commit 95bdcc3

21 files changed

+2554
-1
lines changed

CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ set(CORE_SRCS
8080
)
8181

8282
set(ARDUINO_ALL_LIBRARIES
83+
sensirion_sps
8384
ArduinoOTA
8485
AsyncUDP
8586
BLE
@@ -120,6 +121,12 @@ set(ARDUINO_ALL_LIBRARIES
120121
Zigbee
121122
)
122123

124+
set(ARDUINO_LIBRARY_sensirion_sps_SRCS libraries/sensirion-sps/sps30.cpp
125+
libraries/sensirion-sps/sps_git_version.cpp
126+
libraries/sensirion-sps/sensirion_hw_i2c_implementation.cpp
127+
libraries/sensirion-sps/sensirion_common.cpp
128+
libraries/sensirion-sps/i2c_master_lib.cpp)
129+
123130
set(ARDUINO_LIBRARY_ArduinoOTA_SRCS libraries/ArduinoOTA/src/ArduinoOTA.cpp)
124131

125132
set(ARDUINO_LIBRARY_AsyncUDP_SRCS libraries/AsyncUDP/src/AsyncUDP.cpp)
@@ -356,7 +363,7 @@ foreach(libname IN LISTS ARDUINO_ALL_LIBRARIES)
356363
endif()
357364
endforeach()
358365

359-
set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS})
366+
set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS} libraries/sensirion-sps)
360367
set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS})
361368
set(priv_includes cores/esp32/libb64)
362369
set(requires spi_flash esp_partition mbedtls wpa_supplicant esp_adc esp_eth http_parser esp_ringbuf esp_driver_gptimer esp_driver_usb_serial_jtag driver)

libraries/sensirion-sps/AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Johannes Winkelmann <[email protected]>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
This package includes the I2C master library from
2+
https://github.com/DSSCircuits/I2C-Master-Library
3+
in order to work around limitations in the I2C stack on certain Arduino boards (including the Arduino Uno).
4+
5+
More information can be found here:
6+
http://dsscircuits.com/index.php/articles/66-arduino-i2c-master-library
7+
8+
9+
10+
Copyright (c) 2011-2012 Wayne Truchsess. All right reserved.
11+
12+
This is a modified version of the Arduino Wire/TWI
13+
library. Functions were rewritten to provide more functionality
14+
and also the use of Repeated Start. Some I2C devices will not
15+
function correctly without the use of a Repeated Start. The
16+
initial version of this library only supports the Master.
17+
18+
19+
This library is free software; you can redistribute it and/or
20+
modify it under the terms of the GNU Lesser General Public
21+
License as published by the Free Software Foundation; either
22+
version 2.1 of the License, or (at your option) any later version.
23+
24+
This library is distributed in the hope that it will be useful,
25+
but WITHOUT ANY WARRANTY; without even the implied warranty of
26+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27+
Lesser General Public License for more details.
28+
29+
You should have received a copy of the GNU Lesser General Public
30+
License along with this library; if not, write to the Free Software
31+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2017-2018, Sensirion AG
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
* Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
* Neither the name of Sensirion AG nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

libraries/sensirion-sps/README.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Arduino library for the SPS30 particulate matter sensor
2+
3+
To learn more about the SPS30, please visit https://www.sensirion.com/sps30/.
4+
For support questions on the SPS30, please visit https://sensirion.com/contact.
5+
6+
This library is using the code from Sensirion's
7+
[embedded-sps](https://github.com/Sensirion/embedded-sps) library, and adding a
8+
handful of changes to adapt to Arduino.
9+
10+
Most notably, for AVR based platforms (like Arduino Uno and friends), this is
11+
using an alternative
12+
[I2C Master Library](https://github.com/DSSCircuits/I2C-Master-Library) to work
13+
around the I2C buffer size limit that exists on those boards.
14+
15+
## Compatibility
16+
17+
This library has been tested on the following platforms:
18+
- AVR based Arduino, like Arduino Uno
19+
- ESP8266, using v2.5.0 or newer (Tested on Adafruit Feather Huzzah ESP8266)
20+
- ESP32, using v1.0.1 or newer (Tested on Adafruit Feather Huzzah ESP32)
21+
- SAMD (tested on Arduino MKR 1010)
22+
23+
## Hardware setup
24+
25+
**Important Notes:**
26+
27+
* The SPS30 requires 5V supply voltage +/-0.5V in order to provide correct
28+
output values; the SPS30 should be compatible with 3.3V I2C levels, so as
29+
long as the supply voltage is correct the SPS30 should work fine with 3.3V
30+
setups
31+
* Make sure that the SPS30's Pin 4 ("Interface select") is connected to GND, on
32+
power-up of the sensor, otherwise the sensor works in UART instead of I2C
33+
mode and this driver will not detect the sensor. Note that the
34+
interface-select configuration is read on every start of the sensor including
35+
after a soft-reset.
36+
37+
38+
39+
### ESP8266 partial legacy support
40+
41+
This library automatically detects ESP8266 core versions 2.3.0, 2.4.0, 2.4.1 and
42+
2.4.2 and supports a limited subset of functionality on there. The following
43+
features are not available:
44+
- Reading out number concentrations,
45+
- Reading out the average particle size
46+
- Reading out the serial number
47+
48+
## Installation
49+
50+
### Through the Arduino IDE
51+
52+
This library is available through Arduino IDE's Library Manager. To install,
53+
select ```Tools```> ```Manage Libraries...```, then search for
54+
```sensirion-sps```. Select the matching library and press ```Install```.
55+
56+
### Manual installation
57+
58+
For manual installation, follow these steps:
59+
60+
1. Download the latest ZIP file from the
61+
[Github release page](https://github.com/Sensirion/arduino-sps/releases/latest)
62+
1. Start the Arduino IDE
63+
1. Select ```Sketch > Include Library > Add .ZIP Library...```
64+
1. A dialog will open; here, select the file you selected in step 1
65+
66+
## Usage
67+
68+
### Serial Monitor (Text output)
69+
70+
1. Open the example from ```File > Examples > arduino-sps > sps30```.
71+
1. Open the serial monitor from the Tools menu
72+
1. Press the "Upload" button to compile and upload the sketch
73+
74+
If you check the serial monitor window, you should see something like this:
75+
76+
![Serial monitor](doc/sps30-arduino-serial-monitor.jpg)
77+
78+
### Serial Plotter (Graphical output)
79+
80+
1. Open the example from ```File > Examples > arduino-sps > sps30```.
81+
1. Open the serial plotter from the Tools menu (if you have the serial monitor
82+
open, you'll need to close it first)
83+
1. Uncomment line 8 of the sample program; it should now read
84+
```#define PLOTTER_FORMAT```
85+
1. Press the "Upload" button to compile and upload the sketch
86+
87+
If you check the serial plotter window, you should see something like this:
88+
89+
90+
![Serial monitor](doc/sps30-arduino-serial-plotter.jpg)
91+
92+
93+
## FAQ: How PMx is defined / Why values are the same
94+
95+
A frequently asked question about values that are the same, which seems unlikely. However, this is due to the definition of PM_x_, that says that it's particles of diameter _x_ and smaller. As such, PM10 includes all particles of diameter 10 μm and smaller, and therefore includes particles from PM4 (which itself includes particles from PM2.5). To illustrate, here's a diagram that shows this
96+
97+
![How PMx is defined](https://user-images.githubusercontent.com/1300460/121040377-b445d880-c766-11eb-82d9-241dcdefab1f.png)
98+
99+
In this example:
100+
- PM2.5 would be 3.1 μg/m^3
101+
- PM4 would be 3.2 μg/m^3 (3.1 particles [2.5 and smaller] + 0.1 [>2.5, <= 4.0])
102+
- PM10 would be 3.2 μg/m^3 (3.1 particles [2.5 and smaller] + 0.1 [>2.5, <= 4.0] + 0 [>4.0 <= 10])
23.2 KB
Loading
33.5 KB
Loading
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#include <sps30.h>
2+
3+
// Example arduino sketch, based on
4+
// https://github.com/Sensirion/embedded-sps/blob/master/sps30-i2c/sps30_example_usage.c
5+
6+
7+
// uncomment the next line to use the serial plotter
8+
// #define PLOTTER_FORMAT
9+
10+
void setup() {
11+
int16_t ret;
12+
uint8_t auto_clean_days = 4;
13+
uint32_t auto_clean;
14+
15+
Serial.begin(9600);
16+
delay(2000);
17+
18+
sensirion_i2c_init();
19+
20+
while (sps30_probe() != 0) {
21+
Serial.print("SPS sensor probing failed\n");
22+
delay(500);
23+
}
24+
25+
#ifndef PLOTTER_FORMAT
26+
Serial.print("SPS sensor probing successful\n");
27+
#endif /* PLOTTER_FORMAT */
28+
29+
ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);
30+
if (ret) {
31+
Serial.print("error setting the auto-clean interval: ");
32+
Serial.println(ret);
33+
}
34+
35+
ret = sps30_start_measurement();
36+
if (ret < 0) {
37+
Serial.print("error starting measurement\n");
38+
}
39+
40+
#ifndef PLOTTER_FORMAT
41+
Serial.print("measurements started\n");
42+
#endif /* PLOTTER_FORMAT */
43+
44+
#ifdef SPS30_LIMITED_I2C_BUFFER_SIZE
45+
Serial.print("Your Arduino hardware has a limitation that only\n");
46+
Serial.print(" allows reading the mass concentrations. For more\n");
47+
Serial.print(" information, please check\n");
48+
Serial.print(" https://github.com/Sensirion/arduino-sps#esp8266-partial-legacy-support\n");
49+
Serial.print("\n");
50+
delay(2000);
51+
#endif
52+
53+
delay(1000);
54+
}
55+
56+
void loop() {
57+
struct sps30_measurement m;
58+
char serial[SPS30_MAX_SERIAL_LEN];
59+
uint16_t data_ready;
60+
int16_t ret;
61+
62+
do {
63+
ret = sps30_read_data_ready(&data_ready);
64+
if (ret < 0) {
65+
Serial.print("error reading data-ready flag: ");
66+
Serial.println(ret);
67+
} else if (!data_ready)
68+
Serial.print("data not ready, no new measurement available\n");
69+
else
70+
break;
71+
delay(100); /* retry in 100ms */
72+
} while (1);
73+
74+
ret = sps30_read_measurement(&m);
75+
if (ret < 0) {
76+
Serial.print("error reading measurement\n");
77+
} else {
78+
79+
#ifndef PLOTTER_FORMAT
80+
Serial.print("PM 1.0: ");
81+
Serial.println(m.mc_1p0);
82+
Serial.print("PM 2.5: ");
83+
Serial.println(m.mc_2p5);
84+
Serial.print("PM 4.0: ");
85+
Serial.println(m.mc_4p0);
86+
Serial.print("PM 10.0: ");
87+
Serial.println(m.mc_10p0);
88+
89+
#ifndef SPS30_LIMITED_I2C_BUFFER_SIZE
90+
Serial.print("NC 0.5: ");
91+
Serial.println(m.nc_0p5);
92+
Serial.print("NC 1.0: ");
93+
Serial.println(m.nc_1p0);
94+
Serial.print("NC 2.5: ");
95+
Serial.println(m.nc_2p5);
96+
Serial.print("NC 4.0: ");
97+
Serial.println(m.nc_4p0);
98+
Serial.print("NC 10.0: ");
99+
Serial.println(m.nc_10p0);
100+
101+
Serial.print("Typical particle size: ");
102+
Serial.println(m.typical_particle_size);
103+
#endif
104+
105+
Serial.println();
106+
107+
#else
108+
// since all values include particles smaller than X, if we want to create buckets we
109+
// need to subtract the smaller particle count.
110+
// This will create buckets (all values in micro meters):
111+
// - particles <= 0,5
112+
// - particles > 0.5, <= 1
113+
// - particles > 1, <= 2.5
114+
// - particles > 2.5, <= 4
115+
// - particles > 4, <= 10
116+
117+
Serial.print(m.nc_0p5);
118+
Serial.print(" ");
119+
Serial.print(m.nc_1p0 - m.nc_0p5);
120+
Serial.print(" ");
121+
Serial.print(m.nc_2p5 - m.nc_1p0);
122+
Serial.print(" ");
123+
Serial.print(m.nc_4p0 - m.nc_2p5);
124+
Serial.print(" ");
125+
Serial.print(m.nc_10p0 - m.nc_4p0);
126+
Serial.println();
127+
128+
129+
#endif /* PLOTTER_FORMAT */
130+
131+
}
132+
133+
delay(1000);
134+
}

0 commit comments

Comments
 (0)