MySensors Library & Examples  2.3.2
DustSensorDSM.ino
1 /*
2  * The MySensors Arduino library handles the wireless radio link and protocol
3  * between your home built sensors/actuators and HA controller of choice.
4  * The sensors forms a self healing radio network with optional repeaters. Each
5  * repeater and gateway builds a routing tables in EEPROM which keeps track of the
6  * network topology allowing messages to be routed to nodes.
7  *
8  * Created by Henrik Ekblad <[email protected]>
9  * Copyright (C) 2013-2019 Sensnology AB
10  * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
11  *
12  * Documentation: http://www.mysensors.org
13  * Support Forum: http://forum.mysensors.org
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * version 2 as published by the Free Software Foundation.
18  *
19  *******************************
20  *
21  * DESCRIPTION
22  *
23  * Dust Sensor for SamYoung DSM501
24  * connect the sensor as follows :
25  * Pin 2 of dust sensor PM1 -> Digital 3 (PMW)
26  * Pin 3 of dust sensor -> +5V
27  * Pin 4 of dust sensor PM2.5 -> Digital 6 (PWM)
28  * Pin 5 of dust sensor -> Ground
29  * Datasheet: http://www.samyoungsnc.com/products/3-1%20Specification%20DSM501.pdf
30 * Contributor: epierre
31 **/
32 
33 // Enable debug prints
34 #define MY_DEBUG
35 
36 // Enable and select radio type attached
37 #define MY_RADIO_RF24
38 //#define MY_RADIO_NRF5_ESB
39 //#define MY_RADIO_RFM69
40 //#define MY_RADIO_RFM95
41 
42 #include <MySensors.h>
43 
44 #define CHILD_ID_DUST_PM10 0
45 #define CHILD_ID_DUST_PM25 1
46 #define DUST_SENSOR_DIGITAL_PIN_PM10 6
47 #define DUST_SENSOR_DIGITAL_PIN_PM25 3
48 
49 uint32_t SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
50 //VARIABLES
51 int val = 0; // variable to store the value coming from the sensor
52 float valDUSTPM25 =0.0;
53 float lastDUSTPM25 =0.0;
54 float valDUSTPM10 =0.0;
55 float lastDUSTPM10 =0.0;
56 uint32_t duration;
57 uint32_t starttime;
58 uint32_t endtime;
59 uint32_t sampletime_ms = 30000;
60 uint32_t lowpulseoccupancy = 0;
61 float ratio = 0;
62 long concentrationPM25 = 0;
63 long concentrationPM10 = 0;
64 
65 MyMessage dustMsgPM10(CHILD_ID_DUST_PM10, V_LEVEL);
66 MyMessage msgPM10(CHILD_ID_DUST_PM10, V_UNIT_PREFIX);
67 MyMessage dustMsgPM25(CHILD_ID_DUST_PM25, V_LEVEL);
68 MyMessage msgPM25(CHILD_ID_DUST_PM25, V_UNIT_PREFIX);
69 
70 void setup()
71 {
72  pinMode(DUST_SENSOR_DIGITAL_PIN_PM10,INPUT);
73  pinMode(DUST_SENSOR_DIGITAL_PIN_PM25,INPUT);
74 }
75 
77 {
78  // Send the sketch version information to the gateway and Controller
79  sendSketchInfo("Dust Sensor DSM501", "1.4");
80 
81  // Register all sensors to gateway (they will be created as child devices)
82  present(CHILD_ID_DUST_PM10, S_DUST);
83  send(msgPM10.set("ppm"));
84  present(CHILD_ID_DUST_PM25, S_DUST);
85  send(msgPM25.set("ppm"));
86 }
87 
88 void loop()
89 {
90 
91  //get PM 2.5 density of particles over 2.5 µm.
92  concentrationPM25=(long)getPM(DUST_SENSOR_DIGITAL_PIN_PM25);
93  Serial.print("PM25: ");
94  Serial.println(concentrationPM25);
95  Serial.print("\n");
96 
97  if ((concentrationPM25 != lastDUSTPM25)&&(concentrationPM25>0)) {
98  send(dustMsgPM25.set((int32_t)ceil(concentrationPM25)));
99  lastDUSTPM25 = ceil(concentrationPM25);
100  }
101 
102  //get PM 1.0 - density of particles over 1 µm.
103  concentrationPM10=getPM(DUST_SENSOR_DIGITAL_PIN_PM10);
104  Serial.print("PM10: ");
105  Serial.println(concentrationPM10);
106  Serial.print("\n");
107  //ppmv=mg/m3 * (0.08205*Tmp)/Molecular_mass
108  //0.08205 = Universal gas constant in atm·m3/(kmol·K)
109  int temp=20; //external temperature, if you can replace this with a DHT11 or better
110  long ppmv=(concentrationPM10*0.0283168/100/1000) * (0.08205*temp)/0.01;
111 
112  if ((ceil(concentrationPM10) != lastDUSTPM10)&&((long)concentrationPM10>0)) {
113  send(dustMsgPM10.set((int32_t)ppmv));
114  lastDUSTPM10 = ceil(concentrationPM10);
115  }
116 
117  //sleep to save on radio
118  sleep(SLEEP_TIME);
119 
120 }
121 
122 
123 long getPM(int DUST_SENSOR_DIGITAL_PIN)
124 {
125 
126  starttime = millis();
127 
128  while (1) {
129 
130  duration = pulseIn(DUST_SENSOR_DIGITAL_PIN, LOW);
131  lowpulseoccupancy += duration;
132  endtime = millis();
133 
134  if ((endtime-starttime) > sampletime_ms) {
135  ratio = (lowpulseoccupancy-endtime+starttime)/(sampletime_ms*10.0); // Integer percentage 0=>100
136  long concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
137  //Serial.print("lowpulseoccupancy:");
138  //Serial.print(lowpulseoccupancy);
139  //Serial.print("\n");
140  //Serial.print("ratio:");
141  //Serial.print(ratio);
142  //Serial.print("\n");
143  //Serial.print("DSM501A:");
144  //Serial.println(concentration);
145  //Serial.print("\n");
146 
147  lowpulseoccupancy = 0;
148  return(concentration);
149  }
150  }
151 }
MyMessage is used to create, manipulate, send and read MySensors messages.
Definition: MyMessage.h:289
bool sendSketchInfo(const char *name, const char *version, const bool requestEcho=false)
API declaration for MySensors.
bool send(MyMessage &msg, const bool requestEcho=false)
bool present(const uint8_t sensorId, const mysensors_sensor_t sensorType, const char *description="", const bool requestEcho=false)
void setup()
Called after node initialises but before main loop.
int8_t sleep(const uint32_t sleepingMS, const bool smartSleep=false)
void presentation()
Node presentation.
#define LOW
Definition: bcm2835.h:574
MyMessage & set(const void *payload, const size_t length)
Set entire payload.
void loop()
Main loop.