summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/datalogger/main.cc39
-rw-r--r--src/driver/Kconfig4
-rw-r--r--src/driver/sen5x.cc51
3 files changed, 94 insertions, 0 deletions
diff --git a/src/app/datalogger/main.cc b/src/app/datalogger/main.cc
index 5800b1b..fd016e7 100644
--- a/src/app/datalogger/main.cc
+++ b/src/app/datalogger/main.cc
@@ -54,6 +54,9 @@
#ifdef CONFIG_driver_scd4x
#include "driver/scd4x.h"
#endif
+#ifdef CONFIG_driver_sen5x
+#include "driver/sen5x.h"
+#endif
#ifdef CONFIG_driver_veml6075
#include "driver/veml6075.h"
#endif
@@ -202,6 +205,38 @@ void loop(void)
}
#endif
+#ifdef CONFIG_driver_sen5x
+ if (sen5x.read()) {
+ kout << dec;
+ if (sen5x.pm1 != sen5x.PM_INVALID) {
+ kout << "PM1.0: " << (sen5x.pm1 / 10) << "." << (sen5x.pm1 % 10) << " µg/m³" << endl;
+ }
+ if (sen5x.pm2_5 != sen5x.PM_INVALID) {
+ kout << "PM2.5: " << (sen5x.pm2_5 / 10) << "." << (sen5x.pm2_5 % 10) << " µg/m³" << endl;
+ }
+ if (sen5x.pm4 != sen5x.PM_INVALID) {
+ kout << "PM4.0: " << (sen5x.pm4 / 10) << "." << (sen5x.pm4 % 10) << " µg/m³" << endl;
+ }
+ if (sen5x.pm10 != sen5x.PM_INVALID) {
+ kout << "PM10 : " << (sen5x.pm10 / 10) << "." << (sen5x.pm10 % 10) << " µg/m³" << endl;
+ }
+ if (sen5x.humidity != sen5x.HUMIDITY_INVALID) {
+ kout << "Humidity: " << (sen5x.humidity / 100) << "." << ((sen5x.humidity % 100) / 10) << " %" << endl;
+ }
+ if (sen5x.temperature != sen5x.TEMPERATURE_INVALID) {
+ kout << "Temperature: " << (sen5x.temperature / 200) << "." << ((sen5x.temperature % 200) / 20) << " °c" << endl;
+ }
+ if (sen5x.voc != sen5x.VOC_INVALID) {
+ kout << "VOC index: " << (sen5x.voc / 10) << "." << (sen5x.voc % 10) << endl;
+ }
+ if (sen5x.nox != sen5x.NOX_INVALID) {
+ kout << "NOx index: " << (sen5x.nox / 10) << "." << (sen5x.nox % 10) << endl;
+ }
+ } else {
+ kout << "SEN5x error" << endl;
+ }
+#endif
+
#ifdef CONFIG_driver_veml6075
float uva, uvb;
if (veml6075.readUV(&uva, &uvb)) {
@@ -318,6 +353,10 @@ int main(void)
scd4x.start();
#endif
+#ifdef CONFIG_driver_sen5x
+ sen5x.start();
+#endif
+
#ifdef CONFIG_driver_veml6075
veml6075.init();
#endif
diff --git a/src/driver/Kconfig b/src/driver/Kconfig
index 5f544ac..581ef10 100644
--- a/src/driver/Kconfig
+++ b/src/driver/Kconfig
@@ -119,6 +119,10 @@ config driver_scd4x
bool "Sensirion SCD4x CO2 Sensor"
depends on meta_driver_i2c
+config driver_sen5x
+bool "Sensirion SEN5x PM Sensor"
+depends on meta_driver_i2c
+
config driver_veml6075
bool "VEML6075 UV Sensor"
depends on meta_driver_i2c
diff --git a/src/driver/sen5x.cc b/src/driver/sen5x.cc
new file mode 100644
index 0000000..2a5d6b8
--- /dev/null
+++ b/src/driver/sen5x.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 Daniel Friesel
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include "arch.h"
+#include "driver/sen5x.h"
+#if defined(CONFIG_meta_driver_hardware_i2c)
+#include "driver/i2c.h"
+#elif defined(CONFIG_driver_softi2c)
+#include "driver/soft_i2c.h"
+#endif
+
+void SEN5x::start()
+{
+ txbuf[0] = 0x00;
+ txbuf[1] = 0x21;
+ i2c.xmit(address, 2, txbuf, 0, rxbuf);
+}
+
+void SEN5x::stop()
+{
+ txbuf[0] = 0x01;
+ txbuf[1] = 0x04;
+ i2c.xmit(address, 2, txbuf, 0, rxbuf);
+}
+
+bool SEN5x::read()
+{
+ txbuf[0] = 0x03;
+ txbuf[1] = 0xc4;
+
+ if (i2c.xmit(address, 2, txbuf, 0, rxbuf)) {
+ return false;
+ }
+ arch.delay_ms(20);
+ if (i2c.xmit(address, 0, txbuf, 24, rxbuf)) {
+ return false;
+ }
+ pm1 = (rxbuf[0] << 8) + rxbuf[1];
+ pm2_5 = (rxbuf[3] << 8) + rxbuf[4];
+ pm4 = (rxbuf[6] << 8) + rxbuf[7];
+ pm10 = (rxbuf[9] << 8) + rxbuf[10];
+ humidity = (rxbuf[12] << 8) + rxbuf[13];
+ temperature = (rxbuf[15] << 8) + rxbuf[16];
+ voc = (rxbuf[18] << 8) + rxbuf[19];
+ nox = (rxbuf[21] << 8) + rxbuf[22];
+ return true;
+}
+
+SEN5x sen5x;