supla-device
Loading...
Searching...
No Matches
particle_meter_pm1006k.h
1// SPDX-FileCopyrightText: malarz
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// Dependencies:
5// https://github.com/kevinlutzer/Arduino-PM1006K
6
7#ifndef SRC_SUPLA_SENSOR_PARTICLE_METER_PM1006K_H_
8#define SRC_SUPLA_SENSOR_PARTICLE_METER_PM1006K_H_
9
10#include <supla/sensor/particle_meter.h>
11
12#include <PM1006K.h>
13
14namespace Supla {
15namespace Sensor {
17 public:
24 explicit ParticleMeterPM1006K(int rx_pin, int tx_pin, int fan_pin = -1,
25 int refresh = 600, int fan = 15)
26 : ParticleMeter() {
27 rxPin = rx_pin;
28 txPin = tx_pin;
29 if (refresh < 60) {
30 refresh = 600;
31 } else if (refresh > 86400) {
32 refresh = 600;
33 }
34 if (fan < 15) {
35 fan = 15;
36 } else if (fan > 120) {
37 fan = 120;
38 } else if (fan > refresh) {
39 fan = refresh;
40 }
41 refreshIntervalMs = refresh * 1000;
42 fanTime = fan * 1000;
43
44 // FAN setup
45 fanPin = fan_pin;
46 if (fanPin >= 0) {
47 pinMode(fanPin, OUTPUT);
48 fanOff = false;
49 digitalWrite(fanPin, HIGH);
50 SUPLA_LOG_DEBUG("PM1006K FAN: started & on");
51 }
52
53 // create GPM channel for PM2.5
54 createPM2_5Channel();
55 }
56
57 void onInit() override {
58 // Setup and create instance of the PM1006K driver
59 // The baud rate for the serial connection must be PM1006K::BAUD_RATE.
60 Serial1.begin(PM1006K::BAUD_RATE, SERIAL_8N1, rxPin, txPin);
61 sensor = new PM1006K(&Serial1);
62 }
63
64 void iterateAlways() override {
65 // enable fan fanTime before reading sensor
66 if (millis() - lastReadTime > refreshIntervalMs-fanTime) {
67 if ((fanPin >= 0) && fanOff) {
68 fanOff = false;
69 digitalWrite(fanPin, HIGH);
70 SUPLA_LOG_DEBUG("PM1006K FAN: on");
71 }
72 }
73
74 if (millis() - lastReadTime > refreshIntervalMs) {
75 double valuePM1 = NAN;
76 double valuePM2_5 = NAN;
77 double valuePM10 = NAN;
78 if (!sensor->takeMeasurement()) {
79 SUPLA_LOG_DEBUG("PM1006K: failed to take measurement");
80 } else {
81 valuePM1 = sensor->getPM1_0();
82 SUPLA_LOG_DEBUG("PM1006K: PM1 read: %.0f", valuePM1);
83 valuePM2_5 = sensor->getPM2_5();
84 SUPLA_LOG_DEBUG("PM1006K: PM2.5 read: %.0f", valuePM2_5);
85 valuePM10 = sensor->getPM10();
86 SUPLA_LOG_DEBUG("PM1006K: PM10 read: %.0f", valuePM10);
87 }
88
89 if (isnan(valuePM2_5) || valuePM2_5 <= 0) {
90 if (invalidCounter < 3) {
91 invalidCounter++;
92 } else {
93 pm1value = NAN;
94 pm2_5value = NAN;
95 pm10value = NAN;
96 }
97 } else {
98 invalidCounter = 0;
99 pm1value = valuePM1;
100 pm2_5value = valuePM2_5;
101 pm10value = valuePM10;
102
103 // switch faan off after successfull reading
104 if ((fanPin >= 0) && (refreshIntervalMs !=fanTime)) {
105 fanOff = true;
106 digitalWrite(fanPin, LOW);
107 SUPLA_LOG_DEBUG("PM1006K FAN: off");
108 }
109 }
110 if (pm1channel != nullptr) {
111 pm1channel->setValue(pm1value);
112 }
113 pm2_5channel->setValue(pm2_5value);
114 if (pm10channel != nullptr) {
115 pm10channel->setValue(pm10value);
116 }
117 lastReadTime = millis();
118 }
119 }
120
121 protected:
122 ::PM1006K* sensor = nullptr;
123 int fanPin = -1;
124 int rxPin = 0;
125 int txPin = 0;
126 bool fanOff = true;
127 uint32_t fanTime = 15;
128 int invalidCounter = 0;
129};
130
131} // namespace Sensor
132} // namespace Supla
133
134#endif // SRC_SUPLA_SENSOR_PARTICLE_METER_PM1006K_H_
virtual void setValue(const double &value)
Method used to set new value for channel with driver which accepts MeasurementDriver::setValue() meth...
Definition general_purpose_channel_base.cpp:560
Definition particle_meter_pm1006k.h:16
void iterateAlways() override
Method called on each SuplaDevice iteration.
Definition particle_meter_pm1006k.h:64
void onInit() override
Third method called on element in SuplaDevice.begin()
Definition particle_meter_pm1006k.h:57
ParticleMeterPM1006K(int rx_pin, int tx_pin, int fan_pin=-1, int refresh=600, int fan=15)
class constructor for PM1006K sensor
Definition particle_meter_pm1006k.h:24
Definition particle_meter.h:11