Project - Cerberus Dust Sensor

Cerberus Dust Sensor

Using a Grove - Dust Sensor in a Gadgeteer project. The code includes 2 methods, one of which is commented out as I prefer interrupts for stuff like this. I wasn’t too happy with my results as I got a lot of zero reading and while I know the air is clean in where I live, I wouldn’t have guessed that clean. Improvements, suggestions, etc welcomed.

1 Like


Where can I find the Grove driver for NETMF 4.2?


I wrote/borrowed it and I’ll look tomorrow if I have source/etc I can upload for you as the computer I wrote it on is in the shop, but I might have the code sitting somewhere else as well.

Thank you Duke.

I should mention that I sent Tzu Hsuan a driver install as I wanted to upload it here, but all you can upload are images. The driver for Grove module is the same as the eBlock Extension module from GHI and the source code is available at codeplex in case anyone else needs this.

Dear Duke:

I connect the Dust sensor to Grove J4 and to FEZ Cerbuino Bee Socket 3.
But seems not work.
I always get the concentration =0.62, seems the Interrupt event not fired.

Below is my code


public partial class Program
        // This method is run when the mainboard is powered up or reset.  

        private GT.Timer _sensorTimer;
        private GT.Interfaces.InterruptInput _dustSensor;
        private bool _pulseLow = false;
        public const Int64 ticks_per_millisecond = System.TimeSpan.TicksPerMillisecond;
        private Int64 _startTime = 0;
        private Int64 _lowTime = 0;

        void ProgramStarted()
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            //method 1
            _dustSensor = eBlockExpansion.SetupInterruptInput(GT.Socket.Pin.Three, GT.Interfaces.GlitchFilterMode.Off, GT.Interfaces.ResistorMode.Disabled, GT.Interfaces.InterruptMode.RisingAndFallingEdge);
            _dustSensor.Interrupt += new InterruptInput.InterruptEventHandler(_dustSensor_Interrupt);

            _sensorTimer = new GT.Timer(60000);
            _sensorTimer.Tick += new GT.Timer.TickEventHandler(_sensorTimer_Tick);
        void _dustSensor_Interrupt(InterruptInput sender, bool value)
            Debug.Print("pulse detected");
            if (value)
                _lowTime = _lowTime + (GetCurrentTimeInTicks() - _startTime);
                _pulseLow = false;
                _startTime = GetCurrentTimeInTicks();
                _pulseLow = true;

        public static long GetCurrentTimeInTicks()
            return Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;

        void _sensorTimer_Tick(GT.Timer timer)

            //in case we are in the middle of a LOW
            if (_pulseLow)
                Int64 now = GetCurrentTimeInTicks();
                _lowTime = _lowTime + (now - _startTime);
                _startTime = now;

            double ratio = (_lowTime / (double)ticks_per_millisecond) / 600.0;

            _lowTime = 0;

            double concentration = CalculateConcentration(ratio);

           // StoreResult(concentration);

        private static double CalculateConcentration(double ratio)
            double concentration = 1.1 * (ratio * ratio * ratio) - 3.8 * (ratio * ratio) + 520.0 * ratio + 0.62;
            return concentration;

Which socket are you plugged into on the board?