pms5003 arduino code


#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
const int rs = 13, en = 12, d4 = 8, d5 = 9, d6 = 10, d7 = 11;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define ival   5000  // interval 5 sec
#define ival2 50000  // interval 50 sec

SoftwareSerial pmsSerial(2, 3); // TX, RX

struct pms5003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};

struct pms5003data data;

unsigned long p1,p2,curr; //Refreshes the LCD once every 3000ms (3 seconds) non-blocking, pms5003 gives checksum errors when delayed.

void setup()
{
  Serial.begin(115200);
  pmsSerial.begin(9600);
  lcd.begin(16,2);
  lcd.setCursor(0, 0);
  lcd.print("Warming up");
  delay(4000);
  curr = millis();
  p1 = curr + ival;
  p2 = curr + ival2;
  lcd.clear();
}

void loop()
{
  if (readPMSdata(&pmsSerial)) {
  /* // debug info
    Serial.println();
    Serial.println("---------------------------------------");
    Serial.println("Concentration Units (standard)");
    Serial.print("PM 1.0: "); Serial.print(data.pm10_standard);
    Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_standard);
    Serial.print("\t\tPM 10: "); Serial.println(data.pm100_standard);
    Serial.println("---------------------------------------");
    Serial.println("Concentration Units (environmental)");
    Serial.print("PM 1.0: "); Serial.print(data.pm10_env);
    Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_env);
    Serial.print("\t\tPM 10: "); Serial.println(data.pm100_env);
    Serial.println("---------------------------------------");
    Serial.print("Particles > 0.3um / 0.1L air:"); Serial.println(data.particles_03um);
    Serial.print("Particles > 0.5um / 0.1L air:"); Serial.println(data.particles_05um);
    Serial.print("Particles > 1.0um / 0.1L air:"); Serial.println(data.particles_10um);
    Serial.print("Particles > 2.5um / 0.1L air:"); Serial.println(data.particles_25um);
    Serial.print("Particles > 5.0um / 0.1L air:"); Serial.println(data.particles_50um);
    Serial.print("Particles > 10.0 um / 0.1L air:"); Serial.println(data.particles_100um);
    Serial.println("---------------------------------------");
    */
   }
 //String pm10Std = String(data.pm10_standard);
 // String pm25Std = String(data.pm25_standard);
//  String pm100Std = String(data.pm100_standard);
   String pm10Env = String(data.pm10_env);
  String pm25Env = String(data.pm25_env);
  String pm100Env = String(data.pm100_env);
  String text;

  // Non-blocking code for displaying the sensor readings on the LCD
  curr = millis();

  if (curr > p2) {
    p2 += ival2;
    p1 += ival; // skip this one

      if (data.pm25_env  > 250  )
          text = "Hazardous";
      else if (data.pm25_env  > 150  )
          text = "Very unhealthy";
      else if (data.pm25_env  > 55  )
          text = "Unhealthy";
      else if (data.pm25_env  > 35  )
          text = "Unhealthy FSG";
      else if (data.pm25_env  > 12  )
          text = "Moderate";
      else
          text = "Good";
      lcd.clear();//Clear the screen
      lcd.setCursor(0,0);
      lcd.print(text);

  } else  if (curr > p1) {
      p1 += ival;
      lcd.clear();//Clear the screen
      lcd.setCursor(0,0);
      lcd.print("PM1  PM2.5  PM10");
      lcd.setCursor(0,1);
      lcd.print(pm10Env);
      lcd.setCursor(5,1);
      lcd.print(pm25Env);
      lcd.setCursor(12,1);
      lcd.print(pm100Env);
  }
}

boolean readPMSdata(Stream *s) {
  if (! s->available()) {
    return false;
  }

  // Read a byte at a time until we get to the special '0x42' start-byte
  if (s->peek() != 0x42) {
    s->read();
    return false;
  }

  // Now read all 32 bytes
  if (s->available() < 32) {
    return false;
  }

  uint8_t buffer[32];
  uint16_t sum = 0;
  s->readBytes(buffer, 32);

  // get checksum ready
  for (uint8_t i=0; i<30; i++) {
    sum += buffer[i];
  }

  /* debugging
  for (uint8_t i=2; i<32; i++) {
    Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
  }
  Serial.println();
  */

  // The data comes in endian'd, this solves it so it works on all platforms
  uint16_t buffer_u16[15];
  for (uint8_t i=0; i<15; i++) {
    buffer_u16[i] = buffer[2 + i*2 + 1];
    buffer_u16[i] += (buffer[2 + i*2] << 8);
  }

  // put it into a nice struct :)
  memcpy((void *)&data, (void *)buffer_u16, 30);

  if (sum != data.checksum) {
    // Serial.println("Checksum failure");
    lcd.print("Checksum failure");
    return false;
  }
  // success!
  return true;
}