Sharp Dust Sensor with Arduino – Getting the timing right.

There are various articles and posts about using the Sharp Gp2Y1010AU0F sensor for air quality monitoring. The original seems to be Chris Nafis in 2012 http://www.howmuchsnow.com/arduino/airquality/, but there are several other posts covering this interesting and cheap device.

The Sharp data sheet for the sensor explains how it works and has diagrams showing the required driving circuit, details of the timing required and a graph of the typical output.

https://www.sparkfun.com/datasheets/Sensors/gp2y1010au_e.pdf

There’s also a slightly more informative application note available from Sharp.

http://www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y1010au_appl_e.pdf

Both of these show the timing required for the sensor LED as a 10mS pulse cycle time with a .32mS pulse width. They also state that the output voltage should be measured .28mS after the start of the LED pulse.

The original code, on which all the other versions I’ve seen are based, used the analogRead() function to measure the output voltage from the sensor using the Arduino’s analouge to digital converter (ADC). In outline the sampling loop of the code goes like this…

  • Turn LED ON
  • Wait 280uS
  • Sample sensor output voltage
  • Wait 40uS
  • Turn LED OFF
  • Wait 9680uS
  • Repeat

At first glance this would seem to meet the timings specified by Sharp. However, analogRead() takes 13 clock cycles to complete an ADC conversion and these are ADC clock cycles which are prescaled from the 16MHz system clock by a factor of 128. This means that analogRead() takes at least 104uS to return a value, so the pulse width ends up being far in excess of the 320uS required. The following screen shot from an oscilloscope shows this.

dustsensor1

The yellow trace shows the LED pulse (0v=LED On, +5v =LED Off), and the  cyan trace the output from the sensor.

Having the longer pulse does seem to distort the output, though starting analogRead() at 280uS would still be measuring the maximum value so perhaps it doesn’t change the result. To check if this is the case, I used a signal generator to get the exact timing specified for the LED which, as can be seen below, makes the peak value a little higher.

dustsensorint1

So, having established that the timing does have an impact on the sensor output values I looked at what could be done to get the timing right. The ADC prescaling factor defaults to 128 but this can be reduced. This makes the conversion faster but at the expense of accuracy. When used with a prescaling factor of 64 analogRead() takes around 52uS, so starting the conversion at 280uS would allow the LED to be turned off at about 350uS. Although the main problem is the time that analogRead() takes, all the  other instructions in the code take time too. Fiddling around with the settings and checking the effect on the ‘scope about the closest to the 280/320 ‘ideal’ settings are acheived with a delay of 250uS between turning the LED on and the analogRead(), then turning the LED off as soon as it returns(i.e. post read delay of zero).

Although you can’t get the timing right using the analogRead() function, it can be done with a 16MHz Arduino and using the default ADC prescaling of 128 for full accuracy. The solution is to attach an interrupt service routine to the ADC completed interrupt to read the value. This means that control returns while the ADC conversion is in progress so the LED can be turned off at the right time. The conversion can be started at the right time, but the ADC has to be controlled directly rather than by calling analogRead(). Arduino code showing how to do this will be in my next post.

 

 

8 thoughts on “Sharp Dust Sensor with Arduino – Getting the timing right.”

  1. Hi Andy,

    thank you very much for sharing your the measurements, very nice, just what I am looking for.

    Could you elaborate a bit on your conclusion that the peak is a little higher with the shorter LED-On time.
    I cannot understand how this is possible. When the cyan curve peaks the LED is still on. There is no way the measurement at this point in time can be dependent on how long the LED will remain on. We cannot foresee the future, right?

    How sure are you that the difference of the peak values is not simply caused by accuracy of the measurements.

    Could it be an effect of a variation in the 10mS pulse cycle time? When LED-On time is longer then the over all pulse cycle time is also longer? If you compensate for this, then the idle time is shorter.

    The datasheet states “Time required for the device to be ready to detect dust from when the system is turned on is less than 1 sec.” Did you give the sensor enough time to settle before taking the measurements?

    Sorry for asking so many questions, I am actually curious.

    Thanks,
    Sebastian

    1. Hi Sebastian,

      Thanks for your interest and taking the time to comment.

      I can see what you mean when you say that the LED off time shouldn’t have any effect on the reading as it’s always after the reading. I’m not sure why it happens, but the scope traces are consistently higher with the shorter 320uS pulse width. The only thing I could think of is that it has something to do with the capacitor in the driving circuit. I think this acts sort of like the capacitor in a flash gun, so having a longer pulse would shift the charge/discharge curve slightly from what the sensor is calibrated for.

      It could just be inaccuracy of the measurements, but you can switch back and forth and see the traces change.

      The specification for the pulse cycle is 10ms +/- 1ms, so the extra 104uS means it’s still in spec as long as you don’t add a lot of slow code to the polling loop. The specification for the pulse width is +/- 0.02mS so that would seem to be more critical.

      When I was looking at this I basically had it running continuously and just altered the pulse width on the signal generator. The 1 second warm up / settle time maybe supports the idea that it’s something to do with the capacitor.

      It’s been a while since I looked at the dust sensor, but maybe I’ll dig it out and try a few more things. I’ll see if I can get a trace of the voltage across the capacitor and see if that changes with the pulse width.

      Regards,

      Andy.

      1. Hi again…
        So, I dug out the dust sensor and set it up as before. As a sanity check I started with a 320uS pulse width which I then extended to about 500us and then contracted back to 320. As before the output varied with the pulse width, as the original traces showed.

        I then moved the scope probe from the sensor output to the v-LED line. Changing the pulse width does indeed alter the voltage across the capacitor as I suspected and I think this is the reason for the variation in sensor output.

        The most convincing way to see this is to watch the traces change as you change the pulse width. I’ll try and video it so you can see what I mean.

        Regards,
        Andy

        1. Hi Andy.

          Thanks a lot for the fast (and enlightening) reply.

          What you wrote makes perfekt sense. It is not the width of the ongoing LED-on pulse that changes the output, but the pulses of previous cycles.

          For me, the lesson learned is that the sensor cannot be measured after a “one-shot” LED pulse. It is crucial to continuously provide LED on-off cycles and let the sensor settle first before valid measurements can take place.

          You don’t need to go through the hassle of making a video, at least not for me (feel free do do it anyway, though). I am already quite happy with the information you just shared with me.

          Thanks again,
          Sebastian

          1. Hi Sebastian,

            Yes, that’s how it seems to me too. One of the Sharp data sheets says the sensors are calibrated in the factory but for this to be correct you need to make sure that..
            1 – the timing pulses are correct,
            2 – use a 5v supply not 3.3v,
            3 – the values of the resistor and capacitor are as specified
            4 – don’t do other stuff in the polling loop, like writing to a serial port,
            5 – let the sensor settle after you start the pulses before you get a useable reading.

            Not wanting to be critical of other people’s work but a lot of the code and articles you see published for this sensor break all those rules. My ISR code will get the timing correct, but doesn’t obey rule 5 as I only realised the settle time was important when looking into the reply to your questions. Maybe I should update that code and get around to adding the temperature correction too. Ultimately although it is quite sensitive to changes in dust in the air, I doubt if the sensor is all that accurate. So all it can really tell you is how the dust level varies over time, rather than the ppm.

            Regards,

            Andy.

  2. Hi Andy,

    thank you very much for sharing your the measurements, very nice, just what I am looking for.

    Could you elaborate a bit on your conclusion that the peak is a little higher with the shorter LED-On time.
    I cannot understand how this is possible. When the cyan curve peaks the LED is still on. There is no way the measurement at this point in time can be dependent on how long the LED will remain on. We cannot foresee the future, right?

    How sure are you that the difference of the peak values is not simply caused by accuracy of the measurements.

    Could it be an effect of a variation in the 10mS pulse cycle time? When LED-On time is longer then the over all pulse cycle time is also longer? If you compensate for this, then the idle time is shorter.

    The datasheet states “Time required for the device to be ready to detect dust from when the system is turned on is less than 1 sec.” Did you give the sensor enough time to settle before taking the measurements?

    Sorry for asking so many questions, I am actually curious.

    Thanks,
    Sebastian

      1. Hi Andy,

        yeah, the system did not present me my comment after I submitted, so I thought something went wrong. Sorry for submitting twice.

        Regards, Sebastian.

Leave a Reply to Andy MCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.