DSM501 dust sensor plugin

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
serpa
New user
Posts: 4
Joined: 27 Dec 2015, 14:45

DSM501 dust sensor plugin

#1 Post by serpa » 06 Mar 2016, 16:28

Hi,
I am interested in making environmental sensors. One hot topic in this field is dust/pollution sensors.
Among the available low cost modules thare is the DSM 501 sold for about 7 euro by aliexpress
DSM501.jpg
DSM501.jpg (4.02 KiB) Viewed 8152 times
This sensor has two outputs, one for PM1.0 and one for PM2.5
The outputs are digital and the measurement consists in evauating the time each output stays low in a given time interval (suggested 30 sec).
The details are on the data sheets widely available online, wher also is possible to extract a sort of calibration.
It is clear that these sensor, as well as the cousin GP2Y1010AU, cannot give precise values, but can nevertheless provide usefull information on the change of particulate in the air. I have tested these sensors in my some for about three months and the results are quite interesting: I can clearly see the increase of particulate when there is presence of people in the surrounding, when the house heating is on and when we are cooking.
Having come to know of the espeasy project I wished to include this sensor in the list of available ones.
The problems were:
I haven't found any tutorial on how to make new plugins (I REALLY MISS THIS!!)
The reading process cannot be blocking, as the ESP has other tasks to do (keep the wifi on). So I had to resort to use the interrupts.
In the end I have developep the following plugin, by hacking other plugins.

It works well (with 082 release of espeasy), but I would like to know if someone has some suggestions on how to make it more a "standard" plugin


//#######################################################################################################
//#################################### Plugin 030: DMS501A #############################################
//#################################### by serpa #############################################
//#######################################################################################################

#define PLUGIN_030
#define PLUGIN_ID_030 30
#define PLUGIN_NAME_030 "Dust DMS501A"
#define PLUGIN_VALUENAME1_030 "PM1.0"
#define PLUGIN_VALUENAME2_030 "PM2.5"

unsigned long Plugin_030_pulseCounter[TASKS_MAX];
unsigned long Plugin_030_pulseTotalCounter[TASKS_MAX];
unsigned long Plugin_030_pulseTime[TASKS_MAX];
unsigned long Plugin_030_pulseTimePrevious[TASKS_MAX];
unsigned long tstart1, tstart2;
unsigned long tduration = 30000; // duration of measurement in ms
//unsigned long triggerOn; // start of pulse time in us
//unsigned long triggerOff; // end of pulse time in us
//unsigned long lowpulseoccupancy; // duration of pulse in us
volatile unsigned long thigh1, thigh2;
volatile unsigned long tlow1, tlow2;
volatile unsigned long startlow1, startlow2;
volatile unsigned long starthigh1, starthigh2;
volatile boolean done1, done2;
volatile boolean value1, value2;
//boolean trigger = false;
volatile float ratio1, ratio2;
volatile int DMSpin1, DMSpin2;
float dens1, dens2;
boolean Plugin_030(byte function, struct EventStruct *event, String& string)
{
boolean success = false;

switch (function)
{

case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_030;
Device[deviceCount].Type = DEVICE_TYPE_DUAL;
Device[deviceCount].VType = SENSOR_TYPE_TEMP_HUM;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 2;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
break;
}

case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_030);
break;
}

case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_030));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_030));
break;
}

case PLUGIN_WEBFORM_LOAD:
{
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Averaging Time (mSec):<TD><input type='text' name='plugin_030' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
string += tmpString;
success = true;
break;
}

case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg("plugin_030");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
// tduration= Settings.TaskDevicePluginConfig[event->TaskIndex][0];
success = true;
break;
}


case PLUGIN_INIT:
{
String log = F("INIT : DSM501A ");
log += Settings.TaskDevicePin1[event->TaskIndex];
addLog(LOG_LEVEL_INFO,log);
// tduration= Settings.TaskDevicePluginConfig[event->TaskIndex][0];
tstart1=millis();
startlow1=micros();
starthigh1=startlow1;
DMSpin1=Settings.TaskDevicePin1[event->TaskIndex];
pinMode(DMSpin1, INPUT);
attachInterrupt(digitalPinToInterrupt(DMSpin1),Plugin_030_ISR1,CHANGE);
tstart2=millis();
startlow2=micros();
starthigh2=startlow2;
DMSpin2=Settings.TaskDevicePin2[event->TaskIndex];
pinMode(DMSpin2, INPUT);
attachInterrupt(digitalPinToInterrupt(DMSpin2),Plugin_030_ISR2,CHANGE);
success = true;
break;
}

case PLUGIN_READ:
{
if (done1 && done2) {
done1=FALSE;
dens1 = ratio1 *110; // ug/m^3
done2=FALSE;
dens2 = ratio2 *110; // ug/m^3

String log = F("DSM501A: PM1.0=");
log += dens1;
log += F(" PM2.5=");
log += dens2;
addLog(LOG_LEVEL_INFO,log);
UserVar[event->BaseVarIndex] = (float) dens1;
UserVar[event->BaseVarIndex + 1] = (float) dens2;
}
success = true;
break;
}
}
return success;
}


/*********************************************************************************************\
* Check Pulse (called from irq handler)
\*********************************************************************************************/
void Plugin_030_ISR1()
{
value1 = digitalRead(DMSpin1); //read input pin just changed
if (value1 == 0) { // gone low
startlow1=micros(); // record starting of low period
thigh1 += startlow1-starthigh1; // record duration of past high state
} else { // gone high
starthigh1=micros(); // record starting of high period
tlow1 += starthigh1-startlow1; // record duration of past low state
}
if (millis()>tstart1+tduration) { // check if average time has past
tstart1 = millis(); // reset time period
ratio1=float(tlow1)/float(thigh1+tlow1)*100; // compute ratio low to total
tlow1=0; // reset low time counter
thigh1=0; // reset high time counter
done1 = TRUE; // set reading complete flag
}
}
/*********************************************************************************************\
* Check Pulse (called from irq handler)
\*********************************************************************************************/
void Plugin_030_ISR2()
{
value2 = digitalRead(DMSpin2); //read input pin just changed
if (value2 == 0) { // gone low
startlow2=micros(); // record starting of low period
thigh2 += startlow2-starthigh2; // record duration of past high state
} else { // gone high
starthigh2=micros(); // record starting of high period
tlow2 += starthigh2-startlow2; // record duration of past low state
}
if (millis()>tstart2+tduration) { // check if average time has past
tstart2 = millis(); // reset time period
ratio2=float(tlow2)/float(thigh2+tlow2)*100; // compute ratio low to high
tlow2=0; // reset low time counter
thigh2=0; // reset high time counter
done2 = TRUE; // set reading complete flag
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////

megagolgoth
New user
Posts: 2
Joined: 24 Aug 2016, 22:19

Re: DSM501 dust sensor plugin

#2 Post by megagolgoth » 24 Aug 2016, 22:28

Hi,

Very interesting !

I took the liberty to submit your code (with small changes, like plugin number, name of variable (DMSpin to DSMpin), formating) here : https://github.com/ESP8266nu/ESPEasyPlu ... und/pull/6

I was able to compile it with the revision on the official ESPEasy release.

However, I wasn't able to put cables of my DSM501A on the right place on the board (GPIO12-GPIO14 so D5-D6)... VCC and Ground were maybe right, but there is three output, Output 1, Output 2 and Control Output...

It's confusing for me... Could you explain where you put the cable?

grz3
Normal user
Posts: 36
Joined: 21 Feb 2016, 21:47

Re: DSM501 dust sensor plugin

#3 Post by grz3 » 07 Dec 2016, 08:57

did some one figured out how to connect this sensor to ESP? which pin to which? any aditional components are needed? thank you for any help or scheme.
grz

dony71
Normal user
Posts: 16
Joined: 25 Apr 2018, 20:01

Re: DSM501 dust sensor plugin

#4 Post by dony71 » 26 Apr 2018, 02:22

any instruction how to calibrate this sensor?

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 23 guests