PM2.5 Sensor & Display—Sketch Not Running

I'm trying to make a PM2.5 sensor which displays the PM2.5 concentration and corresponding EPA recommendation onto an e-paper display.

When I try to upload my sketch, the IDE warns me:

Sketch uses 21154 bytes (65%) of program storage space. Maximum is 32256 bytes.

Global variables use 1779 bytes (86%) of dynamic memory, leaving 269 bytes for local variables. Maximum is 2048 bytes.

Low memory available, stability problems may occur.

I have several debugging Serial.println() statements throughout the code, but the serial monitor never shows a single output, and the TX and RX pins never light either. The display doesn't even so much as flash. As far as I can tell, once I upload the sketch absolutely nothing happens.

When I comment out the sensor part of the sketch and pass the display functions dummy values, everything works fine. When I comment out the display part of the sketch and just print PM2.5 concentrations to serial, everything works fine. It's only when I try putting them both together that I run into this issue.

I'm using an Arduino Uno, Nova PM sds011, and Waveshare 1.54-inch v2 e-Paper display. I've wired everything to a breadboard and powered it with an old Sony phone charger, rated for 5V 0.5mA, which should be more than enough current for my project. I've got a 1mF aluminum electrolytic capacitor set across the positive and negative rails of my breadboard to control ripple voltage from my source. I've attached my sketch to this post.

I'm still learning Arduino and still getting familiar with these forums. Please let me know if there's somewhere else I should post this, or whether there's more information I should include. Any help is much appreciated!

Edit: my apologies, the original sketch I'd attached was an outdated version with unused code commented out. I've reattached a more complete version. Here's the newer version in code tags:

/*
   PM2.5 Smoke Concentration Sensor and Display
   Based off of the examples GXEPD2_minimumExample
   from the GXEPD2 library (https://github.com/ZinggJM/GxEPD2) and
   queryReportingMode from the Nova Fitness SDS dust sensors library
   (https://github.com/lewapek/sds-dust-sensors-arduino-library)
   Uses Waveshare 1.54inch E-Paper display, Arduino Uno, and Nova PM SDS011 Air Quality Sensor.
   Last updated 4/9/21
*/

//#define ENABLE_GxEPD2_GFX 0
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#define MAX_DISPLAY_BUFFER_SIZE 800
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_154_D67, MAX_HEIGHT(GxEPD2_154_D67)> display(GxEPD2_154_D67(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // GDEH0154D67

#include "SdsDustSensor.h"
SdsDustSensor sds(3, 5);  //rx pin, tx pin



void setup() {

  Serial.begin(9600);
  Serial.println("setting up...");
  delay(1000);

  sds.begin();


  display.init();
  display.fillScreen(GxEPD_WHITE);
  display.fillScreen(GxEPD_BLACK);
  display.fillScreen(GxEPD_WHITE);
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);

}

void loop() {

  Serial.println("Waking up sensor");
  sds.wakeup();
  Serial.println("Waiting...");
  delay(30000);
  Serial.println("Getting PM values");
  checkSensor();
  Serial.println("Sensor going back to sleep\n");
  sds.sleep();
  
  delay(60000);

}

void checkSensor() {

  PmResult pm = sds.queryPm();
  
  display.firstPage();
  do
  {
    
    Serial.println("PM2.5 = ");
    Serial.print(pm.pm25);
    
    display.fillScreen(GxEPD_WHITE);
    
    display.setCursor((display.width() - 200) / 2, display.height() / 8);
    display.println("PM2.5 Conc.[µg/m^3]: ");
    display.println(pm.pm25);
  
    display.setCursor(0, display.height() * 1 / 2);
    display.println("Caution:  100% of \nthose who breathe O2 die.\n");
    //^^ this is stand-in:  later I want custom messages for different PM2.5 concentrations
  }
  while (display.nextPage());
  
}

sensor_test_v8.ino (2.15 KB)

Code in code tags

/*
   PM2.5 Smoke Concentration Sensor and Display
   Based off of the examples GXEPD2_minimumExample
   from the GXEPD2 library (https://github.com/ZinggJM/GxEPD2) and
   queryReportingMode from the Nova Fitness SDS dust sensors library
   (https://github.com/lewapek/sds-dust-sensors-arduino-library)
   Uses Waveshare 1.54inch E-Paper display, Arduino Uno, and Nova PM SDS011 Air Quality Sensor.
   Last updated 4/9/21
*/

//#define ENABLE_GxEPD2_GFX 0
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#define MAX_DISPLAY_BUFFER_SIZE 800
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_154_D67, MAX_HEIGHT(GxEPD2_154_D67)> display(GxEPD2_154_D67(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // GDEH0154D67

#include "SdsDustSensor.h"
//int rxPin = 3;
//int txPin = 5;
//SdsDustSensor sds(rxPin, txPin);
SdsDustSensor sds(3, 5);  //I'd hoped this would save some memory, but proably not



void setup() {

  Serial.begin(9600);
  Serial.println("setting up...");
  delay(1000);

  sds.begin();


  display.init();
  display.fillScreen(GxEPD_WHITE);
  display.fillScreen(GxEPD_BLACK);
  display.fillScreen(GxEPD_WHITE);
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);

}

void loop() {

  /*
  sds.wakeup();
  checkSensor();
  sds.sleep();
  delay(60000);
  */

  Serial.println("Waking up sensor");
  sds.wakeup();
  Serial.println("Waiting...");
  delay(30000);
  Serial.println("Getting PM values");
  checkSensor();
  Serial.println("Sensor going back to sleep\n");
  sds.sleep();
  
  delay(60000);

}

void checkSensor() {
  
  /*
  PmResult pm = sds.queryPm();
  Serial.println("PM2.5 = ");
  Serial.print(String(pm.pm25)+"\n");
  */

  PmResult pm = sds.queryPm();
  
  display.firstPage();
  do
  {
    
    Serial.println("PM2.5 = ");
    Serial.print(pm.pm25);
    
    display.fillScreen(GxEPD_WHITE);
    
    display.setCursor((display.width() - 200) / 2, display.height() / 8);
    display.println("PM2.5 Conc.[µg/m^3]: ");
    display.println(pm.pm25);
  
    display.setCursor(0, display.height() * 1 / 2);
    display.println("Caution:  100% of \nthose who breathe O2 die.\n");
    //^^ this is stand-in:  later I want custom messages for different PM2.5 concentrations
  }
  while (display.nextPage());
  
}

My experience with the e-paper displays is that they are ram hogs.

Please use code tags, for posting code, by clicking on the upper leftmost symbol in this window. Then more helpers are able to read it.

Downloading code looks like working. The Serial.print telling "setting up..." ought to appear.

Can it be a powering problem? Please post a wiring diagram, not a Fritzing.

What MCU are you using? You may have to setup serial software or initialize a serial hardware port, something your posted code does not do.

You may find a 2nd look at the link Nova Fitness SDS dust sensors Arduino library could be a good diea.

Railroader:
...Can it be a powering problem? Please post a wiring diagram, not a Fritzing.

Here's an Imgur link. I tried adding the image directly but it didn't seem to work.
I spent a few hours trying to get EAGLE to work, but couldn't get the proper modules and didn't know what I should do as substitute, so I went with a hand-drawn diagram. Please let me know if there is anything I can do to make it clearer—I don't have much experience with drawing diagrams.

Idahowalker:
What MCU are you using? You may have to setup serial software or initialize a serial hardware port, something your posted code does not do.

You may find a 2nd look at the link Nova Fitness SDS dust sensors Arduino library could be a good diea.

What I understand to be my MCU has ATMEGA328P-PU printed on it. Nothing jumped out at me on rereading the Nova Fitness library. Is there something in particular you think I should focus on?

An Uno will need software serial setup, a Mega, Due, STM32 BluePill, and a ESP32 does not.

Sorry but I pass on the Imgur link as I don't want to be coockied or spammed by them.

Railroader:
Sorry but I pass on the Imgur link as I don't want to be coockied or spammed by them.

Is there a preferable image hosting service over imgur? Is there some maximum file size that I can attach to a single post?

Idahowalker:
An Uno will need software serial setup, a Mega, Due, STM32 BluePill, and a ESP32 does not.

Would you mind explaining why the serial setup isn't necessary when the sensor code runs on its own but is necessary when both parts of the code run at the same time?

kronimiciad:
Is there a preferable image hosting service over imgur?

Yes. Look for informative topics here. One last alternative is to attach the file.

I've attached my schematic to this post As I noted earlier, please let me know if there's anything I should do to make it clearer.

Edit: attempting to attach the file keeps throwing errors. Attempting to resolve.

Edit2: ah, that seems to have worked. From my end, at least. I think my problem was that the original image's resolution was too high.

Sorry but I don't find it.

Railroader:
Sorry but I don't find it.

I beg your pardon, but I don't know what you mean. Do you mean that you cannot see the image in my post? Cannot see the attachment? Both?
I'm not certain where you meant to look for better image hosting services. If it seems that the forums won't let me upload an image here, could you direct me to a resource where I could find a better image host?

Now it popped up on my screen.

kronimiciad:
Edit2: ah, that seems to have worked. From my end, at least. I think my problem was that the original image's resolution was too high.

You need to keep the file size below 2M, I make sure my images are no bigger than 1100 pixels on its greatest dimension.
Tom... :slight_smile:

Hi,
Did you write your code in stages?
Write code JUST to get the PM sensor input working in serial monitor, NO E-Paper code at all.

If not then write one to prove you have reliable communication with the sensor first.

Thanks.. Tom.. :slight_smile:

Railroader:
Now it popped up on my screen.

Is there anything in the diagram that indicates a possible error, or inappropriate part?

TomGeorge:
You need to keep the file size below 2M, I make sure my images are no bigger than 1100 pixels on its greatest dimension.
Tom... :slight_smile:

Thank you for the note! I'll keep that in mind for next time :slight_smile:

TomGeorge:
... Did you write your code in stages?

I did, yes. I wrote one sketch to communicate with the sensor, and it worked, one sketch to print dummy values to my display, and it worked, and when I tried combining them together into a single sketch absolutely nothing happened. No display activity, no serial printing. I can also comment out one half and the other half and get working results. The below code comments out all of my display code, and it prints to serial monitor PM concentration values just fine:

/*
//#define ENABLE_GxEPD2_GFX 0
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#define MAX_DISPLAY_BUFFER_SIZE 800
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_154_D67, MAX_HEIGHT(GxEPD2_154_D67)> display(GxEPD2_154_D67( SS,  8,  9,  7)); // GDEH0154D67
*/

#include "SdsDustSensor.h"
SdsDustSensor sds(3, 5);  //rx pin, tx pin


void setup() {

  Serial.begin(9600);
  Serial.println("setting up...");
  delay(1000);

  sds.begin();

  /*
  display.init();
  display.fillScreen(GxEPD_WHITE);
  display.fillScreen(GxEPD_BLACK);
  display.fillScreen(GxEPD_WHITE);
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  */
}



void loop() {

  Serial.println("Waking up sensor");
  sds.wakeup();
  Serial.println("Waiting...");
  delay(30000);
  Serial.println("Getting PM values");
  checkSensor();
  Serial.println("Sensor going back to sleep\n");
  sds.sleep();
  
  delay(60000);

}



void checkSensor() {

  PmResult pm = sds.queryPm();
  Serial.println("PM2.5 = ");
  Serial.println(String(pm.pm25)+"\n");

  /*
  display.firstPage();
  do
  {
    
    Serial.println("PM2.5 = ");
    Serial.print(pm.pm25);
    
    display.fillScreen(GxEPD_WHITE);
    
    display.setCursor((display.width() - 200) / 2, display.height() / 8);
    display.println("PM2.5 Conc.[µg/m^3]: ");
    display.println(pm.pm25);
  
    display.setCursor(0, display.height() * 1 / 2);
    display.println("Caution:  100% of \nthose who breathe O2 die.\n");
    //^^ this is stand-in:  later I want custom messages for different PM2.5 concentrations
  }
  while (display.nextPage());
  */
  
}

This comments out all of my sensor code, and it prints dummy values to my display just fine:

//#define ENABLE_GxEPD2_GFX 0
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#define MAX_DISPLAY_BUFFER_SIZE 800
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
GxEPD2_BW<GxEPD2_154_D67, MAX_HEIGHT(GxEPD2_154_D67)> display(GxEPD2_154_D67(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // GDEH0154D67

/*
#include "SdsDustSensor.h"
SdsDustSensor sds(3, 5);  //rx pin, tx pin
*/



void setup() {

  Serial.begin(9600);
  Serial.println("setting up...");
  delay(1000);

  //sds.begin();


  display.init();
  display.fillScreen(GxEPD_WHITE);
  display.fillScreen(GxEPD_BLACK);
  display.fillScreen(GxEPD_WHITE);
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);

}

void loop() {

  /*
  Serial.println("Waking up sensor");
  sds.wakeup();
  Serial.println("Waiting...");
  delay(30000);
  Serial.println("Getting PM values");
  checkSensor();
  Serial.println("Sensor going back to sleep\n");
  sds.sleep();
  */
  checkSensor();
  
  //delay(60000);
  delay(1000);

}

void checkSensor() {

  //PmResult pm = sds.queryPm();
  
  display.firstPage();
  do
  {
    
    Serial.println("PM2.5 = ");
    //Serial.print(pm.pm25);
    
    display.fillScreen(GxEPD_WHITE);
    
    display.setCursor((display.width() - 200) / 2, display.height() / 8);
    display.println("PM2.5 Conc.[µg/m^3]: ");
    //display.println(pm.pm25);
  
    display.setCursor(0, display.height() * 1 / 2);
    display.println("Caution:  100% of \nthose who breathe O2 die.\n");
    //^^ this is stand-in:  later I want custom messages for different PM2.5 concentrations
  }
  while (display.nextPage());
  
}

Hi,
Good it helps if you have two bits of working code to start with. :slight_smile:

It could be that both libraries might be using the same timer or resource, this happens at times as most libraries are open source developed.
I am not a library expert, possibly someone else may have a solution.

If you go and edit your Subject and add Possible Library Clash?

It may attract some other more knowledgeable members.

Tom... :, iy

kronimiciad:
when I tried combining them together into a single sketch absolutely nothing happened. No display activity, no serial printing.

You mean even "setting up..." line that's printed at the start of setup() does not appear?

If that's the case I'd guess there's a clash within the libraries, causing one of them (the second you call the constructor of) to hang for some reason.

Otherwise, place more Serial.print() lines to narrow down how far in thr code you get. I've at times gone as far as adding one between every single line of loop(), printing digits 1, 2, 3, 4, etc, just to see at which point it hangs... and then dive into the offending function.

Thank you for the suggestion, Tom, I appreciate it :grinning:
Alas, for the moment, though I can edit my posts on other threads, I don't have the ability to edit any of my posts on this one, let alone the thread subject line. We'll see if that changes :man_shrugging:

This is the case. Not even the "setting up" is printed. As I mentioned earlier, at no point do the RX or TX LEDs light up.

Edit: for whatever it's worth, I can edit this post, but not the ones from before the forum update.

In lieu of editing the subject line, should I post a new thread that notes the troubleshooting you folks helped me through?