Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Hardware
  3. Air Quality Sensor

Air Quality Sensor

Scheduled Pinned Locked Moved Hardware
calibrationaqigas sensorhchoair quality
270 Posts 46 Posters 309.1k Views 35 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B bhavika

    I am confused with MiCS 4514 sensor. What I had done is :

    using MiCS quick start evaluation board, measured ADC value
    calculated Vout and from that calculated R0.
    Rs/R0 concentration gives me high value, which is not possible, My data is as follows
    clean air file is used for the purpose of R0 value
    https://drive.google.com/file/d/0B8sF8a6FHoseWjhWOHRoYzIxakk/view?usp=sharing
    and Polluted file is used to calculate the actual pollution
    https://drive.google.com/file/d/0B8sF8a6FHoseR1BnclhCUHdibEU/view?usp=sharing

    I am confused. Please help me

    VirV Offline
    VirV Offline
    Vir
    wrote on last edited by
    #186

    @bhavika said:

    I am confused with MiCS 4514 sensor. What I had done is :

    using MiCS quick start evaluation board, measured ADC value
    calculated Vout and from that calculated R0.
    Rs/R0 concentration gives me high value, which is not possible, My data is as follows
    clean air file is used for the purpose of R0 value
    https://drive.google.com/file/d/0B8sF8a6FHoseWjhWOHRoYzIxakk/view?usp=sharing
    and Polluted file is used to calculate the actual pollution
    https://drive.google.com/file/d/0B8sF8a6FHoseR1BnclhCUHdibEU/view?usp=sharing

    I am confused. Please help me

    I am confused by the formula you are using, could you please explain?
    Pollution NO2 = (POWER((RS/R0)*(1/POWER(10,0.8068)),(1/1.01)))

    Pollution CO = POWER((RS/R0)*(1/POWER(10 , 0.5476)),(1/-0.8497)))

    is the actual formula like this?:

    pollution = POWER((ratio *(1/POWER(10, curve[0])),(1/[curve[1])))

    This is different than any other formulas discussed in this thread...
    Vir

    1 Reply Last reply
    0
    • VirV Vir

      What does 37143 represents, Rs? and -3.178 is a second value from your regression method, but what about the first value?
      Can you elaborate on ppm line, please
      Vir

      here the formula is a simplification of this:

      float Vrl = val * ( 5.00 / 1024.0 ); // V
      float Rs = 20000 * ( 5.00 - Vrl) / Vrl ; // Ohm
      int ratio = Rs/Ro;
      ppm = 37143 * pow (ratio, -3.178);

      VirV Offline
      VirV Offline
      Vir
      wrote on last edited by
      #187

      so does 37164 represents the scaling factor and -3.178 the exponent?
      Vir
      @Vir said:

      What does 37143 represents, Rs? and -3.178 is a second value from your regression method, but what about the first value?
      Can you elaborate on ppm line, please
      Vir

      here the formula is a simplification of this:

      float Vrl = val * ( 5.00 / 1024.0 ); // V
      float Rs = 20000 * ( 5.00 - Vrl) / Vrl ; // Ohm
      int ratio = Rs/Ro;
      ppm = 37143 * pow (ratio, -3.178);

      1 Reply Last reply
      0
      • alexsh1A Offline
        alexsh1A Offline
        alexsh1
        wrote on last edited by alexsh1
        #188

        @epierre I have the problem with the dust sketch (shinyei ppd42ns). The following code does not work in MySensors 1.5

        ...
        gw.send(msgPM10.set("ppm"));
          ...
        gw.send(msgPM25.set("ppm")); 
        ...
        
        2016-04-24 14:44:19.438 Error: MySensors: Unknown/Invalid sensor type (43)
        2016-04-24 14:44:19.438 Error: MySensors: Unknown/Invalid sensor type (43)
        

        So far both PM10 and PM25 are showing zero. However, if I upload the following code, it works fine (one channel though):

        // Watch video here: https://www.youtube.com/watch?v=a8r4CeQopfY
        
        /* 
         Connection:
         
         JST Pin 1 (Black Wire)  => Arduino GND
         JST Pin 3 (Red wire)    => Arduino 5VDC
         JST Pin 4 (Yellow wire) => Arduino Digital Pin 8
        
         Green Led connected to Arduino D7
         Yellow Led connected to Arduino D6
         Red Led connected to Arduino D5
         
         
        Dust Sensor possible application:
        - Applications of customer
        - Air quality sensor
        - Dustlessness workshop
        - Cigarette detector
        */
        
        /*
        Sensor is to create Digital (Lo Pulse) output to Particulate Matters (PM). Lo Pulse Occupancy time (LPO time) is in proportion
        to PM concentration. The output is for PM whose size is around 1 micro meter or larger. We can use the sensor to detect the dust in clean room.
        Minimum detect particle: 1um
        http://www.seeedstudio.com/wiki/Grove_-_Dust_Sensor
         Grove - Dust Sensor Demo v1.0
         Interface to Shinyei Model PPD42NS Particle Sensor
         Program by Christopher Nafis 
         Written April 2012
         
         http://www.seeedstudio.com/depot/grove-dust-sensor-p-1050.html
         http://www.sca-shinyei.com/pdf/PPD42NS.pdf
         */
        
        int pin = 8;
        unsigned long duration;
        unsigned long starttime;
        unsigned long sampletime_ms = 1000;//sampe 1s ;
        unsigned long lowpulseoccupancy = 0;
        float ratio = 0;
        float concentration = 0;
        int gLed = 7;
        int yLed = 6;
        int rLed = 5;
        
        void setup() {
          Serial.begin(9600);
          pinMode(8,INPUT);
          pinMode(gLed,OUTPUT);
          pinMode(yLed,OUTPUT);
          pinMode(rLed,OUTPUT);
          starttime = millis();//get the current time;
        }
        
        void loop() {
          duration = pulseIn(pin, LOW);
          lowpulseoccupancy = lowpulseoccupancy+duration;
        
          if ((millis()-starttime) > sampletime_ms)//if the sampel time == 30s
          {
            ratio = lowpulseoccupancy/(sampletime_ms*10.0);  // Integer percentage 0=>100
            concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
            Serial.print("concentration = ");
            Serial.print(concentration);
            Serial.print(" pcs/0.01cf  -  ");
            if (concentration < 1.0) {
             Serial.println("It's a smokeless and dustless environment"); 
             digitalWrite(gLed, HIGH);
             digitalWrite(yLed, LOW);
             digitalWrite(rLed, LOW);
          }
            if (concentration > 1.0 && concentration < 20000) {
             Serial.println("It's probably only you blowing air to the sensor :)"); 
             digitalWrite(gLed, HIGH);
             digitalWrite(yLed, LOW);
             digitalWrite(rLed, LOW);
            }
            
            if (concentration > 20000 && concentration < 315000) {
             Serial.println("Smokes from matches detected!"); 
             digitalWrite(gLed, LOW);
             digitalWrite(yLed, HIGH);
             digitalWrite(rLed, LOW);
            }
              if (concentration > 315000) {
             Serial.println("Smokes from cigarettes detected! Or It might be a huge fire! Beware!"); 
             digitalWrite(gLed, LOW);
             digitalWrite(yLed, LOW);
             digitalWrite(rLed, HIGH);
          }
            
            lowpulseoccupancy = 0;
            starttime = millis();
          }
        }
        
        
        1 Reply Last reply
        0
        • epierreE epierre

          Hello,

          sadly the discussions were lost...

          So let's start again on the subject:

          https://github.com/empierre/arduino

          Here is the list of my current experimentations:

          • MQ135.ino : for CO2/COV ... validated
            
          • MQ2.ino : for ethanol... needs pre-heat : ongoing
          • MQ6 sensor : just received
          • MQ131 sensor : just received
          • TGS2600 sensor : just received

          I'm getting serious a with a mega and a sensor board, 4 of them are connected together !

          The MQ135 is not on the list, I use it to measure CO2 in children's room...
          Values:

          • MQ2: 85 - Combustible gas and smoke
          • MQ6: 25 - Isobutane, Butane, LPG
          • MQ131: 57 - O3, CL2
          • TGS2600: 943 - ethanol, hydrogen, iso-butane, CO, Methane

          As discussed before, I would appreciate someone helping me reading the logarithmic curves in the datasheet (link on each sensor name above) to get the linear value based on analog reading. I need to learn reading it... thanks!

          as an example here in sandboxelectronics we saw that several values could be read from the datasheet:

          float           LPGCurve[3]  =  {2.3,0.21,-0.47};   //two points are taken from the curve.
                                                              //with these two points, a line is formed which is "approximately equivalent"
                                                           //to the original curve.
                                                          //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59)
          float           COCurve[3]  =  {2.3,0.72,-0.34};    //two points are taken from the curve.
                                                          //with these two points, a line is formed which is "approximately equivalent"
                                                          //to the original curve.
                                                          //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000,  0.15)
          float           SmokeCurve[3] ={2.3,0.53,-0.44};    //two points are taken from the curve.
                                                          //with these two points, a line is formed which is "approximately equivalent"
                                                          //to the original curve.
                                                          //data format:{ x, y, slope}; point1: (lg200, 0.53), point2: (lg10000,  -0.22)                                                    
          float           Ro           =  10;                 //Ro is initialized to 10 kilo ohms
          
          AnneFRA Offline
          AnneFRA Offline
          AnneFR
          wrote on last edited by
          #189

          @epierre hi, could remove some doubts regarding the mq131 sensor?
          thanks,
          Anne

          1 Reply Last reply
          0
          • epierreE Offline
            epierreE Offline
            epierre
            Hero Member
            wrote on last edited by
            #190

            @alexsh1 said:

            (shinyei ppd42ns)

            I corrected the following sketch which had bad yg/m3 to ppm conversion thanks to LouiS22 from Domoticz forum remark (type conversion errors leading to 0 values).

            https://github.com/empierre/arduino/blob/master/DustSensor_SamYoung_DSM501.ino

            I guess I'll have to do the same here (but I lack time...):
            DustSensor_Shinyei_PPD42NS.ino

            z-wave - Vera -&gt; Domoticz
            rfx - Domoticz &lt;- MyDomoAtHome &lt;- Imperihome
            mysensors -&gt; mysensors-gw -&gt; Domoticz

            alexsh1A 1 Reply Last reply
            0
            • epierreE epierre

              @alexsh1 said:

              (shinyei ppd42ns)

              I corrected the following sketch which had bad yg/m3 to ppm conversion thanks to LouiS22 from Domoticz forum remark (type conversion errors leading to 0 values).

              https://github.com/empierre/arduino/blob/master/DustSensor_SamYoung_DSM501.ino

              I guess I'll have to do the same here (but I lack time...):
              DustSensor_Shinyei_PPD42NS.ino

              alexsh1A Offline
              alexsh1A Offline
              alexsh1
              wrote on last edited by
              #191

              @epierre Thanks - I'll have another go at Shinyei PPD42NS sketch once I have time. Ideally, I'd like to combine it with MH-Z14A sketch.

              epierreE 1 Reply Last reply
              0
              • alexsh1A alexsh1

                @epierre Thanks - I'll have another go at Shinyei PPD42NS sketch once I have time. Ideally, I'd like to combine it with MH-Z14A sketch.

                epierreE Offline
                epierreE Offline
                epierre
                Hero Member
                wrote on last edited by
                #192

                @alexsh1 which is a good idea, also a temp/him is quite usefull though I didn't added the impact in the formulas so far.

                z-wave - Vera -&gt; Domoticz
                rfx - Domoticz &lt;- MyDomoAtHome &lt;- Imperihome
                mysensors -&gt; mysensors-gw -&gt; Domoticz

                alexsh1A 2 Replies Last reply
                0
                • epierreE epierre

                  @alexsh1 which is a good idea, also a temp/him is quite usefull though I didn't added the impact in the formulas so far.

                  alexsh1A Offline
                  alexsh1A Offline
                  alexsh1
                  wrote on last edited by alexsh1
                  #193

                  @epierre I have combined the two sketches - works just fine, but need to find a spare temp sensor.The hardware setup looks messy so adding an extra i2c sensor will complicate it even more. I'll come back with the combined three-in-one sketch shortly.

                  BTW, this

                  gw.send(msgPM25.set("ppm"));
                  

                  still throws the following error. What version MySensors are you using?

                   MySensors: Unknown/Invalid sensor type (43)
                  
                  1 Reply Last reply
                  0
                  • epierreE epierre

                    @alexsh1 which is a good idea, also a temp/him is quite usefull though I didn't added the impact in the formulas so far.

                    alexsh1A Offline
                    alexsh1A Offline
                    alexsh1
                    wrote on last edited by alexsh1
                    #194

                    @epierre I started looking at the formula you have used in ppmv calculation. Why do you need ppmv? All values in EPA or Europe are in μg/m3.

                    The ppmv equation is:

                    ppmv = mg/m^3 * (0.08205*T)/M 
                    

                    T = atmospheric temperature in kelvins = 273.15 + °C
                    M = molecular weight of the air pollutant = 28.97
                    (http://www.engineeringtoolbox.com/molecular-mass-air-d_679.html - this is a good link)
                    0.08205 = Universal Gas Law constant in atm·l/(mol·K)

                    Your code for this equation is:

                    ppmv=(float)(((concentrationPM25*0.0283168)/100) * ((0.08205*temp)/0.01))/1000;
                    

                    Now, I think it should be as follows:

                    1. temp = °C + 273.15
                    int temp=273.15 + 22;
                    
                    

                    22C - is a typical temp inside though the intention is to use a sensor

                    1. The amended ppmv equation is going to be:
                    ppmv=(((concentrationPM25*0.0283168)/100) * ((0.08205*temp)/28.97))/1000;
                    

                    I have not changed 0.0283168 /100 - not sure that this is. And the whole thing is divided by 1000? why?

                    IMPORTANT UPDATE:

                    I have just received the following result:

                    
                    PM10: 7373
                    
                    send: 11-11-0-0 s=0,c=1,t=37,pt=7,l=5,sg=0,st=ok:1.744
                    
                    

                    If I use the following web-site http://www.herramientasingenieria.com/onlinecalc/ppm-mg_m3.php and the result is
                    mg/m3 = 7373 * 0.283168/100 = 2.08 mg/m3
                    The molecular weight is 28.97 for dry air

                    2.08 mg/m3 is equivalent to 1.74ppm for a gas with molecular weight=28.97 Pressure=1013.25, Temperature=22C 
                    

                    Success!
                    Now I have found a spare BMP280 (temp and pressure sensor) which I can use here.
                    Additionally, I need to use 24-h and 1 year averages - https://www3.epa.gov/airquality/particlepollution/2012/decfsstandards.pdf

                    Stay tuned!

                    epierreE 1 Reply Last reply
                    0
                    • alexsh1A alexsh1

                      @epierre I started looking at the formula you have used in ppmv calculation. Why do you need ppmv? All values in EPA or Europe are in μg/m3.

                      The ppmv equation is:

                      ppmv = mg/m^3 * (0.08205*T)/M 
                      

                      T = atmospheric temperature in kelvins = 273.15 + °C
                      M = molecular weight of the air pollutant = 28.97
                      (http://www.engineeringtoolbox.com/molecular-mass-air-d_679.html - this is a good link)
                      0.08205 = Universal Gas Law constant in atm·l/(mol·K)

                      Your code for this equation is:

                      ppmv=(float)(((concentrationPM25*0.0283168)/100) * ((0.08205*temp)/0.01))/1000;
                      

                      Now, I think it should be as follows:

                      1. temp = °C + 273.15
                      int temp=273.15 + 22;
                      
                      

                      22C - is a typical temp inside though the intention is to use a sensor

                      1. The amended ppmv equation is going to be:
                      ppmv=(((concentrationPM25*0.0283168)/100) * ((0.08205*temp)/28.97))/1000;
                      

                      I have not changed 0.0283168 /100 - not sure that this is. And the whole thing is divided by 1000? why?

                      IMPORTANT UPDATE:

                      I have just received the following result:

                      
                      PM10: 7373
                      
                      send: 11-11-0-0 s=0,c=1,t=37,pt=7,l=5,sg=0,st=ok:1.744
                      
                      

                      If I use the following web-site http://www.herramientasingenieria.com/onlinecalc/ppm-mg_m3.php and the result is
                      mg/m3 = 7373 * 0.283168/100 = 2.08 mg/m3
                      The molecular weight is 28.97 for dry air

                      2.08 mg/m3 is equivalent to 1.74ppm for a gas with molecular weight=28.97 Pressure=1013.25, Temperature=22C 
                      

                      Success!
                      Now I have found a spare BMP280 (temp and pressure sensor) which I can use here.
                      Additionally, I need to use 24-h and 1 year averages - https://www3.epa.gov/airquality/particlepollution/2012/decfsstandards.pdf

                      Stay tuned!

                      epierreE Offline
                      epierreE Offline
                      epierre
                      Hero Member
                      wrote on last edited by
                      #195

                      @alexsh1 said:

                      @epierre I started looking at the formula you have used in ppmv calculation. Why do you need ppmv? All values in EPA or Europe are in μg/m3.

                      because domoticz only knows ppm... and many AIQ like use only that except for particles.

                      1. temp = °C + 273.15
                        int temp=273.15 + 22;
                        22C - is a typical temp inside though the intention is to use a sensor

                      not for me ;-)

                      1. The amended ppmv equation is going to be:
                        ppmv=(((concentrationPM250.0283168)/100) * ((0.08205temp)/28.97))/1000;
                      I have not changed 0.0283168 /100 - not sure that this is. And the whole thing is divided by 1000? why?
                      

                      was a volume conversion

                      The molecular weight is 28.97 for dry air

                      2.08 mg/m3 is equivalent to 1.74ppm for a gas with molecular weight=28.97 Pressure=1013.25, Temperature=22C 
                      

                      Success!

                      success for the mysensors value ?

                      MySensors: Unknown/Invalid sensor type (43)
                      

                      Domoticz doesn't recognize this command... I use 1.5.x but I have my own gateway to domoticz

                      z-wave - Vera -&gt; Domoticz
                      rfx - Domoticz &lt;- MyDomoAtHome &lt;- Imperihome
                      mysensors -&gt; mysensors-gw -&gt; Domoticz

                      alexsh1A bezeeflyB 2 Replies Last reply
                      0
                      • epierreE epierre

                        @alexsh1 said:

                        @epierre I started looking at the formula you have used in ppmv calculation. Why do you need ppmv? All values in EPA or Europe are in μg/m3.

                        because domoticz only knows ppm... and many AIQ like use only that except for particles.

                        1. temp = °C + 273.15
                          int temp=273.15 + 22;
                          22C - is a typical temp inside though the intention is to use a sensor

                        not for me ;-)

                        1. The amended ppmv equation is going to be:
                          ppmv=(((concentrationPM250.0283168)/100) * ((0.08205temp)/28.97))/1000;
                        I have not changed 0.0283168 /100 - not sure that this is. And the whole thing is divided by 1000? why?
                        

                        was a volume conversion

                        The molecular weight is 28.97 for dry air

                        2.08 mg/m3 is equivalent to 1.74ppm for a gas with molecular weight=28.97 Pressure=1013.25, Temperature=22C 
                        

                        Success!

                        success for the mysensors value ?

                        MySensors: Unknown/Invalid sensor type (43)
                        

                        Domoticz doesn't recognize this command... I use 1.5.x but I have my own gateway to domoticz

                        alexsh1A Offline
                        alexsh1A Offline
                        alexsh1
                        wrote on last edited by
                        #196

                        @epierre Yes, all works fine now. I modified the combined sketch and here is the final result.

                        0_1463152922051_Screenshot (21).jpg

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          moskovskiy82
                          wrote on last edited by
                          #197

                          Which one to use for detection of fire smoke? Currently have got several MQ-7 but they don't seem so good at it

                          epierreE 1 Reply Last reply
                          0
                          • M moskovskiy82

                            Which one to use for detection of fire smoke? Currently have got several MQ-7 but they don't seem so good at it

                            epierreE Offline
                            epierreE Offline
                            epierre
                            Hero Member
                            wrote on last edited by
                            #198

                            @moskovskiy82 said:

                            Which one to use for detection of fire smoke? Currently have got several MQ-7 but they don't seem so good at it

                            as discussed just above, a particle sensor could be good for smoke is a particle concentration, coupled with heat this would be a good indicator

                            if (concentration > 315000) {
                                 Serial.println("Smokes from cigarettes detected! Or It might be a huge fire! Beware!"); 
                            

                            z-wave - Vera -&gt; Domoticz
                            rfx - Domoticz &lt;- MyDomoAtHome &lt;- Imperihome
                            mysensors -&gt; mysensors-gw -&gt; Domoticz

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              moskovskiy82
                              wrote on last edited by
                              #199

                              What about mq2 or mq135? Any experience? As a gas sensor will be more suitable detecting early fire

                              epierreE 1 Reply Last reply
                              0
                              • M moskovskiy82

                                What about mq2 or mq135? Any experience? As a gas sensor will be more suitable detecting early fire

                                epierreE Offline
                                epierreE Offline
                                epierre
                                Hero Member
                                wrote on last edited by
                                #200

                                @moskovskiy82 said:

                                What about mq2 or mq135? Any experience? As a gas sensor will be more suitable detecting early fire

                                please see what it does, this is not a gas sensor this only detect particle size whatever the gas...

                                z-wave - Vera -&gt; Domoticz
                                rfx - Domoticz &lt;- MyDomoAtHome &lt;- Imperihome
                                mysensors -&gt; mysensors-gw -&gt; Domoticz

                                M 1 Reply Last reply
                                0
                                • epierreE epierre

                                  @moskovskiy82 said:

                                  What about mq2 or mq135? Any experience? As a gas sensor will be more suitable detecting early fire

                                  please see what it does, this is not a gas sensor this only detect particle size whatever the gas...

                                  M Offline
                                  M Offline
                                  moskovskiy82
                                  wrote on last edited by
                                  #201

                                  @epierre
                                  It still detects concentration. Both state CO detection. So in case of fire won't they detect the increase in concentration much faster that the particle sensor like Sharp’s GP2Y1010AU0F or alternative?

                                  alexsh1A 1 Reply Last reply
                                  0
                                  • M moskovskiy82

                                    @epierre
                                    It still detects concentration. Both state CO detection. So in case of fire won't they detect the increase in concentration much faster that the particle sensor like Sharp’s GP2Y1010AU0F or alternative?

                                    alexsh1A Offline
                                    alexsh1A Offline
                                    alexsh1
                                    wrote on last edited by
                                    #202

                                    @moskovskiy82 For a fire smoke, you can use pretty much any gas or particle sensor - there are a quite few gases formed during the burning process. MQ2 is highly sensitivity and has a fast response time. I can recommend it for a fire detection usage. However, I have been disappointed in MQ* sensors in general - there are not accurate, require 24h heat-up time, consume a lot of power etc. The only advantage is the price.

                                    To detect fire to can use a flame sensor - http://www.instructables.com/id/Flame-detection-using-Arduino-and-flame-sensor/

                                    1 Reply Last reply
                                    1
                                    • rollercontainerR Offline
                                      rollercontainerR Offline
                                      rollercontainer
                                      wrote on last edited by
                                      #203

                                      Can someone tell me how to read this line?

                                      float mq135_ro = 10000.0;    // this has to be tuned 10K Ohm
                                      

                                      Do I have to messure the sensor and adjust the variable or do I have to tune the resistance? If I have to do the first thing, when do I have to messure it? In warm state and clean air with a multimeter?

                                      1 Reply Last reply
                                      0
                                      • alexsh1A Offline
                                        alexsh1A Offline
                                        alexsh1
                                        wrote on last edited by alexsh1
                                        #204

                                        @epierre Did you check out the airbeam, which is based on a more expensive sensor Shinyei PPD60PV?
                                        http://www.takingspace.org/airbeam-technical-specifications-operation-performance/

                                        They made a step-by-step manual about building the same on Shinyei PPD42NS. I took their code and stripped a few parts and this is what I am left with:

                                        #include  <SoftwareSerial.h>
                                        #include  <FlexiTimer2.h>
                                        
                                        int pin = 3;
                                        
                                        volatile  double  rawParticalCount;
                                        volatile  double  totalParticles  = 0;
                                        volatile  double  particleCountToDisplay  = 0;
                                        volatile  double  ratio = 0;
                                        volatile  uint16_t  timeCounter = 0;
                                        
                                        #define         numberOfPeaksRecording                            5
                                        volatile        uint32_t        previousPeaks[numberOfPeaksRecording];
                                        volatile        uint32_t        sumOfPreviousPeaks          = 0;
                                        volatile        uint32_t        instantGoal                         = 0;
                                        volatile        int32_t         delta                                     = 0;
                                        volatile        uint32_t        slowMovingAverage             = 0;
                                        volatile  boolean readyToSendData = false;
                                        
                                        void  setup() {
                                            Serial.begin(115200);
                                            pinMode(pin,INPUT);
                                            
                                            FlexiTimer2::set(1,1.0/10000,readPin);
                                            FlexiTimer2::start();
                                            
                                        }
                                        void  loop()  {
                                           
                                            
                                            if(readyToSendData){
                                                        Serial.print(rawParticalCount,  DEC);
                                                        Serial.print("  Raw Particle  Count (0-10000) ");
                                                        Serial.print(ratio, DEC);
                                                        Serial.print("  Ratio (0-100%)  ");
                                                        Serial.print(particleCountToDisplay,  DEC); 
                                                        Serial.print("  Particle  Count");
                                                        Serial.println("");
                                                                     
                                                        readyToSendData = false;
                                            }
                                            
                                        }
                                        
                                        void  readPin(){
                                            if(digitalRead(pin) ==  LOW){
                                                rawParticalCount++;
                                            }    
                                            timeCounter++;
                                            if  (timeCounter  ==  10000)
                                            {
                                                timeCounter=0;
                                                   
                                                //Changes are made  here  based on  Chris Nafis's code: http://www.howmuchsnow.com/arduino/airquality/grovedust/
                                                ratio = rawParticalCount/100.0; 
                                                //Convert to  percentage, the shinyei reads 10milliseconds  to  90milliseconds  duration  for particles.  Basing on 10milliseconds, smallest  particle  assumingly  from  specification sheet.
                                                //FlexiTimer2,  reads 10,000  readings  per second, which would be  1 reading per 100 microseconds. 100 readings  would be  10  milliseconds. Since Shinyei runs  at minimal 10  millisecond range.  I divided 10,000  readings  by  100 to  get 100.
                                                //Good  example would be  rawPArticalCount  is  5000  half  of  the 10,000  readings were  active. 5000/100  would be  50  which translate to  50% low pulse occupancy.
                                                totalParticles  = (1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62);
                                                rawParticalCount  = 0;
                                                  
                                                        //  shift counters  over, code  adapted from  template  provided  by  Mike  Taylor  and Joshua  Schapiro  from  Carnegie  Mellon  University's  CREATE  Lab
                                                        for (uint8_t  i = 0;  i < (numberOfPeaksRecording-1); i++)  {
                                                                previousPeaks[i]  = previousPeaks[i+1];
                                                        }
                                                        previousPeaks[numberOfPeaksRecording  - 1]  = totalParticles;
                                                        sumOfPreviousPeaks  = 0;
                                                        for (uint8_t  i = 0;  i < numberOfPeaksRecording; i++)  {
                                                                sumOfPreviousPeaks  +=  previousPeaks[i];
                                                        }
                                                        instantGoal = 2*sumOfPreviousPeaks;
                                                        
                                                        delta = instantGoal - slowMovingAverage;
                                                        
                                                        if  (delta  < -5000){
                                                                slowMovingAverage = slowMovingAverage - 250;
                                                        } else  if  (delta  < -2500){
                                                                slowMovingAverage = slowMovingAverage - 120;
                                                        } else  if(delta  < -1200){
                                                                slowMovingAverage = slowMovingAverage - 60;
                                                        } else  if(delta  < -500){
                                                                slowMovingAverage = slowMovingAverage - 25;
                                                        } else  if(delta  < -5){
                                                                slowMovingAverage = slowMovingAverage - 5;
                                                        } else  if(delta  < -1){
                                                                slowMovingAverage = slowMovingAverage - 1;
                                                        } else  if(delta  > 5000) {
                                                                slowMovingAverage = slowMovingAverage + 500;
                                                        } else  if(delta  > 2500){
                                                                slowMovingAverage = slowMovingAverage + 250;
                                                        } else  if(delta  > 1200){
                                                                slowMovingAverage = slowMovingAverage + 120;
                                                        } else  if(delta  > 500){
                                                                slowMovingAverage = slowMovingAverage + 50;
                                                        } else  if(delta  > 5){
                                                                slowMovingAverage = slowMovingAverage + 5;
                                                        } else  if(delta  > 1){
                                                                slowMovingAverage = slowMovingAverage + 1;
                                                        }
                                                        
                                                        particleCountToDisplay  = slowMovingAverage;
                                                readyToSendData = true;
                                            }
                                        }
                                        

                                        I have not adopted it for MySensors yet.
                                        I like moving average they use, but the values do not make sense to me:

                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  53470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 27.0000000000  Ratio (0-100%)  53970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  54470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 21.6200008392  Ratio (0-100%)  54970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  55470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 24.2800006866  Ratio (0-100%)  55970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  56470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 24.1200008392  Ratio (0-100%)  56970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  57470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 22.3199996948  Ratio (0-100%)  57970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  58470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 20.3600006103  Ratio (0-100%)  58970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  59470.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 17.6299991607  Ratio (0-100%)  59970.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  60220.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 19.0499992370  Ratio (0-100%)  60720.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 0.0000000000  Ratio (0-100%)  60715.0000000000  Particle  Count
                                        0.0000000000  Raw Particle  Count (0-10000) 20.6599998474  Ratio (0-100%)  61215.0000000000  Particle  Count
                                        
                                        1 Reply Last reply
                                        0
                                        • epierreE Offline
                                          epierreE Offline
                                          epierre
                                          Hero Member
                                          wrote on last edited by
                                          #205

                                          @alexsh1 said:

                                          I took their code and stripped a few parts and this is what I am left with:

                                          @alexsh1 the PPDN42 is for 1 micron and 2.5 micron , this one is for 0.5 micron

                                          airbeam has standard code: https://github.com/HabitatMap/AirCastingAndroidClient/blob/master/arduino/aircasting/aircasting_shinyeiPPD42NS.ino

                                          or I've not seen ?

                                          z-wave - Vera -&gt; Domoticz
                                          rfx - Domoticz &lt;- MyDomoAtHome &lt;- Imperihome
                                          mysensors -&gt; mysensors-gw -&gt; Domoticz

                                          alexsh1A 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          26

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular