aboutsummaryrefslogtreecommitdiff
path: root/pm.h
blob: 116c74bf4c4b7ead68bf1f406570f097789c2a9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#pragma once
 
#include <sps30.h>
 
#include "data.h"
 
/*
start measuring
 
read once, stop, sleep
 
ready?
   if (now-last measurements) < read_interval, no
   else: start measuring, return ready status
 */
 
class PM {
private:
  uint8_t auto_clean_days;
  unsigned long last_measurment_millis;
  unsigned long read_interval_millis;
  bool awake;
public:
  PM(uint8_t acd=4unsigned long ri=30000) :
    auto_clean_days(acd),
    last_measurment_millis(0),
    read_interval_millis(ri),
    awake(false)
  {}
 
  void start() {
    // this will try to re-init Wire, emit a warning, and carry on 
    sensirion_i2c_init();
 
    while (sps30_probe() != 0{
      Serial.println("! PM sensor probing failed");
      delay(500);
    }
 
    int16_t ret;
 
    ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);
    if (ret) {
      Serial.print("! PM setting the auto-clean interval error: ");
      Serial.println(ret);
    }
 
    ret = sps30_start_measurement();
    if (ret < 0{
      Serial.println("! PM starting measurement error");
    }
 
    awake=true;
  }
 
  bool dataReady() {
    uint16_t data_ready;
    int16_t ret;
 
    // have we read recently? 
    unsigned long now=millis();
    if (
        last_measurment_millis > 0 && // have we measured once at least? 
        now > last_measurment_millis && // has there been no overflow & rollover? 
        (now - last_measurment_millis) < read_interval_millis // is it too soon? 
        ) {
      return false;
    }
 
    if (!awake) {
      sps30_wake_up();
      sps30_start_measurement();
      awake=true;
    }
 
    ret = sps30_read_data_ready(&data_ready);
    if (ret < 0{
      Serial.print("! PM reading data-ready flag error: ");
      Serial.println(ret);
      return false;
    } else if (!data_ready) {
      return false;
    }
 
    return true;
  }
 
  void read(SensorData *data) {
    char serial[SPS30_MAX_SERIAL_LEN];
    int16_t ret;
 
    ret = sps30_read_measurement(&(data->pm));
 
    if (ret <0{
      Serial.print("! PM reading measurement error: ");
      Serial.println(ret);
      return;
    }
 
    last_measurment_millis = millis();
    sps30_stop_measurement();
    sps30_sleep();
    awake=false;
  }
 
  bool serialCommand(const String &tag, const String &command) {
    return false;
  }
};