Dust Sensor Add-On Implementation

355 views
Skip to first unread message

vicatcu

unread,
Dec 2, 2012, 8:19:56 PM12/2/12
to airqua...@googlegroups.com
Gustavo, David H, and others,

You guys have a lot of experience with the Shinyei sensor. I'm writing the software now for the Egg Bus, and I'm following along with Gustavo's nicely documented work here: http://www.howmuchsnow.com/arduino/airquality/grovedust/.

I'm getting a little hung up on the "30 seconds" aspect of the code (i.e. sampletime_ms). Is there any reason to believe a 30-seconds integration period is critical in some way? Do you guys see it as a problem if I just make the period of integration be "the time since last Egg Bus request"?

If I do it that way, I think it would work out most easily to keep two counters: num_samples_low and num_samples_total. They each get reset to zero after servicing an Egg Bus request, num_samples_total gets unconditionally incremented in the main loop, and num_samples_low gets conditionally incremented in the main loop if the sensor output signal is low.

The ratio of num_samples_low to num_samples_total is the "independent variable" in the context of the Egg Bus. The polynomial gets sampled and stored in the ATtiny88 just like other sensor add-ons. Anyone see any problems with this approach before I get too far into writing code?

Cheers,

Vic

Gustavo Olivares

unread,
Dec 2, 2012, 8:44:59 PM12/2/12
to airqua...@googlegroups.com
Hi Vic,

I think you got the names confused. Chris Nafis is who's been working with the Shinyei (and who set the page on "howmuchsnow"), not me :-)

I have a few of those sensors but haven't experimented beyond making sure they work.

Now, about the 30s, I think that it is just an empirical number. The sensor gives a pulse response for the particles that it sees, the width being proportional to the amount of particles in the sensing volume. So, it shouldn't matter if it is 30s or 30hr, you will get 1 value for that "sampling" time. What I think it happens is that in their tests, they found that a 30s sampling time is an acceptable compromise between accuracy (the longer the sampling time, the more accurate the "ratio" is), sensitivity (the longer the sampling time, the lower the minimum concentration measured) and response time (the ideal sensor has an immediate response time but too short a sampling time and you may not have a single particle passing through).

Is it possible to have a dual condition on the sampling?
Something like the integration period is
MAX (30s, time_since_last_Egg_Bus_request)

With those 30s programmable as one could think of using it in a very dirty area (think carpark for instance) and having enough particles that the sensor does respond reliably on 1s sampling times.

What I could do though is test some of the Shinyei specific code for you. I have a few arduinos laying around and as I said I have a couple of dust sensors (and some more Sharp dust sensors as well) to knock something up pretty quickly.

/El Gus

Victor Aprea

unread,
Dec 2, 2012, 10:31:30 PM12/2/12
to airqua...@googlegroups.com
Gustavo, Chris, 

Yes you're right, so sorry, my mistake on confusing names! 

It would be possible to implement a "dual condition" using the egg bus. It would work by the interface module presenting to the system as two (or more) sensors, even though there is only one physical sensor. The "virtual" sensors would  have names like "dust_30s" (based on occupancy during the last 30 seconds) and "dust_60s" (based on occupancy during the last 60 seconds).

What I need to figure out is how to do this processing in a useful way so that the independent variables (i.e. occupancy ratios) are available or computable on demand, and do that in a way that can fit in the memory constraints of the ATtiny88. I think that's going to take a bit of thought an creativity. 

Thanks for helping to catch me up on prior work!

Regards,

Vic


--





--
Victor Aprea // Wicked Device

Michael Heimbinder

unread,
Dec 3, 2012, 9:32:09 AM12/3/12
to airqua...@googlegroups.com
The Shinyei can output data as frequently as once a second. I've posted the code we're using to drive the Shinyei below. To change the averaging time simply change the value for "unsigned long sampletime_ms =". We've been playing around with these units, most recently in San Francisco, and getting some interesting results. For more info see, http://www.takingspace.org/aircasting-goes-west-coast-for-urban-prototyping/

#include <SoftwareSerial.h>
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 3000;
unsigned long lowpulseoccupancy = 0;
double ratio = 0;
double concentration = 0;

SoftwareSerial mySerial(2, 3);

void setup() {
Serial.begin(9600);
mySerial.begin(115200);
pinMode(8,INPUT);
starttime = millis();
}

void loop() {
duration = pulseIn(8, LOW);
lowpulseoccupancy = lowpulseoccupancy+duration;
//Serial.print(starttime);
//Serial.print(" ");
//Serial.println(duration);
if ((millis()-starttime) > sampletime_ms)
{
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(lowpulseoccupancy);
Serial.print(",");
Serial.print(ratio);
Serial.print(",");
Serial.println(concentration);
mySerial.print(concentration);
mySerial.print(";InsertSensorPackageName;PPD42NS;Particulate Matter;PM;hundred particles > 1 um per cubic foot;HPPCF;0;1000;2000;3000;4000");
mySerial.print("\n");
lowpulseoccupancy = 0;
starttime = millis();
}
}

vicatcu

unread,
Dec 3, 2012, 11:14:40 AM12/3/12
to airqua...@googlegroups.com
Michael,

Thanks, this code is very similar to the code on Chris Nafis' website. The firmware is decidedly in control of its own fate. It *pushes* code to the host system over Serial at regular / prescribed intervals. The Egg Bus inverts this paradigm so that the sensor module must report a value when requested by the host.

I could try and emulate the behavior of the existing firmware, but for the sake of the I2C bus having priority, I have to do something more "interrupt friendly" than these implementations - everytime you call millis() in Arduino code, because interrupts get disabled briefly.

I am thinking what I'll do is use Timer0 overflow interrupt to mark the passage of time (i.e. 30 second periods), and use Timer1 to measure low pulse widths using the Input Capture interrupt...

Gustavo Olivares

unread,
Dec 11, 2012, 5:29:40 AM12/11/12
to airqua...@googlegroups.com
Hi Vic,

I just had a little time to play with the Shinyei sensor and I tested the code below.
The connection is a bit odd as the signal from the dust sensor is connected to pins 2 AND 3 (the 2 external interrupts on my etherten)

I tested it with delays as short as 100ms ... and it seems to respond OK up to 500ms ... less than that and "there be dragons"

Now for the "on demand" paradigm. What about a buffered measurement? Keep the Shinyei working as it wants to work, with a pre-defined "integrating time" (30s, 1min, whatever ... even for scientific applications 30s sampling for dust is great, 1s is perfect) and then the response is not "go and get a measurement" but "give me the last update of your measurement".

In the PACMAN I had a similar issue with the Sharp dust sensor and in the end I married the Sharp sensor with an ATtiny85 that gave me an analogue response corresponding to the average of the last 50 measurements (each measurement took ~10ms).

I hope that helps.

/El Gus
---------SHINYEI_TESTS-------------------
// Shinyei Dust Sensor tests
volatile unsigned long Tstart,Tend,t_1,t_2,Tlow,Ttot,t_0;
float ratio,conc;
//Interrupt functions
void T_falling(){
t_1=millis();
}
void T_rising(){
t_2=millis()-t_1;
Tlow=Tlow+t_2;
}
//SETUP
void setup(){
Serial.begin(9600);
Serial.println("Time\tConc\tRatio%");
Tlow=0;
t_0=millis();
attachInterrupt(0,T_falling,FALLING);
attachInterrupt(1,T_rising,RISING);
}
//MAIN LOOP
void loop(){
delay(5000);
Ttot=millis()-t_0;
ratio=100*Tlow/Ttot;
conc=1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
conc=conc/283.0;
Serial.print(t_0);
Serial.print("\t");
Serial.print(conc);
Serial.print("\t");
Serial.println(ratio);
Tlow=0;
t_0=millis();
}
-----------------------------------------

Nafis

unread,
Jan 30, 2013, 4:33:57 PM1/30/13
to airqua...@googlegroups.com

Looks like my code from http://www.howmuchsnow.com/arduino/airquality/grovedust/ minus any reference to my work :-(

CMA Gran

unread,
Jan 13, 2014, 9:56:29 PM1/13/14
to airqua...@googlegroups.com
Hi Mr. Nafis - not specifically on this topic, sorry but I couldn't find your contact info so I am posting here.

I am a student working on a science fair project to test the effectiveness of different ways to mitigate radon and would love to set up something like you have on your website. I have figured out how to post data to Xively from an Arduino, but I am struggling with the Radon monitor. Is it possible for you to post your actual code for reading and the radon values? I have tried the sample code but the readings fluctuate and I don't know why.

My project is about the mitigation of radon, not monitoring it, but it would certainly help improve the quality of my data versus taking readings once per day, for example. I do not need to control the fan or other devices.

Your help would be very much appreciated!

Reply all
Reply to author
Forward
0 new messages