Adafruit Library
ws_uart_drv_pm25aqi.h
Go to the documentation of this file.
1 
15 #ifndef WS_UART_DRV_PM25AQI_H
16 #define WS_UART_DRV_PM25AQI_H
17 
18 #include "Wippersnapper.h"
19 #include "ws_uart_drv.h"
20 #include <Adafruit_PM25AQI.h>
21 
22 /**************************************************************************/
26 /**************************************************************************/
28 public:
29 #ifdef USE_SW_UART
30  /*******************************************************************************/
38  /*******************************************************************************/
39  ws_uart_drv_pm25aqi(SoftwareSerial *swSerial, int32_t interval)
40  : ws_uart_drv(swSerial, interval) {
41  _swSerial = swSerial;
42  pollingInterval = (unsigned long)interval;
43  };
44 #else
45  /*******************************************************************************/
53  /*******************************************************************************/
54  ws_uart_drv_pm25aqi(HardwareSerial *hwSerial, int32_t interval)
55  : ws_uart_drv(hwSerial, interval) {
56  _hwSerial = hwSerial;
57  pollingInterval = (unsigned long)interval;
58  };
59 #endif // USE_SW_UART
60 
61  /*******************************************************************************/
65  /*******************************************************************************/
67  delete _aqi;
68 #ifdef USE_SW_UART
69  _swSerial = nullptr;
70 #else
71  _hwSerial = nullptr;
72 #endif
73  }
74 
75  /*******************************************************************************/
81  /*******************************************************************************/
82  bool begin() override {
83  _aqi = new Adafruit_PM25AQI();
84  bool is_pm1006 = (strcmp(getDriverID(), "pm1006") == 0);
85 #ifdef USE_SW_UART
86  if (!_aqi->begin_UART(
87  _swSerial, // connect to the sensor over software serial
88  is_pm1006)) {
89  return false;
90  }
91 #else
92  if (!_aqi->begin_UART(
93  _hwSerial, // connect to the sensor over hardware serial
94  is_pm1006)) {
95  return false;
96  }
97 #endif
98  return true;
99  }
100 
101  /*******************************************************************************/
106  /*******************************************************************************/
107  bool read_data() override {
108  Serial.println("[UART, PM25] Reading data...");
109  // Attempt to read the PM2.5 Sensor
110  if (!_aqi->read(&_data)) {
111  Serial.println("[UART, PM25] Data not available.");
112  delay(500);
113  return false;
114  }
115  Serial.println("[UART, PM25] Read data OK");
116  Serial.println();
117  Serial.println(F("---------------------------------------"));
118  Serial.println(F("Concentration Units (standard)"));
119  Serial.println(F("---------------------------------------"));
120  Serial.print(F("PM 1.0: "));
121  Serial.print(_data.pm10_standard);
122  Serial.print(F("\t\tPM 2.5: "));
123  Serial.print(_data.pm25_standard);
124  Serial.print(F("\t\tPM 10: "));
125  Serial.println(_data.pm100_standard);
126  Serial.println(F("Concentration Units (environmental)"));
127  Serial.println(F("---------------------------------------"));
128  Serial.print(F("PM 1.0: "));
129  Serial.print(_data.pm10_env);
130  Serial.print(F("\t\tPM 2.5: "));
131  Serial.print(_data.pm25_env);
132  Serial.print(F("\t\tPM 10: "));
133  Serial.println(_data.pm100_env);
134  Serial.println(F("---------------------------------------"));
135 
136  return true;
137  }
138 
139  /*******************************************************************************/
143  /*******************************************************************************/
144  void send_data() override {
145  // Create a new UART response message
146  wippersnapper_signal_v1_UARTResponse msgUARTResponse =
147  wippersnapper_signal_v1_UARTResponse_init_zero;
148  msgUARTResponse.which_payload =
149  wippersnapper_signal_v1_UARTResponse_resp_uart_device_event_tag;
150  strcpy(msgUARTResponse.payload.resp_uart_device_event.device_id,
151  getDriverID());
152 
153  // check if driverID is pm1006
154  if (strcmp(getDriverID(), "pm1006") == 0) {
155  // PM1006 returns only PM2.5_ENV readings
156  msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 1;
157  packUARTResponse(&msgUARTResponse, 0,
158  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
159  (float)_data.pm25_env);
160  } else {
161  msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 6;
162  packUARTResponse(&msgUARTResponse, 0,
163  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD,
164  (float)_data.pm10_standard);
165 
166  packUARTResponse(&msgUARTResponse, 1,
167  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD,
168  (float)_data.pm25_standard);
169 
170  packUARTResponse(&msgUARTResponse, 2,
171  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD,
172  (float)_data.pm100_standard);
173 
174  packUARTResponse(&msgUARTResponse, 3,
175  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV,
176  (float)_data.pm10_env);
177 
178  packUARTResponse(&msgUARTResponse, 4,
179  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
180  (float)_data.pm25_env);
181 
182  packUARTResponse(&msgUARTResponse, 5,
183  wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV,
184  (float)_data.pm100_env);
185  }
186 
187  // Encode message data
188  uint8_t mqttBuffer[512] = {0};
189  pb_ostream_t ostream =
190  pb_ostream_from_buffer(mqttBuffer, sizeof(mqttBuffer));
191  if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_UARTResponse_fields,
192  &msgUARTResponse)) {
193  Serial.println("[ERROR, UART]: Unable to encode device response!");
194  return;
195  }
196 
197  // Publish message to IO
198  size_t msgSz;
199  pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_UARTResponse_fields,
200  &msgUARTResponse);
201  Serial.print("[UART] Publishing event to IO..");
202  mqttClient->publish(uartTopic, mqttBuffer, msgSz, 1);
203  Serial.println("Published!");
204 
205  setPrvPollTime(millis());
206  }
207 
208 protected:
209  Adafruit_PM25AQI *_aqi = nullptr;
210  PM25_AQI_Data _data;
211 #ifdef USE_SW_UART
212  SoftwareSerial *_swSerial = nullptr;
213 #else
214  HardwareSerial *_hwSerial = nullptr;
215 #endif
216 };
217 
218 #endif // WS_UART_DRV_PM25AQI_H
const char * getDriverID()
Gets the UART device&#39;s unique identifier.
Definition: ws_uart_drv.h:92
void send_data() override
Packs and sends the device&#39;s event data to Adafruit IO.
Definition: ws_uart_drv_pm25aqi.h:144
bool read_data() override
Attempts to read data from the PM25AQI sensor.
Definition: ws_uart_drv_pm25aqi.h:107
PM25_AQI_Data _data
PM25AQI sensor data struct.
Definition: ws_uart_drv_pm25aqi.h:210
unsigned long pollingInterval
UART device&#39;s polling interval, in milliseconds.
Definition: ws_uart_drv.h:168
const char * uartTopic
UART device&#39;s MQTT topic.
Definition: ws_uart_drv.h:165
Adafruit_PM25AQI * _aqi
Pointer to PM25AQI sensor object.
Definition: ws_uart_drv_pm25aqi.h:209
ws_uart_drv_pm25aqi(HardwareSerial *hwSerial, int32_t interval)
Initializes the PM25AQI UART device driver.
Definition: ws_uart_drv_pm25aqi.h:54
~ws_uart_drv_pm25aqi()
Destructor for a PM25AQI sensor.
Definition: ws_uart_drv_pm25aqi.h:66
Class that provides an interface for a PM25 AQI UART sensor.
Definition: ws_uart_drv_pm25aqi.h:27
bool begin() override
Initializes a PM25AQI sensor.
Definition: ws_uart_drv_pm25aqi.h:82
ws_uart_drv(HardwareSerial *hwSerial, int32_t interval)
Initializes a UART device driver.
Definition: ws_uart_drv.h:59
Adafruit_MQTT * mqttClient
Pointer to MQTT client object.
Definition: ws_uart_drv.h:166
void setPrvPollTime(unsigned long curTime)
Sets the last time a UART device driver was polled.
Definition: ws_uart_drv.h:84
void packUARTResponse(wippersnapper_signal_v1_UARTResponse *msgUARTResponse, int event_index, wippersnapper_i2c_v1_SensorType sensor_type, float sensor_value)
Packs the UART device&#39;s data into a UARTResponse message.
Definition: ws_uart_drv.h:148
HardwareSerial * _hwSerial
Pointer to Hardware UART interface.
Definition: ws_uart_drv_pm25aqi.h:214
Base class for UART Device Drivers.
Definition: ws_uart_drv.h:36