https://github.com/richardhmm/DIYRepo/tree/master/arduino/libraries/DSM501
authorDobrica Pavlinusic <dpavlin@rot13.org>
Sat, 14 Dec 2019 16:15:13 +0000 (17:15 +0100)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Sat, 14 Dec 2019 16:15:13 +0000 (17:15 +0100)
libraries/DSM501/DSM501.cpp [new file with mode: 0644]
libraries/DSM501/DSM501.h [new file with mode: 0644]
libraries/DSM501/README.md [new file with mode: 0644]
libraries/DSM501/examples/DSM501/DSM501.ino [new file with mode: 0644]

diff --git a/libraries/DSM501/DSM501.cpp b/libraries/DSM501/DSM501.cpp
new file mode 100644 (file)
index 0000000..03339e7
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+The MIT License (MIT)
+
+Copyright (c) 2015 richardhmm
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+#include "DSM501.h"
+
+DSM501::DSM501(int pin10, int pin25) {
+       _pin[PM10_IDX] = pin10;
+       _pin[PM25_IDX] = pin25;
+
+       for (int i = 0; i < 2; i++) {
+               _win_total[i] = 0;
+               _low_total[i] = 0;
+               _lastLowRatio[i] = -1;
+               _done[i] = 0;
+       }
+       
+}
+
+void DSM501::begin(uint32_t span) {
+       pinMode(_pin[PM10_IDX], INPUT);
+       pinMode(_pin[PM25_IDX], INPUT);
+               
+       if (span < MIN_WIN_SPAN)
+           _span = MIN_WIN_SPAN * 1000;
+       else if (span > MAX_WIN_SPAN)
+           _span = MAX_WIN_SPAN * 1000;
+       else
+           _span = span * 1000;
+}
+
+void DSM501::reset() {
+       for (int i = 0; i < 2; i++) {
+               _win_total[i] = 0;
+               _low_total[i] = 0;
+               _done[i] = 0;
+       }
+}
+
+void DSM501::update() {
+       uint32_t start = millis();
+       for(;;)
+       {
+               if (millis() < start || millis() - start >= _span)
+               {
+                   _done[0] = 1;
+                   _done[1] = 1;
+                   break;
+               }
+              _win_total[0] ++;
+               _low_total[0] += !digitalRead(_pin[PM10_IDX]);
+               _win_total[1] ++;
+               _low_total[1] += !digitalRead(_pin[PM25_IDX]);
+       }
+}
+
+float DSM501::getLowRatio(int i) {
+       if (_done[i] == 1)
+       {
+           _lastLowRatio[i] = (_low_total[i] * 100.0) / _win_total[i];
+           _low_total[i] = 0;
+           _win_total[i] = 0;
+           _done[i] = 0;
+           return _lastLowRatio[i];
+       }
+       else
+           return _lastLowRatio[i];
+}
+
+
+float DSM501::getParticalWeight(int i) {
+       /*
+        * with data sheet...regression function is
+        *    y=0.1776*x^3-2.24*x^2+ 94.003*x
+        */
+       float r = getLowRatio(i);
+       float weight = 0.1776*pow(r,3) - 0.24*pow(r,2) + 94.003*r;
+       return weight  < 0.0 ? 0.0 : weight;
+}
+
+float DSM501::getPM25() {
+       return getParticalWeight(0) - getParticalWeight(1);
+}
+
+// China pm2.5 Index
+uint32_t DSM501::getAQI() {
+       // this works only under both pin configure
+       uint32_t aqi = 0;
+
+       float P25Weight = getPM25();
+         if (P25Weight>= 0 && P25Weight <= 35) {
+           aqi = 0   + (50.0 / 35 * P25Weight);
+         } 
+         else if (P25Weight > 35 && P25Weight <= 75) {
+           aqi = 50  + (50.0 / 40 * (P25Weight - 35));
+         } 
+         else if (P25Weight > 75 && P25Weight <= 115) {
+           aqi = 100 + (50.0 / 40 * (P25Weight - 75));
+         } 
+         else if (P25Weight > 115 && P25Weight <= 150) {
+           aqi = 150 + (50.0 / 35 * (P25Weight - 115));
+         } 
+         else if (P25Weight > 150 && P25Weight <= 250) {
+           aqi = 200 + (100.0 / 100.0 * (P25Weight - 150));
+         } 
+         else if (P25Weight > 250 && P25Weight <= 500) {
+           aqi = 300 + (200.0 / 250.0 * (P25Weight - 250));
+         } 
+         else if (P25Weight > 500.0) {
+           aqi = 500 + (500.0 / 500.0 * (P25Weight - 500.0)); // Extension
+         } 
+         else {
+           aqi = 0; // Initializing
+         }
+
+       return aqi;
+}
diff --git a/libraries/DSM501/DSM501.h b/libraries/DSM501/DSM501.h
new file mode 100644 (file)
index 0000000..0a0aa66
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+The MIT License (MIT)
+
+Copyright (c) 2015 richardhmm
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+/**
+see also https://github.com/alexjx/AqiMon/blob/master/DSM501.h
+             http://www.guokr.com/article/434130/
+             http://www.geek-workshop.com/thread-3829-1-1.html
+             
+*/
+#ifndef DSM501_H
+#define DSM501_H
+#if ARDUINO >= 100
+ #include "Arduino.h"
+#else
+ #include "WProgram.h"
+#endif
+
+#define MIN_WIN_SPAN   30      // 30S
+#define MAX_WIN_SPAN     300   // 300S
+
+#define PM10_PIN       3
+#define PM25_PIN       4
+
+#define PM10_IDX       0
+#define PM25_IDX       1
+
+class DSM501 {
+public:
+       DSM501(int pin10 = PM10_PIN, int pin25 = PM25_PIN);
+       void begin(uint32_t span = MIN_WIN_SPAN);
+       void update(); // called in the loop function for update
+       void reset();
+
+       float getLowRatio(int i = 0);
+       float getParticalWeight(int i = 0);
+       float getPM25();
+       uint32_t getAQI();
+
+private:
+       int _pin[2];
+       uint32_t _low_total[2];
+       uint32_t _win_total[2];
+       uint32_t _span;
+       uint8_t _done[2];
+       float _lastLowRatio[2];
+};
+
+#endif
diff --git a/libraries/DSM501/README.md b/libraries/DSM501/README.md
new file mode 100644 (file)
index 0000000..20b536e
--- /dev/null
@@ -0,0 +1,9 @@
+Debug note(调试心得)
+=======
+
+1. Do not put DSM501 in sun. (不要让传感器DSM501暴露在阳光下工作)
+2. Do not put DSM501 in LED light. (不要让DSM501暴露在LED灯、日光灯下工作)
+3. Must be use a good quality supply power. (必须使用好的电源,比如手机电源适配器5V给arduino和DMS501供电)
+
+That is all, if not, PM2.5 data will very big.
+
diff --git a/libraries/DSM501/examples/DSM501/DSM501.ino b/libraries/DSM501/examples/DSM501/DSM501.ino
new file mode 100644 (file)
index 0000000..25a39c1
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+The MIT License (MIT)
+
+Copyright (c) 2015 richardhmm
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+/**
+   connect the sensor as follows :
+          Pin 2 of dust sensor PM1.0      -> Digital 3
+         Pin 3 of dust sensor          -> +5V 
+         Pin 4 of dust sensor PM2.5    -> Digital 4
+         Pin 5 of dust sensor          -> Ground
+  Datasheet: http://www.samyoungsnc.com/products/3-1%20Specification%20DSM501.pdf
+*/
+#include<DSM501.h>
+
+#define DSM501_PM10 3
+#define DSM501_PM25 4
+
+DSM501 dsm501(DSM501_PM10, DSM501_PM25);
+
+void setup()
+{
+  Serial.begin(9600);  //for output information
+
+  // Initialize DSM501
+  dsm501.begin(MIN_WIN_SPAN);
+
+  // wait 60s for DSM501 to warm up
+  for (int i = 1; i <= 60; i++)
+  {
+    delay(1000); // 1s
+    Serial.print(i);
+    Serial.println(" s (wait 60s for DSM501 to warm up)");
+  }
+}
+
+void loop()
+{
+  // call dsm501 to handle updates.
+  dsm501.update();
+  
+  // get PM density of particles over 1.0 μm
+  Serial.print("PM10: ");
+  Serial.print(dsm501.getParticalWeight(0));
+  Serial.println(" ug/m3");
+  
+  // get PM density of particles over 2.5 μm
+  Serial.print("PM25: ");
+  Serial.print(dsm501.getParticalWeight(1));
+  Serial.println(" ug/m3");
+  
+  Serial.print("AQI: ");
+  Serial.println(dsm501.getAQI());
+  
+  // get PM2.5 density of particles between 1.0~2.5 μm
+  Serial.print("PM2.5: ");
+  Serial.print(dsm501.getPM25());
+  Serial.println(" ug/m3");
+}
+
+
+
+
+
+
+