Use with a Nucleo F401RE and a Sharp Optical Dust Sensor GP2Y1010AU0F to measure dust with a Nokia 5110 display to show result.

Dependencies:   mbed

main.cpp

Committer:
kirchnet
Date:
2014-06-14
Revision:
0:99fdd85b4929

File content as of revision 0:99fdd85b4929:

#include "mbed.h"
#include "NOKIA_5110.h"

/*
Sketch to use with a Nucleo F401RE and a
Sharp Optical Dust Sensor GP2Y1010AU0F to measure dust with a
Nokia 5110 display to show result. Will also show results via USB on PC terminal program

NOTE THAT THIS SENSOR USES 5V AND THE NUCLEO 3.3V. USE AT YOUR OWN RISK.
I SHALL NOT BE HELD RESPONSIBLE FOR ANY DAMAGE TO YOUR HARDWARE.

For non-Nucleo mbed platforms you need to change the pins. 

!!!IMPORTANT!!!
A brief note on the sensor and board voltage   !!!IMPORTANT!!!
STM specify in their datasheet (Feb 2014, DocID025644 Rev 2, page 38) that
pin PA1 is "FT" meaning 5V tolerant. Moreover, I have measured voltages of
no more than 3.71V in my experiments. So you should make your own decision
whether and how you want to connect the sensor. Use at your own risk.
I shall not be liable for any damage. 

This sketch is based on code by the following authors: Cyrille Médard de Chardon (serialC), Christophe Trefois (Trefex)
Their work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter
to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
Changelog:
2014-Jun-08: Adapted to Nucleo
2014-Jun-13: Added Nokia 5110 display

Original documentation
http://arduinodev.woofex.net/2012/12/01/standalone-sharp-dust-sensor/
http://www.howmuchsnow.com/arduino/airquality/

The code for the Nokia 5110 is adapted from work by Chris Yan as Revised: January, 2014

For the scientifically inclined who are pressed for time there is a nice writeup about dust here:
http://www.who.int/occupational_health/publications/en/oehairbornedust3.pdf

Pin connections
Sharp dust sensor GP2Y1010AU0F
Data sheet: https://www.sparkfun.com/datasheets/Sensors/gp2y1010au_e.pdf
App note:   http://sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y1010au_appl_e.pdf
Remember to include the resistor and capacitor (polarity!) as described in the Sharp datasheet
    Pin 1: Resistor - 5V (see datasheet)
    Pin 2: Gnd (capacitor between 1 and 2 - see datasheet)
    Pin 3: Digital D8
    Pin 4: Gnd
    Pin 5: +5V
    Pin 6: Analog A0
    Pins are counted left to right when looking at the connector from the front (i.e. so that you can see the pins)

5110 Display
    myPins.sce  = PB_6;
    myPins.rst  = D2;
    myPins.dc   = D3;
    myPins.mosi = PA_7;//SPI_MOSI;
    myPins.miso = NC;
    myPins.sclk = PA_5;//SPI_SCK;
I am not using the backlight. Feel free use another digital pin to power it
*/

Serial pc(SERIAL_TX, SERIAL_RX); //output for debugging
 
DigitalOut myled(LED1);
DigitalOut ledPower(D8);
AnalogIn analog_value(A0);


int samplingTime = 280;//280 microseconds
int deltaTime = 40;//40 us to give total pulse width of 0.32ms
int sleepTime = 9680;//LED off for 9680 us to take 1 measurement per second

float dustDensityCN = 0,dustDensitySharp = 0, voMeasured=0, voCalc=0;
 
int main() {
  pc.printf("Starting sensor. It can take a few measurements until it becomes stable.\n");
    LcdPins myPins;
    myPins.sce  = PB_6;
    myPins.rst  = D2;
    myPins.dc   = D3;
    myPins.mosi = PA_7;//SPI_MOSI;
    myPins.miso = NC;
    myPins.sclk = PA_5;//SPI_SCK;
    pc.printf("LCD pins set ok\n");
    NokiaLcd myLcd( myPins );
    
    // Start the LCD
    myLcd.InitLcd();
    myLcd.SetXY(char(0),char(0));
    myLcd.DrawString("SHARP DUST SENSOR"); 

    pc.printf("LCD started\n");

  while(1) { 
      myled = !myled;
      ledPower=0; // power on the LED. Pull-down to activate
      wait_us(samplingTime);
      voMeasured = analog_value.read(); // Converts and read the analog input value  
      wait_us(deltaTime);
      ledPower=1; // turn the LED off. Pull up to turn off
      wait_us(sleepTime);

      voCalc = voMeasured*3.3;//Map 0:1 measured range to 0:3.3V
  
  // Original equation taken from Sharp data sheet measured in mg/m3
  // Sharp don't give you a best fit line, so you have to guess
     dustDensitySharp = 0.5/2.8 * (float(voCalc) - 0.7);

  // Eqaution calibrated by Chris Nafis (c) 2012
  // see http://www.howmuchsnow.com/arduino/airquality/
  // measured in parts per 0.01 cf
  // [I did not get meaningful values on my sensor with Chris' formula
  // For me the Sharp graph works just fine. So make your own tests]
     dustDensityCN = (float(voCalc) - 0.0356)*1.2;
  
      pc.printf(" - Measurment value: %1.3f", voMeasured);
      pc.printf(" - Voltage calculated: %1.3f", voCalc);
      pc.printf(" - Sharp's Dust Density [mg/m3]: %f", dustDensitySharp);
      pc.printf(" - C. Nafis' Dust Density [pp.01cf](x10^4): %f\n", dustDensityCN,"\n");
      
        myLcd.SetXY(char(1),char(1));
        myLcd.DrawString("Raw value:"); 
        char measurestring[(((sizeof voMeasured) * 8) + 2)/3 + 2];
        sprintf(measurestring, "%1.2f", voMeasured);
        myLcd.DrawString(measurestring);

        myLcd.SetXY(char(1),char(2));
        myLcd.DrawString("Voltage:  "); 
        char voltagestring[(((sizeof voCalc) * 8) + 2)/3 + 2];
        sprintf(voltagestring, "%1.3f", voCalc);
        myLcd.DrawString(voltagestring);

        myLcd.SetXY(char(1),char(3));
        myLcd.DrawString("Sharp dd: "); //Units: refer to printf above
        char sharpstring[(((sizeof dustDensitySharp) * 8) + 2)/3 + 2];
        sprintf(sharpstring, "%1.2f", dustDensitySharp);
        myLcd.DrawString(sharpstring);

        myLcd.SetXY(char(1),char(4));
        myLcd.DrawString("Nafis dd: "); //Units: refer to printf above
        char nafisstring[(((sizeof dustDensityCN) * 8) + 2)/3 + 2];
        sprintf(nafisstring, "%1.2f", dustDensityCN);
        myLcd.DrawString(nafisstring);
 
  wait(1);
}
}