Skip to content

Commit f574dfb

Browse files
authored
Support for DSM501A dust sensor
1 parent e37fc67 commit f574dfb

File tree

5 files changed

+118
-4
lines changed

5 files changed

+118
-4
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,4 +475,10 @@ jobs:
475475
- sed -r -i 's/\/\/(SensorPca9685Rgbw .+)/\1/' $SKETCH
476476
- sed -r -i 's/\/\/(#include <sensors\/SensorPca9685Rgbw.h>)/\1/' $SKETCH
477477
- eval $OTA_CONFIGURATION
478+
- eval $COMPILE
479+
- name: "SensorDSM501A"
480+
script:
481+
- sed -r -i 's/\/\/(SensorDSM501A .+)/\1/' $SKETCH
482+
- sed -r -i 's/\/\/(#include <sensors\/SensorDSM501A.h>)/\1/' $SKETCH
483+
- eval $OTA_CONFIGURATION
478484
- eval $COMPILE

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ SensorNeopixel | 1 | Control a Neopixel LED
144144
SensorSDS011 | 2 | SDS011 air quality sensor, return concentrations of 2.5 and 10 micrometer particles. | https://github.com/ricki-z/SDS011
145145
SensorFPM10A | 1 | FPM10A fingerprint sensor | https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library
146146
SensorPH | 1 | PH ( SKU SEN161 ) sensor, measure the analog value from the amplifier module | -
147-
SensorPca9685W | 1 | Generic dimmer sensor (S_DIMMER) used to drive a single channel pwm output of PCA9685 | https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
148-
SensorPca9685Rgb | 1 | Generic RGB-dimmer sensor (S_RGB_LIGHT) used to drive RGB resp. 3-channel pwm output of PCA9685 | https://github.com/adafruit/Adafruit-PWM-Servo- Driver-Library
149-
SensorPca9685Rgbw | 1 | Generic RGBW-dimmer sensor (S_RGBW_LIGHT) used to drive RGBW resp. 4-channel pwm output of PCA9685| https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
147+
SensorPca9685W | 2 | Generic dimmer sensor (S_DIMMER) used to drive a single channel pwm output of PCA9685 | https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
148+
SensorPca9685Rgb | 2 | Generic RGB-dimmer sensor (S_RGB_LIGHT) used to drive RGB resp. 3-channel pwm output of PCA9685 | https://github.com/adafruit/Adafruit-PWM-Servo- Driver-Library
149+
SensorPca9685Rgbw | 2 | Generic RGBW-dimmer sensor (S_RGBW_LIGHT) used to drive RGBW resp. 4-channel pwm output of PCA9685| https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
150+
SensorDSM501A | 1 | ust sensor module DSM501A for PM1.0 and PM2.5 particles | -
150151

151152
Those sensors requiring a pin to operate would take it as an argument in the constructor.
152153
NodeManager automatically creates all the child_ids, assigning an incremental counter. If you need to set your own child_id, pass it as the last argument to the constructor
@@ -939,6 +940,12 @@ Each sensor class may expose additional methods.
939940
String getRgbwVal();
940941
~~~
941942

943+
* SensorDSM501A
944+
~~~c
945+
// [101] set the reference temperature for calculating PM1.0
946+
void setTemperature(int value);
947+
~~~
948+
942949
### OTA Configuration
943950
944951
When `NODEMANAGER_OTA_CONFIGURATION` is set to ON the API presented above can be also called remotely through `SensorConfiguration`, which is automatically added to NodeManager. SensorConfiguration exposes by default child id 200 that can be used to interact with the service by sending `V_CUSTOM` type of messages and commands within the payload. For each `REQ` message, the node will respond with a `SET` message if successful.

examples/Template/Template.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ NodeManager. Just uncomment the settings you need and the sensors you want to ad
355355
//#include <sensors/SensorPca9685Rgbw.h>
356356
//SensorPca9685Rgbw pca9685Rgbw;
357357

358+
//#include <sensors/SensorDSM501A.h>
359+
//SensorDSM501A DSM501A;
360+
358361
/***********************************
359362
* Main Sketch
360363
*/

keywords.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,5 @@ SensorWaterMeter KEYWORD1
214214
SensorPH KEYWORD1
215215
SensorPca9685Rgb KEYWORD1
216216
SensorPca9685Rgbw KEYWORD1
217-
SensorPca9685W KEYWORD1
217+
SensorPca9685W KEYWORD1
218+
SensorDSM501A KEYWORD1

sensors/SensorDSM501A.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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-2017 Sensnology AB
10+
* Full contributor list: https://github.com/mysensors/Arduino/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+
#ifndef SensorDSM501A_h
20+
#define SensorDSM501A_h
21+
22+
/*
23+
SensorDSM501A
24+
*/
25+
26+
class SensorDSM501A: public Sensor {
27+
28+
protected:
29+
int8_t _pin_10;
30+
int8_t _pin_25;
31+
int _temperature = 20;
32+
33+
public:
34+
SensorDSM501A(int8_t pin_10 = 3, int8_t pin_25 = 6, uint8_t child_id = 0): Sensor(-1) {
35+
_name = "DSM501A";
36+
_pin_10 = pin_10;
37+
_pin_25 = pin_25;
38+
children.allocateBlocks(2);
39+
new Child(this,INT,nodeManager.getAvailableChildId(child_id),S_DUST,V_LEVEL,_name);
40+
new Child(this,INT,child_id > 0 ? nodeManager.getAvailableChildId(child_id+1) : nodeManager.getAvailableChildId(child_id),S_DUST,V_LEVEL,_name);
41+
};
42+
43+
// [101] set the reference temperature for calculating PM1.0
44+
void setTemperature(int value) {
45+
_temperature = value;
46+
}
47+
48+
// define what to do during setup
49+
void onSetup() {
50+
pinMode(_pin_10,INPUT);
51+
pinMode(_pin_25,INPUT);
52+
};
53+
54+
// define what to do during loop
55+
void onLoop(Child* child) {
56+
if (child == children.get(1)) {
57+
// get PM 1.0 - density of particles over 1 µm.
58+
child->setValue((int)((_getPM(_pin_10)*0.0283168/100/1000) * (0.08205*_temperature)/0.01));
59+
}
60+
if (child == children.get(2)) {
61+
// get PM 2.5 density of particles over 2.5 µm.
62+
child->setValue((int)_getPM(_pin_25));
63+
}
64+
};
65+
66+
// return PM concentration
67+
long _getPM(int pin) {
68+
uint32_t duration;
69+
uint32_t starttime = millis();
70+
uint32_t endtime;
71+
uint32_t sampletime_ms = 30000;
72+
uint32_t lowpulseoccupancy = 0;
73+
float ratio = 0;
74+
while (1) {
75+
duration = pulseIn(pin, LOW);
76+
lowpulseoccupancy += duration;
77+
endtime = millis();
78+
if ((endtime-starttime) > sampletime_ms) {
79+
ratio = (lowpulseoccupancy-endtime+starttime)/(sampletime_ms*10.0); // Integer percentage 0=>100
80+
long concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
81+
debug_verbose(PSTR(LOG_SENSOR "l=%u r=%d.%02d c=%d\n"),lowpulseoccupancy,(int)ratio, (int)(ratio*100)%100,concentration);
82+
return(concentration);
83+
}
84+
}
85+
};
86+
87+
#if NODEMANAGER_OTA_CONFIGURATION == ON
88+
// define what to do when receiving an OTA configuration request
89+
void onOTAConfiguration(ConfigurationRequest* request) {
90+
switch(request->getFunction()) {
91+
case 101: setTemperature(request->getValueInt()); break;
92+
default: return;
93+
}
94+
};
95+
#endif
96+
};
97+
#endif

0 commit comments

Comments
 (0)