Is my PMS5003 broken or am i doing something wrong?

I've been trying to follow first how2electronics guide and then this adafruit guide to try and get my PMS5003 sensor working with a Arduino Uno.

I can hear the fan is running if I put my ear to the sensor. I looked at the suggestions in this forum post which seemed to suggest that a resistor is needed, but then seemed to say that it was only needed for pins that aren't used anyway? (my understanding is for just reading the only pins on the sensor i need to connect are VCC, GND and TXD). (Which I have wired to 5V, GND and pin 2 respectively)

I also tried connecting TXD to A0 and updating the adafruit example accordingly, but that didn't help.

If I run the first code provided at the how2electronics guide I get 0's for PM1, PM2.5 and PM10 readings, even if I wait for 60 seconds for it to warm up.

I tried adapting the second code example from that guide (Pasted below as I have a different LCD), but the if (pms.read(data)) on line 23 is never true.

When I try the code provided by adafruit it always shows "Could not read from AQI".

I tried debugging the info coming from the serial with this code, it gives mostly 1's but clear blocks of 0's too. I tried running this both with PIN 2 as suggested in all the guides and also tried connecting to pin A0.

My debug code:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int val = 0;
int cursor = 0;

void setup() {
  if (!i2CAddrTest(0x27)) {
    lcd = LiquidCrystal_I2C(0x3F, 16, 2);
  }
  lcd.init();  // initialize the lcd
  // Turn on backlight
  lcd.backlight();
  lcd.setCursor(0, 0);

  pinMode(2, INPUT);
}

void loop() {
  val = digitalRead(2);

  lcd.print(String(val));

  cursor++;
  if (cursor > 31) {
    lcd.setCursor(0, 0);
    cursor = 0;
  } else if (cursor == 16) lcd.setCursor(0, 1);

  delay(10);
}

bool i2CAddrTest(uint8_t addr) {
  Wire.begin();
  Wire.beginTransmission(addr);
  if (Wire.endTransmission() == 0) {
    return true;
  }
  return false;
}

Here's my modified how2electronics code for my LCD

#include "PMS.h"
#include "SoftwareSerial.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

SoftwareSerial Serial1(2, 3); // RX, TX
 
PMS pms(Serial1);
PMS::DATA data;
 
void setup()
{
  Serial1.begin(9600);
 if (!i2CAddrTest(0x27)) {
    lcd = LiquidCrystal_I2C(0x3F, 16, 2);
  }
  lcd.init(); // initialize the lcd 
  // Turn on backlight 
  lcd.backlight(); 
    lcd.setCursor(0, 0);
  lcd.print("Warming up");
  delay(4000);
  // lcd.clear();
}

void loop()
{
  if (pms.read(data))
  {
    int pm1 = 4;
    int pm25 = 7;
    int pm10 = 2;

    pm1 = data.PM_AE_UG_1_0;
    pm25 = data.PM_AE_UG_2_5;
    pm10 = data.PM_AE_UG_10_0;

    lcd.clear();
    lcd.setCursor(0, 0);
    // lcd.print("PM1.0 :" + Stri0ng(data.PM_AE_UG_1_0) + "(ug/m3)");
    lcd.print("PM1 :" + String(pm1));
    lcd.setCursor(8, 0);
    // lcd.print("PM2.5 :" + String(data.PM_AE_UG_2_5) + "(ug/m3)");
    lcd.print("PM2.5:" + String(pm25));
    lcd.setCursor(0, 1);
    // lcd.print("PM10  :" + String(data.PM_AE_UG_10_0) + "(ug/m3)");
    lcd.print("PM10:" + String(pm10));
    lcd.setCursor(8, 1);
    lcd.print("(ug/m3)");
    
    delay(1000);
  }
}

bool i2CAddrTest(uint8_t addr) {
  Wire.begin(); Wire.beginTransmission(addr);
  if (Wire.endTransmission() == 0) {
     return true;
  }
  return false;
}

And my modified adafruit example.

#include "Adafruit_PM25AQI.h"
#include "SoftwareSerial.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

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

Adafruit_PM25AQI aqi = Adafruit_PM25AQI();

void setup() {
  if (!i2CAddrTest(0x27)) {
    lcd = LiquidCrystal_I2C(0x3F, 16, 2);
  }
  lcd.init();  // initialize the lcd
  // Turn on backlight
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Warming up");

  if (!aqi.begin_UART(&pmSerial)) {  // connect to the sensor over software serial
    Serial.println("Could not find PM 2.5 sensor!");
    while (1) delay(10);
  }
}

void loop() {
  PM25_AQI_Data data;

  if (!aqi.read(&data)) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Could not read from AQI");
    delay(500);  // try again in a bit!
    return;
  }


  int pm1 = 4;
  int pm25 = 7;
  int pm10 = 2;


  pm1 = data.pm10_env;
  pm25 = data.pm25_env;
  pm10 = data.pm100_env;

  lcd.clear();
  lcd.setCursor(0, 0);
  // lcd.print("PM1.0 :" + Stri0ng(data.PM_AE_UG_1_0) + "(ug/m3)");
  lcd.print("PM1 :" + String(pm1));
  lcd.setCursor(8, 0);
  // lcd.print("PM2.5 :" + String(data.PM_AE_UG_2_5) + "(ug/m3)");
  lcd.print("PM2.5:" + String(pm25));
  lcd.setCursor(0, 1);
  // lcd.print("PM10  :" + String(data.PM_AE_UG_10_0) + "(ug/m3)");
  lcd.print("PM10:" + String(pm10));
  lcd.setCursor(8, 1);
  lcd.print("(ug/m3)");

  delay(1000);
}

bool i2CAddrTest(uint8_t addr) {
  Wire.begin();
  Wire.beginTransmission(addr);
  if (Wire.endTransmission() == 0) {
    return true;
  }
  return false;
}

You never initialise your SoftwareSerial instance, like in the original adafruit example, so it's not active.

pmSerial.begin(9600);

You don't initialize Serial, either.

And once again "I'm doing something wrong" wins the day

Thanks for the help.
Once I initialised the serial port on the adafruit code it was displaying values. Still all zero's, but then I but a smoking matchstick nearby and got values. Seems like calibration is a bit off (since I'm sure my house is not a perfect zero on air quality).

As usual. When something doesn't work as expected, I'm also always asking myself: "what am I doing wrong here?"

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.